diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..fb51c68824e --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,61 @@ +version: 2 +jobs: + build: + working_directory: ~/project + docker: + - image: starefossen/ruby-node:2-8 + auth: + username: intelexdocker + password: $DOCKERHUB_PASSWORD + steps: + - checkout + - run: + name: Install and configure dependencies + command: | + gem install bundler -v 2.3.26 + bundle install --jobs 4 --retry 3 + - run: + name: Build static html + command: bundle exec middleman build --clean + - persist_to_workspace: + root: /root/project + paths: + - build + deploy: + working_directory: ~/project + docker: + - image: starefossen/ruby-node:2-8 + auth: + username: intelexdocker + password: $DOCKERHUB_PASSWORD + steps: + - checkout + - add_ssh_keys: + fingerprints: + - "72:81:e7:4d:d2:d4:0d:7f:59:6b:e1:74:57:3d:36:12" + - attach_workspace: + at: /root/project + - run: + name: Install and configure dependencies + command: | + npm install -g --silent gh-pages@2.0.1 + git config user.email "ci-build@klukas.net" + git config user.name "ci-build" + - run: + name: Deploy docs to gh-pages branch + command: gh-pages --dotfiles --message "[skip ci] Updates" --dist build +workflows: + version: 2 + build-and-deploy: + jobs: + - build: + context: + - docker-hub + - deploy: + context: + - docker-hub + filters: + branches: + only: master + requires: + - build diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..88c77a9b01c --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,9 @@ +If this is a question or feature request, make sure to: + +- [ ] The title starts with `Question:` or `Feature:`. + +If this is an bug report, not a question, make sure to: + +- [ ] I'm not running Windows (which is unsupported), or if I am, I can confirm this issue appears on another platform, or Vagrant. +- [ ] This issue appears in the latest `dev` branch. +- [ ] I've included my browser and Ruby version in this issue. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000000..a4569f24145 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,5 @@ +!!!!! STOP AND READ !!!!! + +If the dropdown above says "base fork: lord/master", you are submitting your change to ALL USERS OF SLATE, not just your company. This is probably not what you want. Click "base fork" to change it to the right place. + +If you're actually trying to submit a change to upstream Slate, please submit to our dev branch, PRs sent to the master branch are generally rejected. diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml new file mode 100644 index 00000000000..4594c82b489 --- /dev/null +++ b/.github/workflows/ruby.yml @@ -0,0 +1,24 @@ +name: Ruby + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Ruby 2.6 + uses: actions/setup-ruby@v1 + with: + ruby-version: 2.6.x + - name: Build and test with Rake + run: | + gem install bundler + bundle install --jobs 4 --retry 3 + bundle exec middleman build --clean + - name: GitHub Pages Deploy + uses: JamesIves/github-pages-deploy-action@master + env: + BRANCH: "gh-pages" + FOLDER: "build" + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} diff --git a/.gitignore b/.gitignore index f6fc8c00b25..10501583560 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,11 @@ tmp *.DS_STORE build/ .cache +.vagrant +.sass-cache # YARD artifacts .yardoc _yardoc doc/ -.idea/ \ No newline at end of file +.idea/ diff --git a/.travis.yml b/.travis.yml index 3280d947c9a..542116929e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ sudo: false language: ruby rvm: - - 1.9.3 - - 2.0.0 + - 2.2.5 + - 2.3.3 + - 2.4.0 cache: bundler +script: bundle exec middleman build diff --git a/CHANGELOG.md b/CHANGELOG.md index 59ee6a441e5..be29842dc46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,56 @@ # Changelog +## Version 1.5.0 + +*February 23, 2017* + +- Add [multiple tabs per programming language](https://github.com/lord/slate/wiki/Multiple-language-tabs-per-programming-language) feature +- Upgrade Middleman to add Ruby 1.4.0 compatibility +- Switch default code highlighting color scheme to better highlight JSON +- Various small typo and bug fixes + +## Version 1.4.0 + +*November 24, 2016* + +- Upgrade Middleman and Rouge gems, should hopefully solve a number of bugs +- Update some links in README +- Fix broken Vagrant startup script +- Fix some problems with deploy.sh help message +- Fix bug with language tabs not hiding properly if no error +- Add `!default` to SASS variables +- Fix bug with logo margin +- Bump tested Ruby versions in .travis.yml + +## Version 1.3.3 + +*June 11, 2016* + +Documentation and example changes. + +## Version 1.3.2 + +*February 3, 2016* + +A small bugfix for slightly incorrect background colors on code samples in some cases. + +## Version 1.3.1 + +*January 31, 2016* + +A small bugfix for incorrect whitespace in code blocks. + +## Version 1.3 + +*January 27, 2016* + +We've upgraded Middleman and a number of other dependencies, which should fix quite a few bugs. + +Instead of `rake build` and `rake deploy`, you should now run `bundle exec middleman build --clean` to build your server, and `./deploy.sh` to deploy it to Github Pages. + ## Version 1.2 -*June 20, 2014* +*June 20, 2015* **Fixes:** @@ -21,7 +69,7 @@ ## Version 1.1 -*July 27th, 2014* +*July 27, 2014* **Fixes:** diff --git a/CNAME b/CNAME new file mode 100644 index 00000000000..2944895ef06 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +developers.intelex.com \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index b04fc955ca5..00000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,9 +0,0 @@ -# Contributing to Slate - -Thanks for contributing to Slate! A couple of quick guidelines for submitting PRs: - -- Please point your pull requests at the `dev` branch, and keep your commit messages clear and informative. -- Please make sure your contributions work in the most recent version of Chrome, Firefox, and IE. -- If you're implementing a new feature, even if it's relatively small, it's nice to open an issue before you start so that others know what you're working on and can help make sure you're on the right track. - -Thanks again! Happy coding. \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 8183c7a8b04..00000000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM ubuntu:trusty - -RUN apt-get update -RUN apt-get install -yq ruby ruby-dev build-essential git -RUN gem install --no-ri --no-rdoc bundler -ADD Gemfile /app/Gemfile -ADD Gemfile.lock /app/Gemfile.lock -RUN cd /app; bundle install -ADD . /app -EXPOSE 4567 -WORKDIR /app -CMD ["bundle", "exec", "middleman", "server"] diff --git a/Gemfile b/Gemfile index 3a2a2e01a82..0b2029086bd 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,9 @@ source 'https://rubygems.org' # Middleman -gem 'middleman', '~>3.3.10' -gem 'middleman-gh-pages', '~> 0.0.3' -gem 'middleman-syntax', '~> 2.0.0' -gem 'middleman-autoprefixer', '~> 2.4.4' -gem 'rouge', '~> 1.9.0' -gem 'redcarpet', '~> 3.3.1' - -gem 'rake', '~> 10.4.2' -gem 'therubyracer', '~> 0.12.1', platforms: :ruby +gem 'middleman', '~>4.2.1' +gem 'middleman-syntax', '~> 3.0.0' +gem 'middleman-autoprefixer', '~> 2.7.0' +gem "middleman-sprockets", "~> 4.1.0" +gem 'rouge', '~> 2.0.5' +gem 'redcarpet', '~> 3.4.0' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index f9978492816..121b62da58f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,140 +1,126 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.1.11) - i18n (~> 0.6, >= 0.6.9) - json (~> 1.7, >= 1.7.7) + activesupport (5.0.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) minitest (~> 5.1) - thread_safe (~> 0.1) tzinfo (~> 1.1) - autoprefixer-rails (5.2.0.1) + addressable (2.5.0) + public_suffix (~> 2.0, >= 2.0.2) + autoprefixer-rails (6.6.1) execjs - json - celluloid (0.16.0) - timers (~> 4.0.0) - chunky_png (1.3.4) + backports (3.6.8) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.9.1.1) - compass (1.0.3) - chunky_png (~> 1.2) - compass-core (~> 1.0.2) - compass-import-once (~> 1.0.5) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - sass (>= 3.3.13, < 3.5) - compass-core (1.0.3) - multi_json (~> 1.0) - sass (>= 3.3.0, < 3.5) + coffee-script-source (1.12.2) compass-import-once (1.0.5) sass (>= 3.2, < 3.5) + concurrent-ruby (1.0.4) + contracts (0.13.0) + dotenv (2.2.0) erubis (2.7.0) - execjs (2.5.2) - ffi (1.9.8) - haml (4.0.6) + execjs (2.7.0) + fast_blank (1.0.0) + fastimage (2.0.1) + addressable (~> 2) + ffi (1.9.17) + ffi (1.9.17-x86-mingw32) + haml (4.0.7) tilt - hike (1.2.3) - hitimes (1.2.2) - hooks (0.4.0) - uber (~> 0.0.4) + hamster (3.0.0) + concurrent-ruby (~> 1.0) + hashie (3.5.1) i18n (0.7.0) - json (1.8.3) - kramdown (1.7.0) - libv8 (3.16.14.7) - listen (2.10.1) - celluloid (~> 0.16.0) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - middleman (3.3.12) + kramdown (1.13.2) + listen (3.0.8) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + memoist (0.15.0) + middleman (4.2.1) coffee-script (~> 2.2) - compass (>= 1.0.0, < 2.0.0) compass-import-once (= 1.0.5) - execjs (~> 2.0) haml (>= 4.0.5) kramdown (~> 1.2) - middleman-core (= 3.3.12) - middleman-sprockets (>= 3.1.2) + middleman-cli (= 4.2.1) + middleman-core (= 4.2.1) sass (>= 3.4.0, < 4.0) - uglifier (~> 2.5) - middleman-autoprefixer (2.4.4) - autoprefixer-rails (~> 5.2.0) + middleman-autoprefixer (2.7.1) + autoprefixer-rails (>= 6.5.2, < 7.0.0) middleman-core (>= 3.3.3) - middleman-core (3.3.12) - activesupport (~> 4.1.0) + middleman-cli (4.2.1) + thor (>= 0.17.0, < 2.0) + middleman-core (4.2.1) + activesupport (>= 4.2, < 5.1) + addressable (~> 2.3) + backports (~> 3.6) bundler (~> 1.1) + contracts (~> 0.13.0) + dotenv erubis - hooks (~> 0.3) + execjs (~> 2.0) + fast_blank + fastimage (~> 2.0) + hamster (~> 3.0) + hashie (~> 3.4) i18n (~> 0.7.0) - listen (>= 2.7.9, < 3.0) - padrino-helpers (~> 0.12.3) - rack (>= 1.4.5, < 2.0) - rack-test (~> 0.6.2) - thor (>= 0.15.2, < 2.0) - tilt (~> 1.4.1, < 2.0) - middleman-gh-pages (0.0.3) - rake (> 0.9.3) - middleman-sprockets (3.4.2) - middleman-core (>= 3.3) - sprockets (~> 2.12.1) - sprockets-helpers (~> 1.1.0) - sprockets-sass (~> 1.3.0) - middleman-syntax (2.0.0) - middleman-core (~> 3.2) - rouge (~> 1.0) - minitest (5.7.0) - multi_json (1.11.1) - padrino-helpers (0.12.5) + listen (~> 3.0.0) + memoist (~> 0.14) + padrino-helpers (~> 0.13.0) + parallel + rack (>= 1.4.5, < 3) + sass (>= 3.4) + servolux + tilt (~> 2.0) + uglifier (~> 3.0) + middleman-sprockets (4.1.0) + middleman-core (~> 4.0) + sprockets (>= 3.0) + middleman-syntax (3.0.0) + middleman-core (>= 3.2) + rouge (~> 2.0) + minitest (5.10.1) + padrino-helpers (0.13.3.3) i18n (~> 0.6, >= 0.6.7) - padrino-support (= 0.12.5) - tilt (~> 1.4.1) - padrino-support (0.12.5) + padrino-support (= 0.13.3.3) + tilt (>= 1.4.1, < 3) + padrino-support (0.13.3.3) activesupport (>= 3.1) - rack (1.6.4) - rack-test (0.6.3) - rack (>= 1.0) - rake (10.4.2) - rb-fsevent (0.9.5) - rb-inotify (0.9.5) + parallel (1.10.0) + public_suffix (2.0.5) + rack (2.0.1) + rb-fsevent (0.9.8) + rb-inotify (0.9.8) ffi (>= 0.5.0) - redcarpet (3.3.1) - ref (1.0.5) - rouge (1.9.0) - sass (3.4.14) - sprockets (2.12.3) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-helpers (1.1.0) - sprockets (~> 2.0) - sprockets-sass (1.3.1) - sprockets (~> 2.0) - tilt (~> 1.1) - therubyracer (0.12.2) - libv8 (~> 3.16.14.0) - ref - thor (0.19.1) + redcarpet (3.4.0) + rouge (2.0.7) + sass (3.4.23) + servolux (0.12.0) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + thor (0.19.4) thread_safe (0.3.5) - tilt (1.4.1) - timers (4.0.1) - hitimes + tilt (2.0.6) tzinfo (1.2.2) thread_safe (~> 0.1) - uber (0.0.13) - uglifier (2.7.1) - execjs (>= 0.3.0) - json (>= 1.8.0) + uglifier (3.0.4) + execjs (>= 0.3.0, < 3) + wdm (0.1.1) PLATFORMS ruby + x86-mingw32 DEPENDENCIES - middleman (~> 3.3.10) - middleman-autoprefixer (~> 2.4.4) - middleman-gh-pages (~> 0.0.3) - middleman-syntax (~> 2.0.0) - rake (~> 10.4.2) - redcarpet (~> 3.3.1) - rouge (~> 1.9.0) - therubyracer (~> 0.12.1) + middleman (~> 4.2.1) + middleman-autoprefixer (~> 2.7.0) + middleman-sprockets (~> 4.1.0) + middleman-syntax (~> 3.0.0) + redcarpet (~> 3.4.0) + rouge (~> 2.0.5) + wdm (~> 0.1.1) + +BUNDLED WITH + 1.14.6 diff --git a/README.md b/README.md index efb7e1eb8cd..8b137891791 100644 --- a/README.md +++ b/README.md @@ -1,122 +1 @@ -Slate -======== -[![Build Status](https://travis-ci.org/tripit/slate.svg?branch=master)](https://travis-ci.org/tripit/slate) [![Dependency Status](https://gemnasium.com/tripit/slate.png)](https://gemnasium.com/tripit/slate) - -Slate helps you create beautiful API documentation. Think of it as an intelligent, responsive documentation template for your API. - -Screenshot of Example Documentation created with Slate - -*The example above was created with Slate. Check it out at [tripit.github.io/slate](http://tripit.github.io/slate).* - -Features ------------- - -* **Clean, intuitive design** — with Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [Paypal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even print. - -* **Everything on a single page** — gone are the days where your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy. - -* **Slate is just Markdown** — when you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks! - -* **Write code samples in multiple languages** — if your API has bindings in multiple programming languages, you easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown! - -* **Out-of-the-box syntax highlighting** for [almost 60 languages](http://rouge.jayferd.us/demo), no configuration required. - -* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents. - -* **Let your users update your documentation for you** — by default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it's simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to, you're welcome to not use Github and host your docs elsewhere! - -Getting starting with Slate is super easy! Simply fork this repository, and then follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://tripit.github.io/slate). - - - -Getting Started with Slate ------------------------------- - -### Prerequisites - -You're going to need: - - - **Linux or OS X** — Windows may work, but is unsupported. - - **Ruby, version 1.9.3 or newer** - - **Bundler** — If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal. - -### Getting Set Up - - 1. Fork this repository on Github. - 2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` - 3. `cd slate` - 4. Install all dependencies: `bundle install` - 5. Start the test server: `bundle exec middleman server` - -Or use the included Dockerfile! (must install Docker first) - -```shell -docker build -t slate . -docker run -d -p 4567:4567 slate -``` - -You can now see the docs at . Whoa! That was fast! - -*Note: if you're using the Docker setup on OSX, the docs will be -availalable at the output of `boot2docker ip` instead of `localhost:4567`.* - -Now that Slate is all set up your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/tripit/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/tripit/slate/wiki/Deploying-Slate). - -Examples of Slate in the Wild ---------------------------------- - -* [Travis-CI's API docs](http://docs.travis-ci.com/api/) -* [Mozilla's localForage docs](http://mozilla.github.io/localForage/) -* [Mozilla Recroom](http://mozilla.github.io/recroom/) -* [ChaiOne Gameplan API docs](http://chaione.github.io/gameplanb2b/#introduction) -* [Drcaban's Build a Quine tutorial](http://drcabana.github.io/build-a-quine/#introduction) -* [PricePlow API docs](https://www.priceplow.com/api/documentation) -* [Emerging Threats API docs](http://apidocs.emergingthreats.net/) -* [Appium docs](http://appium.io/slate/en/master) -* [Golazon Developer](http://developer.golazon.com) -* [Dwolla API docs](https://docs.dwolla.com/) -* [RozpisyZapasu API docs](http://www.rozpisyzapasu.cz/dev/api/) -* [Codestar Framework Docs](http://codestarframework.com/documentation/) -* [Buddycloud API](http://buddycloud.com/api) -* [Crafty Clicks API](https://craftyclicks.co.uk/api/) -* [Paracel API Reference](http://paracel.io/docs/api_reference.html) -* [Switch Payments Documentation](http://switchpayments.com/docs/) & [API](http://switchpayments.com/developers/) -* [Coinbase API Reference](https://developers.coinbase.com/api) -* [Whispir.io API](https://whispir.github.io/api) -* [NASA API](https://data.nasa.gov/developer/external/planetary/) -* [CardPay API](https://developers.cardpay.com/) -* [IBM Cloudant](https://docs-testb.cloudant.com/content-review/_design/couchapp/index.html) -* [Bitrix basis components](http://bbc.bitrix.expert/) -* [viagogo API Documentation](http://developer.viagogo.net/) -* [Fidor Bank API Documentation](http://docs.fidor.de/) -* [Market Prophit API Documentation](http://developer.marketprophit.com/) - -(Feel free to add your site to this list in a pull request!) - -Need Help? Found a bug? --------------------- - -Just [submit a issue](https://github.com/tripit/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. - - -Contributors --------------------- - -Slate was built by [Robert Lord](https://lord.io) while at [TripIt](http://tripit.com). - -Thanks to the following people who have submitted major pull requests: - -- [@chrissrogers](https://github.com/chrissrogers) -- [@bootstraponline](https://github.com/bootstraponline) -- [@realityking](https://github.com/realityking) - -Also, thanks to [Sauce Labs](http://saucelabs.com) for helping sponsor the project. - -Special Thanks --------------------- -- [Middleman](https://github.com/middleman/middleman) -- [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js) -- [middleman-syntax](https://github.com/middleman/middleman-syntax) -- [middleman-gh-pages](https://github.com/neo/middleman-gh-pages) -- [Font Awesome](http://fortawesome.github.io/Font-Awesome/) diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 6a952e1e914..00000000000 --- a/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -require 'middleman-gh-pages' -require 'rake/clean' - -CLOBBER.include('build') - -task :default => [:build] diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000000..43b1f995459 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,39 @@ +Vagrant.configure(2) do |config| + config.vm.box = "ubuntu/trusty64" + config.vm.network :forwarded_port, guest: 4567, host: 4567 + + config.vm.provision "bootstrap", + type: "shell", + inline: <<-SHELL + sudo apt-get update + sudo apt-get install -yq ruby2.0 ruby2.0-dev pkg-config build-essential nodejs git libxml2-dev libxslt-dev + sudo apt-get autoremove -yq + gem2.0 install --no-ri --no-rdoc bundler + SHELL + + # add the local user git config to the vm + config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig" + + config.vm.provision "install", + type: "shell", + privileged: false, + inline: <<-SHELL + echo "==============================================" + echo "Installing app dependencies" + cd /vagrant + bundle config build.nokogiri --use-system-libraries + bundle install + SHELL + + config.vm.provision "run", + type: "shell", + privileged: false, + run: "always", + inline: <<-SHELL + echo "==============================================" + echo "Starting up middleman at http://localhost:4567" + echo "If it does not come up, check the ~/middleman.log file for any error messages" + cd /vagrant + bundle exec middleman server --force-polling --latency=1 &> ~/middleman.log & + SHELL +end diff --git a/config.rb b/config.rb index 43bceaa5a43..b7df3586bec 100644 --- a/config.rb +++ b/config.rb @@ -17,6 +17,11 @@ # Activate the syntax highlighter activate :syntax +ready do + require './lib/multilang.rb' +end + +activate :sprockets activate :autoprefixer do |config| config.browsers = ['last 2 version', 'Firefox ESR'] @@ -30,9 +35,15 @@ # Build Configuration configure :build do + # If you're having trouble with Middleman hanging, commenting + # out the following two lines has been known to help activate :minify_css activate :minify_javascript # activate :relative_assets # activate :asset_hash # activate :gzip end + +# Deploy Configuration +# If you want Middleman to listen on a different port, you can set that below +set :port, 4567 diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000000..909a9d9089d --- /dev/null +++ b/deploy.sh @@ -0,0 +1,203 @@ +#!/usr/bin/env bash +set -o errexit #abort if any command fails +me=$(basename "$0") + +help_message="\ +Usage: $me [-c FILE] [] +Deploy generated files to a git branch. + +Options: + + -h, --help Show this help information. + -v, --verbose Increase verbosity. Useful for debugging. + -e, --allow-empty Allow deployment of an empty directory. + -m, --message MESSAGE Specify the message used when committing on the + deploy branch. + -n, --no-hash Don't append the source commit's hash to the deploy + commit's message. +" + +bundle exec middleman build --clean + +parse_args() { + # Set args from a local environment file. + if [ -e ".env" ]; then + source .env + fi + + # Parse arg flags + # If something is exposed as an environment variable, set/overwrite it + # here. Otherwise, set/overwrite the internal variable instead. + while : ; do + if [[ $1 = "-h" || $1 = "--help" ]]; then + echo "$help_message" + return 0 + elif [[ $1 = "-v" || $1 = "--verbose" ]]; then + verbose=true + shift + elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then + allow_empty=true + shift + elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then + commit_message=$2 + shift 2 + elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then + GIT_DEPLOY_APPEND_HASH=false + shift + else + break + fi + done + + # Set internal option vars from the environment and arg flags. All internal + # vars should be declared here, with sane defaults if applicable. + + # Source directory & target branch. + deploy_directory=build + deploy_branch=gh-pages + + #if no user identity is already set in the current git environment, use this: + default_username=${GIT_DEPLOY_USERNAME:-deploy.sh} + default_email=${GIT_DEPLOY_EMAIL:-} + + #repository to deploy to. must be readable and writable. + repo=origin + + #append commit hash to the end of message by default + append_hash=${GIT_DEPLOY_APPEND_HASH:-true} +} + +main() { + parse_args "$@" + + enable_expanded_output + + if ! git diff --exit-code --quiet --cached; then + echo Aborting due to uncommitted changes in the index >&2 + return 1 + fi + + commit_title=`git log -n 1 --format="%s" HEAD` + commit_hash=` git log -n 1 --format="%H" HEAD` + + #default commit message uses last title if a custom one is not supplied + if [[ -z $commit_message ]]; then + commit_message="publish: $commit_title" + fi + + #append hash to commit message unless no hash flag was found + if [ $append_hash = true ]; then + commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash" + fi + + previous_branch=`git rev-parse --abbrev-ref HEAD` + + if [ ! -d "$deploy_directory" ]; then + echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2 + return 1 + fi + + # must use short form of flag in ls for compatibility with OS X and BSD + if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then + echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2 + return 1 + fi + + if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then + # deploy_branch exists in $repo; make sure we have the latest version + + disable_expanded_output + git fetch --force $repo $deploy_branch:$deploy_branch + enable_expanded_output + fi + + # check if deploy_branch exists locally + if git show-ref --verify --quiet "refs/heads/$deploy_branch" + then incremental_deploy + else initial_deploy + fi + + restore_head +} + +initial_deploy() { + git --work-tree "$deploy_directory" checkout --orphan $deploy_branch + git --work-tree "$deploy_directory" add --all + commit+push +} + +incremental_deploy() { + #make deploy_branch the current branch + git symbolic-ref HEAD refs/heads/$deploy_branch + #put the previously committed contents of deploy_branch into the index + git --work-tree "$deploy_directory" reset --mixed --quiet + git --work-tree "$deploy_directory" add --all + + set +o errexit + diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$? + set -o errexit + case $diff in + 0) echo No changes to files in $deploy_directory. Skipping commit.;; + 1) commit+push;; + *) + echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2 + return $diff + ;; + esac +} + +commit+push() { + set_user_id + git --work-tree "$deploy_directory" commit -m "$commit_message" + + disable_expanded_output + #--quiet is important here to avoid outputting the repo URL, which may contain a secret token + git push --quiet $repo $deploy_branch + enable_expanded_output +} + +#echo expanded commands as they are executed (for debugging) +enable_expanded_output() { + if [ $verbose ]; then + set -o xtrace + set +o verbose + fi +} + +#this is used to avoid outputting the repo URL, which may contain a secret token +disable_expanded_output() { + if [ $verbose ]; then + set +o xtrace + set -o verbose + fi +} + +set_user_id() { + if [[ -z `git config user.name` ]]; then + git config user.name "$default_username" + fi + if [[ -z `git config user.email` ]]; then + git config user.email "$default_email" + fi +} + +restore_head() { + if [[ $previous_branch = "HEAD" ]]; then + #we weren't on any branch before, so just set HEAD back to the commit it was on + git update-ref --no-deref HEAD $commit_hash $deploy_branch + else + git symbolic-ref HEAD refs/heads/$previous_branch + fi + + git reset --mixed +} + +filter() { + sed -e "s|$repo|\$repo|g" +} + +sanitize() { + "$@" 2> >(filter 1>&2) | filter +} + +[[ $1 = --source-only ]] || main "$@" diff --git a/lib/multilang.rb b/lib/multilang.rb new file mode 100644 index 00000000000..2448188de26 --- /dev/null +++ b/lib/multilang.rb @@ -0,0 +1,16 @@ +module Multilang + def block_code(code, full_lang_name) + if full_lang_name + parts = full_lang_name.split('--') + rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified + super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match| + match + " tab-" + full_lang_name + end + else + super(code, full_lang_name) + end + end +end + +require 'middleman-core/renderers/redcarpet' +Middleman::Renderers::MiddlemanRedcarpetHTML.send :include, Multilang \ No newline at end of file diff --git a/source/CNAME b/source/CNAME new file mode 100644 index 00000000000..2944895ef06 --- /dev/null +++ b/source/CNAME @@ -0,0 +1 @@ +developers.intelex.com \ No newline at end of file diff --git a/source/alpha.html.md b/source/alpha.html.md new file mode 100644 index 00000000000..5deda7fc251 --- /dev/null +++ b/source/alpha.html.md @@ -0,0 +1,15 @@ +--- +title: Intelex API Reference + +language_tabs: + - javascript: JavaScript + - csharp: C# + +includes: + - interface-api + - package-api + - dev-support + +search: true +--- + diff --git a/source/images/logo.png b/source/images/logo.png index fa1f13da819..94526502526 100644 Binary files a/source/images/logo.png and b/source/images/logo.png differ diff --git a/source/includes/_acts-api.md b/source/includes/_acts-api.md new file mode 100644 index 00000000000..de1400d5cc1 --- /dev/null +++ b/source/includes/_acts-api.md @@ -0,0 +1,3 @@ +# ACTS API + +The ACTS API gives you the ability to retrieve or update data of selected database tables in ACTS product. diff --git a/source/includes/_api-reference.md b/source/includes/_api-reference.md new file mode 100644 index 00000000000..9cb82e6cf73 --- /dev/null +++ b/source/includes/_api-reference.md @@ -0,0 +1,157 @@ +# API Reference + +The Intelex API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP authentication and HTTP verbs, which are understood by off-the-shelf HTTP clients. JSON is returned by all API responses, including errors. + +## Getting Started + +> API Endpoint - replace **intelex_url** with the full URL path to your Intelex system + +``` +https://intelex_url/api/v2/ +``` + +To begin using the Intelex API you will need: + +* Your own instance of the Intelex platform with the REST API enabled +* A valid Intelex system user account +* The full URL to your Intelex system +* A basic understanding of the [Intelex Application model](https://community.intelex.com/library/knowledgebase/help/Content/Getting%20Started/Application%20Builder.htm). + +## Authentication + +> Example Requests: + +```javascript +// Basic Authentication +var request = require("request"); + +var options = { + headers: { Authorization: "Basic [insert credentials here]" } + }; + + +//ApiKey Authentication +var request = require("request"); + +var options = { + headers: { Authorization: "ApiKey [insert key here]" } + }; + + +// Secure Access Token Authentication +var request = require("request"); + +var options = { + headers: { Authorization: "Bearer [insert Access token here]" } + }; +``` + +```csharp + +// Basic Authentication +var request = new RestRequest(Method.GET); + +request.AddHeader("Authorization", "Basic [insert credentials here]"); + + +// ApiKey Authentication +var request = new RestRequest(Method.GET); + +request.AddHeader("Authorization", "ApiKey [insert key here]"); + + +// Secure Access Token Authentication +var request = new RestRequest(Method.GET); + +request.AddHeader("Authorization", "Bearer [insert Access token here]"); +``` + +The Intelex API supports three methods for authentication: Basic, ApiKey, and Secure. All API requests must be made over HTTPS and API requests without authentication will fail. Only Admin and Full Access users can use ApiKey and Secure authentication. + +Security on data for all types of authentication is managed by the platform security configuration. API requests will maintain the security settings configured for the user on the Intelex platform. + +Basic authentication is performed via HTTP Basic Auth with your Intelex user credentials (Username:Password). The credentials are verified by Intelex and access granted or denied accordingly. + +ApiKey authentication can be performed by generating API access key(s) from the Intelex User Profile menu (note that this page is only accessible to full-access and admin users). The unique generated key can then be used to authenticate with the Intelex REST API. + +Starting at Platform Version 6.6.7, secure token based authentication is supported by the V6 API. This form of authentication needs to be enabled by Intelex. During the authentication process, the client provides the ‘client id’ and ‘client secret’ to the authentication endpoint, along with the audience and grant type, as shown in the example. In response, the API furnishes an access token that comes with a specified expiration. After successful authentication, clients gain access to V6 API endpoints. + +>Example Requests: + +```CSharp +Body for Authentication Endpoint +{"client_id":"Client ID Data", +"client_secret":"Client Secret Data", +"audience":"https://api.intelex.com/v6/", +"grant_type":"client_credentials"} +``` + +>Example Response: + +```json +{ + "access_token": "Generated Bearer Access Token Used For Validation", + "expires_in": "Token Expiry Time In Seconds", + "token_type": "Bearer" +} +``` + +### Get endpoint, secured client id and client secret + +Login to the V6 application. Navigate to System Administration, User Administration, and then Navigate to API Access. +Select the secured API from the API Access page; the endpoint, client id and client secret will be displayed on the details page. Use these to obtain an access token via API end point. + +## Data Format + +The Intelex API only supports [JSON](http://www.json.org/) as the data format for requests and responses. + +## Response Codes + +> Example error response + +```json +{ + "error": { + "code": "string", + "message": "string" + } +} +``` + +The Intelex REST API will respond with the following HTTP status codes: + +Response Code | Meaning +---------- | ------- +200 | Success -- Enjoy your data! +201 | Created -- We created the record! +204 | No Content -- Your request was successful, but we don't have anything more to tell you +400 | Bad Request -- Something is wrong with your request +401 | Unauthorized -- Your credentials are wrong +403 | Forbidden -- You do not have permission to access the resource +404 | Not Found -- The object or navigation property you are trying to access doesn't exist +405 | Method Not Allowed -- We won't let you do that +429 | Too Many Requests -- You have sent too many requests and have to wait till you can send more +500 | Internal Server Error -- We had a problem with our server. Try again later +501 | Not Implemented -- What you are trying to do doesn't work...yet. + +## Versioning + +When we make backwards-incompatible changes to the API, we release new versions. The current version is **v2** and can be determined with our API base path **/api/v2/**. Read our [Intelex platform release notes](https://community.intelex.com/library/knowledgebase/release-notes) to see our API changelog. + +## API Rate Limiting / Quotas +To ensure Intelex Platform is reliable and has the expected performance for all users, we limit the number of API calls an API user (or application) can make within a given time period. If the limit is exceeded, the API user may be throttled and subsequent requests will fail returning HTTP resposne code 429 Too Many Requests. In such cases, it is the responsibility of the client application to implement appropriate retry logic for requests that fail due to rate limiting. + +### Limit +The Intelex Platform API Rate limit is **6 requests per second**. + +### Quota headers +Quota details may be passed back to the API user/application via response headers. + +Header | Description | Sample value +---------- | ------- | ------- +Retry-After | Time in seconds to wait before retrying the request after rate limit is exceeded. | 600 + +### Best Practices + +* Use HTTP clients that support automatic retries with an exponential back-off strategy when receiving 429 (Too Many Requests) responses. +* Avoid spikes of traffic by spreading out API calls over time wherever possible. \ No newline at end of file diff --git a/source/includes/_dev-support.md b/source/includes/_dev-support.md new file mode 100755 index 00000000000..5a0d06173a6 --- /dev/null +++ b/source/includes/_dev-support.md @@ -0,0 +1,12 @@ +# Developer Support + +[Join the Intelex Developer group on Community](https://community.intelex.com/connect/groups/developer-community) and: + +* Stay up-to-date about our API +* Ask technical questions +* Give us feedback +* Submit support requests + + + + diff --git a/source/includes/_errors.md b/source/includes/_errors.md deleted file mode 100644 index 56cffb34d22..00000000000 --- a/source/includes/_errors.md +++ /dev/null @@ -1,20 +0,0 @@ -# Errors - - - -The Kittn API uses the following error codes: - - -Error Code | Meaning ----------- | ------- -400 | Bad Request -- Your request sucks -401 | Unauthorized -- Your API key is wrong -403 | Forbidden -- The kitten requested is hidden for administrators only -404 | Not Found -- The specified kitten could not be found -405 | Method Not Allowed -- You tried to access a kitten with an invalid method -406 | Not Acceptable -- You requested a format that isn't json -410 | Gone -- The kitten requested has been removed from our servers -418 | I'm a teapot -429 | Too Many Requests -- You're requesting too many kittens! Slow down! -500 | Internal Server Error -- We had a problem with our server. Try again later. -503 | Service Unavailable -- We're temporarially offline for maintanance. Please try again later. diff --git a/source/includes/_interface-api.md b/source/includes/_interface-api.md new file mode 100644 index 00000000000..3637f3e1ac8 --- /dev/null +++ b/source/includes/_interface-api.md @@ -0,0 +1,255 @@ +# Interface API + +## Requesting System Info + +The following resources give you access to system information + +### Requesting Apps + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/apps' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/apps"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "Id": "string", + "Caption": "string", + "Group": "string", + "Icon": "string", + "NavigationUrl": "string" + } + ] +} +``` + +Returns the apps that you can use + +#### GET /api/v2/apps + +Attribute | Description +--------- | ----------- +Id | Application ID +Caption | Application name +Group | Group that the app belongs to +Icon | Icon for the application +NavigationUrl | Navigation URL of application + + + +### Requesting Reports + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/reports' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/reports"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "Id": "string", + "Caption": "string", + "NavigationUrl": "string" + } + ] +} +``` + +Returns the reports that you can view + +#### GET /api/v2/reports + +Attribute | Description +--------- | ----------- +Id | Report ID +Caption | Report name +NavigationUrl | URL to view report + + +### Requesting Dashboards + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/dashboards' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/dashboards"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "Id": "string", + "Caption": "string", + "NavigationUrl": "string" + } + ] +} +``` + +Returns the dashboards that you can view + +#### GET /api/v2/dashboards + +Attribute | Description +--------- | ----------- +Id | Dashboard ID +Caption | Dashboard name +NavigationUrl | URL to view dashboard + +### Requesting Locations + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/locations' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/locations"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "Id": "string", + "Code": "string", + "Name": "string", + "Enabled": true, + "Children": [ + { + "Id": "string", + "Code": "string", + "Name": "string", + "Enabled": true + } + ] + } + ] +} +``` + +Returns the location hierarchy + +#### GET /api/v2/locations + +Attribute | Description +--------- | ----------- +Id | Location ID +Code | Location code +Name | Location name +Enabled | Determines if the location can be accessed +Children | An array of child locations + +### Requesting User Info + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/users/me' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/users/me"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "Login": "string", + "FullName": "string", + "DefaultToolbar": [] +} +``` + +Returns a user's details + +#### GET /api/v2/users/me + +Attribute | Description +--------- | ----------- +Login | Username +FullName | User's full name +DefaultToolbar | Details of the user's default toolbar + diff --git a/source/includes/_object-data-api.md b/source/includes/_object-data-api.md new file mode 100644 index 00000000000..bc06313e147 --- /dev/null +++ b/source/includes/_object-data-api.md @@ -0,0 +1,2315 @@ +# Object Data API + +> Object Data API Endpoint - replace **intelex_object** with the system name of your object + +``` +https://intelex_url/api/v2/object/intelex_object +``` + +The Object Data API gives you the ability to create, retrieve, update, and delete data in your Intelex application objects. Each Object Data API resource is an Intelex application object. Access each resource by using the system name of the object in the API endpoint URL. The data sent and returned with your API requests are the fields that exist on the object you are accessing. The system name of fields is used in every request and response. + +Your instance of Intelex may include system and custom objects. System objects include general platform objects and standard application objects. Custom objects are any objects created from scratch for your organization. All of these objects have unique system names. You'll find the system name on the object detail page, in the System Name field. + + +## Record Metadata +> Example response with record metadata + +```json +{ + "value": { + "@odata.type": "#Intelex.IncidentsObject", + "@odata.id": "https://intelex_url/api/v2/object/IncidentsObject(UID)", + "@odata.editLink": "https://intelex_url/api/v2/object/IncidentsObject(UID)" + } +} +``` + +Some records returned from the API will contain a few properties that provide some useful information. + +Property | Description +--------- | ----------- +@odata.type|The entity type of the record. Useful when requesting records from parent objects +@odata.id|A URL that can be used to access the record. To remove this property from your requests, append the query string key/value of: **noIdLink=1** to your request URI +@odata.editLink|Denotes if the record can be modified by the user making the request. Same as @odata.id link. To remove this property from your requests, append the query string key/value of: **noEditLink=1** to your request URI + +## Record Limits +> Example response with pagination link + +```json +{ + "@odata.nextLink": "https://intelex_url/api/v2/object/IncidentsObject?$skip=500" +} +``` + +We've provided a convenient way to access more data in any request for sequential data where the number of records exceeds 500. Simply call the url in the nextLink parameter and we'll respond with the next set of data. + +## Object Relational Data +Many Intelex objects have relations to other objects. These relations are configured as relation type or lookup type fields. These fields are accessible via the API as navigation properties. +Every object will have navigation properties that can be used to access its related data in another object. You'll need to use the system name of the field configured with the related object in order to access related data. + +You can access related data by using the [$expand](#query-option-expand) query option or you can [navigate to related data](#requesting-related-records) using a URL path. You can traverse multiple levels of relational data by navigating through the URL path or with nested $expand queries. + +Please note: Trying to access or modify relation fields that are self-referencing will not work (i.e. A relation type field on an object that is a relation to itself) + + +## System Objects + +Sometimes you might need to access data from system objects that contain data such as Employees or Locations. Here are some of the system objects for your reference: + +System Object | Description | System Name +--------- | ----------- | --------- +Employees | Intelex Employees | SysEmployeeEntity +Users | Intelex Users | SysUserEntity +Locations | Intelex locations | SysLocationEntity +Groups | Intelex Employee groups | SysGroupEntity +EDIS Staging Table | Staging table used to process EDIS | EmployeeStagingEntity + +## Requesting Object Data + +### Requesting records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" + } + ] +} +``` + +Returns all records from an Intelex object that the user is authorized to view + +#### GET /api/v2/object/{intelex_object} + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject + +### Requesting a specific record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" +} +``` + +Returns an individual record from the Incidents object by referencing the UID of the record + +#### GET /object/{intelex_object}({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject +id | The Intelex UID of the record being requested + + +### Requesting related records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" + } + ] +} +``` + +Navigating to related records allows clients to request only the relational data belonging to a parent record. This includes relation type fields, lookup type fields, private document attachments, and workflow. + +#### GET /object/{intelex_object}({id})/{navigation_property} + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject +id | The Intelex UID of the record being requested +navigation_property|The Intelex system name of the relation type or lookup type field + +### Requesting a specific related record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents(UID)' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents(UID)"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" +} +``` + +Navigating to related records allows clients to request only the relational data belonging to a parent record. This includes relation type fields, lookup type fields, private document attachments, and workflow. + +#### GET /object/{intelex_object}({id})/{navigation_property}({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject +id | The Intelex UID of the record or related record being requested +navigation_property|The Intelex system name of the relation type or lookup type field + +## Querying Object Data + +### Selecting record fields + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + qs: { '$select': 'IncidentNo' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject?$select=IncidentNo"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "IncidentNo": 0 + } + ] +} +``` + +The $select system query option allows clients to request a limited set of fields for each record. + +#### GET /object/{intelex_object}?$select={field_name} + +Option | Example Values +--------- | ----------- +Select a single field | $select=IncidentNo +Select mutliple fields | $select=IncidentNo, Description + +##### URL Parameters + +Parameter | Description +--------- | ----------- +field_name | Field name(s) to include in response + +### Counting records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + qs: { '$count': 'true' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject?$count=true"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.count": 1, + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" + } + ] +} +``` + +The $count system query option with a value of true specifies that the total count of items within a collection matching the request be returned along with the result. + +#### GET /object/{intelex_object}?$count=true + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject + +### Paginating records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + qs: { '$skip': '10', '$top': '5' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject?$skip=10&$top=5"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" + } + ] +} +``` + +The $top system query option requests the number of items in the queried collection to be included in the result. The $skip query option requests the number of items in the queried collection that are to be skipped and not included in the result. + +#### GET /object/{intelex_object}?$top={top_n}&$skip={skip_n} + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject + +##### Query Parameters +Parameter | Description +--------- | ----------- +top_n | Number of items to be included in the response +skip_n| Number of items to be skipped + +### Sorting records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + qs: { '$orderby': 'DateCreated desc' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject?$orderby=DateCreateddesc"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" + } + ] +} +``` + +The $orderby system query option allows clients to request records in either ascending order using 'asc' or descending order using 'desc'. Default is ascending. The request below sorts the collection by date in descending order. + +#### GET /object/{intelex_object}?$orderby={field_name} + +Option | Example Values +-------- | -------- +Sort by descending|$orderby=DateCreated desc +Sort by ascending|$orderby=DateCreated asc +Sort by drop-down value |$orderby=Severity/Caption +Sort by multiple fields|$orderby=DateCreated, Severity/Caption +Sort by workflow person responsible|$orderby=Workflow/PersonResponsible/Name + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject + +##### Query Parameters + +Parameter | Description +--------- | ----------- +field_name | Fields that you want to sort by + +### Filtering records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + qs: { '$filter': 'IncidentNo eq 1000' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject?$filter=IncidentNo eq 10"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" + } + ] +} +``` + + +The $filter system query option allows clients to filter a collection of records. The expression specified with $filter is evaluated for each record in the collection, and only items where the expression evaluates to true are included in the response. There are built-in filter operators that can be used in order to retrieve the data you need + +#### GET /object/{intelex_object}?$filter={filter_expression} + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject + +##### Query Parameters + +Parameter | Description +--------- | ----------- +filter_expression | Filter expression used to query data + + +##### Comparison Operators: +|Name|Description|Example Values| +|---|---|---| +|eq|Equal|Severity/Value eq 'Moderate' +|ne|Not equal|Description ne null +|gt|Greater than|IncidentNo gt 1000 +|ge|Greater than or equal|DateCreated ge 2017-01-01 +|lt|Less than|IncidentNo lt 1000 +|le|Less than or equal|DateCreated le 2014-11-24T12:55:05.35-05:00 + +##### Logical Operators: +|Name|Description|Example Values| +|---|---|---| +|and|Logical and|Description ne null and Workflow/PersonResponsible/Name eq 'AC Slater' +|or|Logical or|Cause eq true or IncidentNo gt 1000 +|not|Logical not|not(contains(Description, 'accident')) + +##### Grouping Operators: +|Name|Description|Example Values| +|---|---|---| +|( )|Precedence grouping|IncidentNo gt 1000 and (Severity/Value eq 'Moderate' or contains(Description, 'fall')) + +##### Functions: +|Name|Description|Example Values| +|---|---|---| +|contains(Field, Value)|Sub-string search|contains(Description, 'accident')) + +##### Filtering using Relation Fields: +|Description|Example Values| +|---|---| +|Filtering by drop-down value |Severity/Value eq 'Moderate' +|Filtering by sub-record values|SubIncidents/any(x:x/SubIncidentId gt 1000) + +##### Filtering using Workflow: +|Description|Example Values| +|---|---| +|Filter based on person responsible|Workflow/PersonResponsible/Name eq 'AC Slater' +|Filter based on workflow status (enum)|Workflow/WorkflowStatus eq Enum.WorkflowStatusType'Completed' + +##### Filtering tasks assigned to you + +`assignedToMe()` is a function that can be used in expressions to easily filter tasks assigned to you as an individual, as a member of a location role, or member of a group. Requires Web Platform Release 6.5.131 or higher. + +|Description|Example Values| +|---|---| +|Filter my tasks on current object|$filter=assignedToMe()| +|Filter others’ tasks on current object|$filter=not assignedToMe()| +|Filter tasks on a M:1 field on the current object|$filter=assignedToMe(Audit/Workflow/PersonResponsible/Id)| +|Filter others’ tasks on a M:1 field on the current object|$filter=not assignedToMe(Audit/Workflow/PersonResponsible/Id)| + +When filtering for a field, you have to specify the full path up to the Id of the Person Responsible, as in the examples above. + +You can only access the records you have permission to view. + +##### Filter alias +@me is an alias that can be used in expressions to filter based on your identity' + +|Description|Example Values| +|---|---| +|Filter where you are the person responsible|$filter=Workflow/PersonResponsible eq @me| + +### Expanding related records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + qs: { '$expand': 'Location' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject?$expand=Location"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string", + "Location": { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "DateCreated": "2015-01-28T16:24:19.63-05:00", + "DateModified": "2016-04-21T15:02:38.723-04:00", + "Address1": null, + "Address2": null, + "Area": null, + "BusinessUnits": null, + "City": null + } + } + ] +} +``` + +The $expand system query option specifies the related object records and lookup object records to be included in-line with requested records. The parameter accepts a comma-separated list of relation field names. Use the system name of the relation type field or lookup type field in your query. + +#### GET /object/{intelex_object}?$expand={relation_field} + +|Option|Example Values| +| -------- | -------- | +|Expand a single relation field|$expand=Severity| +|Expand multiple relation fields|$expand=Severity, Workflow| +|Expand all relations|$expand=*| +|Nested expand|$expand=Workflow($expand=PersonResponsible)| +|Select expanded fields|$expand=Severity($select=Name)| +|Sort expanded collection|$expand=SubIncidents($orderby=DateCreated)| +|Filter expanded collection|$expand=SubIncidents($filter=Description ne null)| +|Filter and select expanded collection|$expand=SubIncidents($filter=Description ne null;$select=Description)| +|Expand child locations on SysLocationEntity system object - 1 level| /object/SysLocationEntity?$expand=ChildLocations +|Expand child locations on SysLocationEntity system object - multi-level| /object/SysLocationEntity?$expand=ChildLocations($expand=ChildLocations) +|Expand parent location on SysLocationEntity system object| /object/SysLocationEntity?$expand=ParentLocation + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject + +##### Query Parameters + +Parameter | Description +--------- | ----------- +relation_field | Relation field used to request related object data + +## Modifying Object Data + +### Create a record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/object/IncidentsObject', + headers: { 'content-type': 'application/json' }, + body: + { ActionsTaken: 'string', + Date: '2017-02-13T22:15:30.203Z', + Description: 'string', + IncidentNo: 0, + ReportedDate: '2017-02-13T22:15:30.203Z', + SuspectedCause: 'string' }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"ActionsTaken\": \"string\",\r\n \"Date\": \"2017-02-13T22:15:30.203Z\",\r\n \"Description\": \"string\",\r\n \"IncidentNo\": 0,\r\n \"ReportedDate\": \"2017-02-13T22:15:30.203Z\",\r\n \"SuspectedCause\": \"string\"\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" +} +``` +> Example request of creating a record and setting a location value: + +```json +{ + "Location@odata.bind": "https://intelex_url/api/v2/object/LocationObject(Id)" +} +``` + +> Example request of creating a record and setting a lookup type value: + +```json +{ + "Severity@odata.bind": "https://intelex_url/api/v2/object/SeverityLookupObject(Id)" +} +``` + +> Example request of creating a record and set workflow recurrence or person responsible: + +```json +{ + "Workflow": { + "PersonResponsible@odata.bind": "https://intelex_url/api/v2/object/EmployeeObject(UID)", + "RecurringSeries": { + "Frequency": "RRULE:FREQ=HOURLY", + "StartDate": "2017-06-06T02:30:00-05:00", + "EndDate": "2017-07-07T02:30:00-05:00" + } + } +} +``` + +> Example request of creating a record and attaching related records: + +```json +{ + "RelatedIncidents@odata.bind": [ + "https://intelex_url/api/v2/object/RelatedIncidentObject(Id)", + "https://intelex_url/api/v2/object/RelatedIncidentObject(Id)" + ] +} +``` + +Creates a record with values in the object specified in the path. A client generated GUID can be used when creating records. Creating a record also supports setting a value for related fields, lookup types, or workflow person responsible. You can do this by binding the @odata.id property of the related record to the field. + +#### POST /object/{intelex_object} + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject + +##### Body Parameters + +Parameter | Description +--------- | ----------- +field_name | The value you want to set for your object field. Replace *field_name* with the system name of the object field +relation_field@odata.bind| The @odata.id of the related record you want to associate to a relational field. Replace *relation_field* with the system name of the relation type field you want to set + + +##### Header Parameters + +When you create a record you also have the opportunity to execute an available workflow action within the same request. This is useful if you'd like a record to move to stage when it is created. In order to execute a workflow stage action within a create request, you'll need to provide a header parameter. + +Parameter | Description |Required | Example Value +--------- | ----------- |--------- | ----------- +ActionToExecute | UID of the workflow stage action|No|Id=797bbb3b-b485-4e73-a21c-2b9d5454f8ab + +### Create a sub-record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents', + headers: { 'content-type': 'application/json' }, + body: + { ActionsTaken: 'string', + Date: '2017-02-13T22:15:30.203Z', + Description: 'string', + IncidentNo: 0, + ReportedDate: '2017-02-13T22:15:30.203Z', + SuspectedCause: 'string' }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"ActionsTaken\": \"string\",\r\n \"Date\": \"2017-02-13T22:15:30.203Z\",\r\n \"Description\": \"string\",\r\n \"IncidentNo\": 0,\r\n \"ReportedDate\": \"2017-02-13T22:15:30.203Z\",\r\n \"SuspectedCause\": \"string\"\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "ActionsTaken": "string", + "Date": "2017-02-13T22:15:30.203Z", + "Description": "string", + "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", + "SuspectedCause": "string" +} +``` + +You can also create related records by sending POST requests to navigation properties. This request will create the record in the related object referenced by the navigation_property. Setting location,person responsible, and attaching related records is also supported when creating related records. + +#### POST /object/{intelex_object}({id})/{navigation_property} + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id| The Intelex UID of the parent record +navigation_property|The Intelex system name of the relation type field that supports sub-records i.e. "Has a list of attached" + +##### Body Parameters + +Parameter | Description +--------- | ----------- +field_name | The value you want to set for your related object field. Replace *field_name* with the system name of the object field + +##### Header Parameters + +When you create related records you also have the opportunity to execute an available workflow action within the same request. This is useful if you'd like a record to move to stage when it is created. In order to execute a workflow stage action within a create request, you'll need to provide a header parameter. + +Parameter | Description |Required | Example Value +--------- | ----------- |--------- | ----------- +ActionToExecute | UID of the workflow stage action|No|Id=797bbb3b-b485-4e73-a21c-2b9d5454f8ab + +### Update a record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'PATCH', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)', + headers: { 'content-type': 'application/json' }, + body: { Description: 'string' }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)"); +var request = new RestRequest(Method.PATCH); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"Description\": \"string\"\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Example of updating a location value: + +```json +{ + "Location@odata.bind": "https://intelex_url/api/v2/object/LocationObject(UID)" +} +``` + +> Example of updating a lookup type value: + +```json +{ + "Severity@odata.bind": "https://intelex_url/api/v2/object/SeverityLookupObject(UID)" +} +``` + +> Example of attaching related records: + +```json +{ + "RelatedIncidents@odata.bind": [ + "https://intelex_url/api/v2/object/RelatedIncidentObject(UID)", + "https://intelex_url/api/v2/object/RelatedIncidentObject(UID)" + ] +} +``` + +Updates a record in the object specified in the path. You can update values for related fields, lookup types by binding the @odata.id property of the related record to the field. + +#### PATCH /object/{intelex_object}({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being updated + +##### Body Parameters + +Parameter | Description +--------- | ----------- +field_name | The value you want to set for your object field. Replace *field_name* with the system name of the object field +relation_field@odata.bind| The @odata.id of the related record you want to associate to a relational field. Replace *relation_field* with the system name of the relation type field you want to set + +##### Header Parameters + +When you update a record you also have the opportunity to execute an available workflow action within the same request. This is useful if you'd like a record to move to stage when it is updated. In order to execute a workflow stage action within an update request, you'll need to provide a header parameter. + +Parameter | Description |Required | Example Value +--------- | ----------- |--------- | ----------- +ActionToExecute | UID of the workflow stage action|No|Id=797bbb3b-b485-4e73-a21c-2b9d5454f8ab + +### Delete a record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)"); +var request = new RestRequest(Method.DELETE); +IRestResponse response = client.Execute(request); +``` + +Deletes an individual record in the Intelex object specified in the path. If SoftDelete is enabled for the object then the record will be archived instead. + +#### DELETE /object/{intelex_object}({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject +id|The Intelex UID of the record being updated + +### Delete a sub-record + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents(UID)' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/SubIncidents(UID)"); +var request = new RestRequest(Method.DELETE); +IRestResponse response = client.Execute(request); +``` + +Deletes an individual sub-record in the Intelex object specified in the path. If SoftDelete is enabled for the object then the record will be archived instead. + +#### DELETE /object/{intelex_object}({id})/{navigation_property}({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object being requested eg. IncidentsObject +id|The Intelex UID of the record or related record being accessed +navigation_property|The Intelex system name of the relation type field + +### Removing a single value reference + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Severity/$ref' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Severity/$ref"); +var request = new RestRequest(Method.DELETE); +IRestResponse response = client.Execute(request); +``` + +Sets the value in a drop-down to null. This call is useful if you need to remove a value that's been set for a record. + +#### DELETE /object/{intelex_object}({id})/{navigation_property}/$ref + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record +navigation_property|The Intelex system name of the relation type field - must be a drop-down relation type field + +### Removing a multi-value reference + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/RelatedIncidents(UID)/$ref' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/RelatedIncidents(UID)/$ref"); +var request = new RestRequest(Method.DELETE); +IRestResponse response = client.Execute(request); +``` + +This request detaches a related records. It deletes the relationship, but does not delete the related record itself. + +#### DELETE /object/{intelex_object}({id})/{navigation_property}({id})/$ref + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record or related record +navigation_property|The Intelex system name of the relation type field - must be references associated relation type field + +## Object Workflow Data + +### Requesting Workflow Data + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "DateModified": "2016-07-14T14:32:05.44-04:00", + "DateCreated": "2016-04-25T12:54:18.563-04:00", + "DateNotRequired": null, + "DueDate": null, + "DueDateType": "string", + "EntityId": "string", + "EntityName": "", + "IsVirtual": false, + "LocationId": "string", + "ObjectId": "string", + "WorkflowStatus": "string" +} +``` + +This request allows you to retrieve the workflow information for a given record. + +#### GET /object/{intelex_object}({id})/Workflow + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Requesting Status + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/Status' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/Status"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "@odata.type": "string" + "@odata.id": "string", + "Id": "string", + "DateCreated": "2017-03-08T11:52:49.723-05:00", + "DateModified": "2017-03-08T11:52:49.723-05:00", + "Description": "Draft", + "DueDateExpression": null, + "DueDateLengthType": null, + "DueDateLengthValue": null, + "InheritedPermission": true, + "IsFirstStage": true, + "IsStandardPermission": true, + "Name": "Draft", + "RecipientExpression": null, + "RecipientType": "string", + "StageAction": null, + "StayInEditMode": false, + "SystemName": "Draft", + "TaskType": "Action" +} +``` + +This request allows you to retrieve the information about the workflow status that the record is currently in. + +#### GET /object/{intelex_object}({id})/Workflow/Status + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Requesting Current Stage + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/CurrentStage' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/CurrentStage"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "DateCreated": "2017-03-08T11:52:49.723-05:00", + "DateModified": "2017-03-08T11:52:49.723-05:00", + "Description": "Draft", + "DueDateExpression": null, + "DueDateLengthType": null, + "DueDateLengthValue": null, + "InheritedPermission": true, + "IsFirstStage": true, + "IsStandardPermission": true, + "Name": "Draft", + "RecipientExpression": null, + "RecipientType": "string", + "StageAction": null, + "StayInEditMode": false, + "SystemName": "Draft", + "TaskType": "Action" +} +``` + +This request allows you to retrieve the information about the workflow stage that the record is currently in. + +#### GET /object/{intelex_object}({id})/Workflow/CurrentStage + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Requesting Stage Actions + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/CurrentStage/Actions' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/CurrentStage/Actions"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "DateModified": "2017-03-08T11:52:49.927-05:00", + "DateCreated": "2017-03-08T11:52:49.927-05:00", + "Confirmation": "string", + "FlowDefinition": "string", + "IsHidden": false, + "MobileCaption": null, + "Name": "string", + "NavigateBackEnabled": true, + "Order": 1, + "RequireSignature": true, + "SystemName": "string", + "Tooltip": null, + "TriggerCondition": "", + "UrlIcon": "", + "UserActionsRequired": true + } + ] +} +``` + +This request allows you to retrieve the information about the workflow stage actions available for a record in the current stage. Note: When a workflow is published, the action IDs are created. If someone updates a workflow, they have to re-publish it for the changes to take effect, and all the action IDs change. Typically, you don't need to worry about this, but if your action IDs stop working, you should check them by running a dummy record through the workflow. + +#### GET /object/{intelex_object}({id})/Workflow/CurrentStage/Actions + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Requesting Person Responsible + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/PersonResponsible' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/PersonResponsible"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "@odata.type": "string" + "@odata.id": "string", + "Id": "string", + "DateCreated": "2010-06-20T20:00:00-04:00", + "DateModified": "2015-06-17T15:21:51.813-04:00", + "CustomField": null, + "IsSystem": false, + "Name": "string" +} +``` + +This request allows you to retrieve the individual assigned to the workflow stage of the record. **Workflow** and **PersonResponsible** are navigation properties that can be accessed using the $expand system query option as well. + +#### GET /object/{intelex_object}({id})/Workflow/PersonResponsible + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Requesting Frequency + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/RecurringSeries' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/RecurringSeries"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "@odata.type": "string" + "@odata.id": "string", + "Id": "string", + "DateCompleted": null, + "EndDate": "2017-07-07T03:30:00-04:00", + "EntityId": "string", + "Frequency": "RRULE:FREQ=HOURLY", + "GracePeriod": 0, + "IsActive": true, + "NextScheduledDate": "2017-06-06T04:30:00-04:00", + "OriginalStartDate": "2017-06-06T03:30:00-04:00", + "StartDate": "2017-06-06T03:30:00-04:00" +} +``` + +This request allows you to retrieve the workflow frequency applied to the record. The frequency property value is in iCal format. + +#### GET /object/{intelex_object}({id})/Workflow/RecurringSeries + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Executing a Stage Action + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/CurrentStage/Actions(UID)/Action.ExecuteStageAction' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow/CurrentStage/Actions(UID)/Action.ExecuteStageAction"); +var request = new RestRequest(Method.POST); +IRestResponse response = client.Execute(request); +``` + +This request allows you to push a record through its workflow stages. Note: When a workflow is published, the action IDs are created. If someone updates a workflow, they have to re-publish it for the changes to take effect, and all the action IDs change. Typically, you don't need to worry about this, but if your action IDs stop working, you should check them by running a dummy record through the workflow. + +#### POST /object/{intelex_object}({id})/Workflow/CurrentStage/Actions(id)/Action.ExecuteStageAction + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record or action being accessed + +### Updating Frequency + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'PATCH', + url: 'https://intelex_url/api/v2/object/IncidentsObject%28UID%29/Workflow/RecurringSeries', + headers: { 'content-type': 'application/json' }, + body: + { Frequency: 'RRULE:FREQ=HOURLY', + StartDate: '2017-06-06T03:30:00-04:00' }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject%28UID%29/Workflow/RecurringSeries"); +var request = new RestRequest(Method.PATCH); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\n \"Frequency\": \"RRULE:FREQ=HOURLY\",\n \"StartDate\": \"2017-06-06T03:30:00-04:00\"\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +This request allows you to modify the workflow frequency for a given record. The Frequency property will only accept iCal formatted strings. + +#### PATCH /object/{intelex_object}({id})/Workflow/RecurringSeries + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record or action being accessed + +##### Body Parameters + +Parameter | Description +--------- | ----------- +Frequency | iCal formatted string representing the calendar frequency +StarDate | Date you want the frequency to begin +EndDate | Date you want the frequency to end + +### Updating Person Responsible + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'PATCH', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow', + headers: { 'content-type': 'application/json' }, + body: { 'PersonResponsible@odata.bind': 'https://intelex_url/api/v2/object/EmployeeObject(UID)' }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/Workflow"); +var request = new RestRequest(Method.PATCH); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\n\t\"PersonResponsible@odata.bind\": \"https://intelex_url/api/v2/object/EmployeeObject(UID)\"\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +This request allows you to modify the workflow person responsible for a given record. This is the method used to re-assign tasks for a given record. + +#### PATCH /object/{intelex_object}({id})/Workflow + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record or action being accessed + +##### Body Parameters + +Parameter | Description +--------- | ----------- +PersonResponsible@odata.bind | the @odata.id of the employee you want to assign as person responsible + +## Object Attachments + +There are two types of file attachments on records. Files can be attached to the Private Document Attachment grid on a record or to the File type field of an object. To access files in the Private Document Attachment grid use the system reserved property: ILX.Attachments. To access files in the File type field use the system name of the field. Document Control uses this file type field and an example is added below showing how to access the released and effective version of document control files. + +### Requesting Private Documents + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject%28UID%29/ILX.Attachments' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject%28UID%29/ILX.Attachments"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.id": "string", + "@odata.mediaContentType": "string", + "Id": "string", + "AttachmentName": "string", + "Bytes": 0, + "IsDraft": true, + "ObjectRecordId": "string", + "Uri": "string", + "Attachment@odata.mediaReadLink": "string" + } + ] +} +``` + +This request returns a list of all private document attachments belonging to a given record. ILX.Attachments is a system reserved property for working with private document attachments. Any object that has private document attachments enabled will be able to access this property and request the private documents that belong to a record. + + +#### GET /object/{intelex_object}({id})/ILX.Attachments + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +### Downloading Private Documents + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.Attachments(UID)', + headers: + { prefer: 'attachment=thumbnail', + accept: 'application/octet-stream' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject%28UID%29/ILX.Attachments(UID)"); +var request = new RestRequest(Method.GET); +request.AddHeader("prefer", "attachment=thumbnail"); +request.AddHeader("accept", "application/octet-stream"); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.id": "string", + "@odata.mediaContentType": "string", + "Id": "string", + "AttachmentName": "string", + "Bytes": 0, + "IsDraft": true, + "ObjectRecordId": "string", + "Uri": "string", + "Attachment@odata.mediaReadLink": "string" +} +``` + +By default, this request returns the metadata of a specific private document attachment. When you provide the Accept header value of octet-stream, then the file will be downloaded instead. If it is an image, you also have the ability to request it in a thumbnail size. + +#### GET /object/{intelex_object}({id})/ILX.Attachments({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record or document being accessed + +##### Header Parameters + +Parameter | Description | Example Value +--------- | ------------| ----------- +Accept|Provide the content type in order to download the file|application/octet-stream +Prefer|Used to request a thumbnail version of an image file|attachment=thumbnail + +### Downloading Document Control Files + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/DocDocumentEntity(UID)/CurrentRevision/File', + headers: + { accept: 'application/octet-stream' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/DocDocumentEntity%28UID%29/CurrentRevision/File"); +var request = new RestRequest(Method.GET); +request.AddHeader("accept", "application/octet-stream"); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "Id": "string", + "DateModified": "string", + "DateCreated": "string", + "Content@odata.mediaReadLink": "string", + "FileExtension": "string", + "Name": "string", + "Size": 0 +} +``` + +By default, this request returns the metadata of a released and effective document of a document control record. When you provide the Accept header value of octet-stream, then the file will be downloaded instead. Document Control files use the File field type. This field type is available on any object and can be accessed like any other navigation property to download files. The example below is specific to Document Control. + +#### GET /object/DocDocumentEntity({id})/CurrentRevision/File + +##### URL Parameters + +Parameter | Description +--------- | ----------- +id|The Intelex UID of the record being accessed +PdfSecurity| The level of security for pdf. Values: None = 1 or Default = 0 + +##### Header Parameters + +Parameter | Description | Example Value +--------- | ------------| ----------- +Accept|Provide the content type in order to download the file|application/octet-stream + +### Attaching Private Documents + +> Example Request + +```javascript +var fs = require("fs"); +var request = require("request"); + +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.Attachments', + headers: { 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' }, + formData: + { '': + { value: 'fs.createReadStream("C:\\Document.docx")', + options: + { filename: 'C:\\Document.docx', + contentType: null } } } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.Attachments"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"); +request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"\"; filename=\"C:\\Document.docx\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.id": "string", + "@odata.mediaContentType": "string", + "Id": "string", + "AttachmentName": "string", + "Bytes": 0, + "IsDraft": true, + "ObjectRecordId": "string", + "Uri": "string", + "Attachment@odata.mediaReadLink": "string" +} +``` + +This request attaches a private document to a record. The file must be attached to the request as form-data. Files that exceed 10MB will not be attached. If the UID of the record does not exist, the file will be attached in draft mode. Once a record is created with the same record UID in the attach request, then the attachment will be associated to the record and will no longer be in draft mode. + +#### POST /object/{intelex_object}({id})/ILX.Attachments + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record being accessed + +##### Body Parameters + +Parameter | Type | Description +--------- | ----------- | --------- +multipart/formData | file | The file you want to attach to the record. Cannot exceed 10MB. + + +### Detaching Documents + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.Attachments(UID)' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.Attachments(UID)"); +var request = new RestRequest(Method.DELETE); +IRestResponse response = client.Execute(request); +``` + +This request deletes the specified document attached to a given record. ILX.Attachments is a system reserved property for working with private document attachments. Any object that has private document attachments enabled will be able to access this property and request the private documents that belong to a record. + +#### DELETE /object/{intelex_object}({id})/ILX.Attachments({id}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the record or document being accessed + +### Uploading Document Control Files +The first step for File type is to upload document. The file must be attached to the request as form-data. File size is configurable via web.config setting AttachmentMaxFileSize. There are two endpoints to upload file, difference is in the responses. + +> Example Request + +```javascript +var fs = require("fs"); +var request = require("request"); +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/FileUpload', + headers: { 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' }, + formData: + { '': + { value: 'fs.createReadStream("C:\\Document.docx")', + options: { filename: 'C:\\Document.docx', contentType: null } } + } +}; +request(options, function (error, response, body) { + if (error) throw new Error(error); + console.log(body); +}); +``` +> Example Response + +```javascript +[ "47df4cec-50ad-4da5-a820-7827985a77bb" ] +``` + +#### Endpoint 1 +This will return UID for the newly created file. The UID then can be attached to a record. +##### POST /FileUpload + +##### Header Parameters +Parameter | Description | Value +--------- | ----------- | ----- +content-type | The multipart/form-data content type is intended to allow information providers to express file upload requests uniformly, and to provide a MIME-compatible representation for file upload responses. | multipart/form-data + +##### Returns + +201 Created with Array of File UID + +











+> Example Request + +```javascript +var fs = require("fs"); +var request = require("request"); +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/object/SysFileInfoEntity', + headers: { 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' }, + formData: + { '': + { value: 'fs.createReadStream("C:\\Document.docx")', + options: { filename: 'C:\\Document.docx', contentType: null } } + } +}; +request(options, function (error, response, body) { + if (error) throw new Error(error); + console.log(body); +}); +``` +> Example Response: + +```json +{ + "@odata.context": “string”, + "@odata.type": "#Intelex.SysFileInfoEntity", + "@odata.id": “string”, + "@odata.editLink": "string", + "Id": "string", + "DateModified": "string", + "DateCreated": "string", + "Content@odata.mediaReadLink": "string", + "FileExtension": "string", + "Name": "string: filename", + "Size": number +} +``` +#### Endpoint 2 +This will return Edm for the newly created file. The @data.id link then can be used to attached to a record. + +##### POST /object/SysFileInfoEntity +##### Header Parameters +Parameter | Description | Value +--------- | ----------- | ----- +content-type | The multipart/form-data content type is intended to allow information providers to express file upload requests uniformly, and to provide a MIME-compatible representation for file upload responses. | multipart/form-data + +##### Returns +201 Created with newly created SysFileInfoEntity + +### Attaching Document Control Files +Once you have @odata.id of FileInfo, you can use that to attach to an object with File field. It is similar to [Modifying Object Data](#modifying-object-data) +> Example Request + +``` +{ + .... + "FileInput@odata.bind": "http://torwdtahmed02.intelex.com/devlogin/inspections/api/v2/object/SysFileInfoEntity(47df4cec-50ad-4da5-a820-7827985a77bb)" +} +``` +##### POST /object/{intelex_object} + +##### Request Parameters +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject + +##### Request Body +If intelex object has field FileInput (of type File), then Post body should contain this to attach file + +"FileInput@odata.bind": @odata.id from file upload response" + + + +### Detaching Document Control File +It is same as detaching a reference field in [Modifying Object Data](#modifying-object-data). +There is Intelex service that periodically cleans orphan files. +## Object Merge Templates + +Object merge templates allow you to extract data from any Intelex object and export it into a Microsoft Word® or PDF document, depending on the configuration of the merge template. By mapping 'MergeFields' in the Word document to data fields in a particular Intelex object, you are able to export dynamically generated files populated with object record data you need, such as employee names, hire dates, etc. You can use dot notations to drill down to child objects and populate their data. + +Intelex objects with the merge template option enabled, and at least one uploaded Merge Template, can be queried in one of two ways. + +- Retrieve a list of records detailing all Merge Templates for that object. +- Request a merge document content for a specific object record. + +To access Merge Template details use the system reserved property: ILX.MailMergeDocs. + +### Requesting Merge Templates + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.MailMergeDocs' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.MailMergeDocs"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.context": "string", + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "DateCreated": "2020-06-08T12:32:51.28-04:00", + "DateModified": "2020-06-08T12:32:51.28-04:00", + "Description": "string", + "DownloadAs": "string", + "ObjectRecordId": "string", + "TemplateName": "string" + } + ] +} +``` + +This request returns a list of all merge templates belonging to a given object. ILX.MailMergeDocs is a system reserved property for working with merge templates. Any object that has merge templates enabled will be able to access this property and request the templates that belong to the object. + + +#### GET /object/{intelex_object}({id})/ILX.MailMergeDocs + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id|The Intelex UID of the object record being accessed + + +### Downloading Merge Documents + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.MailMergeDocs(UID)', + headers: + { accept: 'application/octet-stream' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/object/IncidentsObject(UID)/ILX.MailMergeDocs(UID)"); +var request = new RestRequest(Method.GET); +request.AddHeader("accept", "application/octet-stream"); +IRestResponse response = client.Execute(request); +``` + +> Example Response - including the 'accept' header parameter, the response will be the binary contents of the dynamically generated document file. + +By including the 'accept' header parameter, the response will be the binary contents of the dynamically generated document file. + +``` +PK �Y�P����.customXml/item1.xml�ZYo�8~_` ... +``` + +> Example Response - without the 'accept' header, the response will be the metadata for the requested merge template record. + +Without the 'accept' header, the response will be the metadata for the requested merge template record. + +```json +{ + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "DateCreated": "2020-06-08T12:32:51.28-04:00", + "DateModified": "2020-06-15T11:02:24.28-04:00", + "Description": "string", + "DownloadAs": "string", + "ObjectRecordId": "string", + "TemplateName": "string" +} +``` + +By default, this request returns the metadata of a specific Merge Template document. When you provide the Accept header value of 'application/octet-stream', then the binary contents of merged file itself will be returned instead. + +#### GET /object/{intelex_object}({id1})/ILX.MailMergeDocs({id2}) + +##### URL Parameters + +Parameter | Description +--------- | ----------- +intelex_object | The Intelex system name of the object eg. IncidentsObject +id1|The Intelex UID of the record being accessed +id2|The Intelex UID of the merge template to return + +##### Header Parameters + +Parameter | Description | Example Value +--------- | ------------| ----------- +Accept|Provide the content type in order to download the file|application/octet-stream + + +## Object Batch Requests + +> Example Batch Request Body: The following example includes a batch with a unique identifier of AAA123 and a change set with a unique identifier of BBB456. The request creates a record then updates the record that was just created + +``` +--batch_AAA123 +Content-type: multipart/mixed; boundary=changeset_BBB456 + +--changeset_BBB456 +Content-Type: application/http +Content-Transfer-Encoding: binary +Content-ID:1 + +POST IncidentsObject HTTP/1.1 +Content-Type: application/json + + { "ActionsTaken": "string", "Date": "string", "Description": "string", "IncidentNo": 0, "ReportedDate": "2017-02-13T22:15:30.203Z", "SuspectedCause": "string" } + +--changeset_BBB456 +Content-Type: application/http +Content-Transfer-Encoding: binary +Content-ID:2 + +PATCH $1 HTTP/1.1 +Content-Type: application/json + +{"Description":"string"} + +--changeset_BBB456-- + +--batch_AAA123-- +``` + +> The above batch request returns the following response with a 200 OK status: + +``` +--batchresponse_20a3a5a7-2df7-435e-9c62-ead3472499e7 +Content-Type: multipart/mixed; boundary=changesetresponse_18666d72-dd34-46dc-8cae-2f0ff8208f7c + +--changesetresponse_18666d72-dd34-46dc-8cae-2f0ff8208f7c +Content-Type: application/http +Content-Transfer-Encoding: binary +Content-ID: 1 + +HTTP/1.1 201 Created +Location: https://intelex_url/api/v2/object/IncidentsObject(UID) +Content-Type: application/json; odata.metadata=minimal +OData-Version: 4.0 + +{ + "@odata.type": "string", "@odata.id": "string", "@odata.editLink": "string", "Id": "string", "ActionsTaken": "string", "Date": "2017-02-13T22:15:30.203Z", "Description": "string", "IncidentNo": 0, + "ReportedDate": "2017-02-13T22:15:30.203Z", "SuspectedCause": "string" +} +--changesetresponse_18666d72-dd34-46dc-8cae-2f0ff8208f7c +Content-Type: application/http +Content-Transfer-Encoding: binary +Content-ID: 2 + +HTTP/1.1 204 No Content + + +--changesetresponse_18666d72-dd34-46dc-8cae-2f0ff8208f7c-- +--batchresponse_20a3a5a7-2df7-435e-9c62-ead3472499e7-- + +``` + + + +Use a POST request to submit a batch operation that contains multiple requests. A batch request can include GET, POST, PATCH, and DELETE requests as well as change sets. To use transactional capabilities of batch requests, only operations that will change data can be included within a change set. GET requests must not be included in the change set. + +The POST request containing the batch must have a Content-Type header with a value set to multipart/mixed with a boundary set to include the identifier of the batch using this pattern: + +` +--batch_ +` + +The unique identifier doesn't need to be a GUID, but should be unique. Each item within the batch must be preceded by the batch identifier with a Content-Type and Content-Transfer-Encoding header: + +` +--batch_AAA123 +` + +` +Content-Type: application/http +` + +` +Content-Transfer-Encoding:binary +` + +The end of the batch must contain a termination indicator: + +` +--batch_AAA123-- +` + +By default, processing batch requests will stop on the first error unless the **odata.continue-on-error** preference is specified in the Prefer header. Also, the responses returned are essentially text documents rather than objects that can easily be parsed into JSON. You'll need to parse the text in the response. + + +#### POST /object/$batch + + +##### Header Parameters + +Parameter | Description |Required | Example Value +--------- | ----------- |--------- | ----------- +Content-Type | Content type for entire batch request |Yes|multipart/mixed;boundary=batch_AAA123 +Prefer|Preference to continue if error is encountered|No|odata.continue-on-error + +##### Change Sets + +When multiple operations are contained in a change set, all the operations are considered atomic, which means that if any one of the operations fail, any completed operations will be rolled back. Like a batch requests, change sets must have a Content-Type header with a value set to multipart/mixed with a boundary set to include the identifier of the change set using this pattern: + +` +--changeset_ +` + +The unique identifier doesn't need to be a GUID, but should be unique. Each item within the change set must be preceded by the change set identifier with a Content-Type and Content-Transfer-Encoding header like the following: + + +` +--changeset_BBB456 +` + +` +Content-Type: application/http +` + +` +Content-Transfer-Encoding:binary +` + +Change sets can also include a Content-ID header with a unique value. This value, when prefixed with $, represents a variable that contains the URI for any entity created in that operation. For example, when you set the value of 1, you can refer to that entity using $1 later in your change set. + +The end of the change set must contain a termination indicator like the following: + +` +--changeset_BBB456--- +` + +##### Batch Limits + +The Batch service has its limits. The maximum number of operations or changesets that can be included in the body of a $batch request is 100. The maximum number of operations inside a changeset is 1000. The size of the payload for a $batch request cannot exceed 1MB. diff --git a/source/includes/_package-api.md b/source/includes/_package-api.md new file mode 100644 index 00000000000..b0cbcd084c9 --- /dev/null +++ b/source/includes/_package-api.md @@ -0,0 +1,123 @@ +# Package API + +## Installing Packages + +The following resources allow you to install and import Intelex packages + +### Install a Package + +> Example Request + +```javascript +var fs = require("fs"); +var request = require("request"); + +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/packages/install', + headers: { 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' }, + formData: + { '': + { value: 'fs.createReadStream("C:\\Package.ipack")', + options: + { filename: 'C:\\Package.ipack', + contentType: null } } } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/packages/install"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"); +request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"\"; filename=\"C:\\Package.ipack\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "PackageId": "string", + "Name": "string", + "Description": "string", + "PackageVersion": "string", + "BuildDate": "2017-06-26T10:09:37.19", + "DateInstalled": "2017-06-29T08:56:37.077", + "PlatformVersion": "string", + "Status": "string" +} +``` + +Installs an Intelex package. This request will only accept one of two body parameters. If you want to install and package that already has been imported, then provide the PackageId in your request. If you want to import and install a package, then provide the package file as multipart/formdata. Do not provide both parameters. + +#### POST /api/v2/packages/install + +##### Body Parameters + +Parameter | Description +--------- | --------- +PackageId | The ID of an existing package that has been imported +multipart/formData (file) | The Intelex ipack file you want to install + + +### Import a Package + +> Example Request + +```javascript +var fs = require("fs"); +var request = require("request"); + +var options = { method: 'POST', + url: 'https://intelex_url/api/v2/packages/import', + headers: { 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' }, + formData: + { '': + { value: 'fs.createReadStream("C:\\Package.ipack")', + options: + { filename: 'C:\\Package.ipack', + contentType: null } } } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/packages/import"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"); +request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"\"; filename=\"C:\\Package.ipack\"\r\nContent-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "PackageId": "string", + "Name": "string", + "Description": "string", + "PackageVersion": "string", + "BuildDate": "2017-06-26T10:09:37.19", + "DateInstalled": "2017-06-29T08:56:37.077", + "PlatformVersion": "string", + "Status": "string" +} +``` + +Imports an Intelex package + +#### POST /api/v2/packages/import + +##### Body Parameters + +Parameter | Description +--------- | --------- +multipart/formData (file) | The Intelex ipack file you want to import \ No newline at end of file diff --git a/source/includes/_system-api b/source/includes/_system-api new file mode 100644 index 00000000000..7120bbe2cb7 --- /dev/null +++ b/source/includes/_system-api @@ -0,0 +1,100 @@ +# Task API - In Beta + +The Task API gives you the ability to retrieve your Intelex tasks. These tasks can be found in the My Tasks Summary application in your Intelex platform. Tasks are object data records that are assigned to an employee in the Intelex system. You can create tasks by [creating records](#create-a-record) and setting the workflow's person responsible or re-assign tasks by [updating a record's person responsible](#updating-person-responsible) + +The Task API is currently in beta. This means that we might make changes to the data returned or how requests are made with future Intelex releases. Once the beta tag is removed, breaking changes to this API will be [versioned](#versioning). + +## Metadata +> Example response with record metadata + +```json +{ + "value": { + "@odata.type": "#Intelex.IncidentsObject", + "@odata.id": "https://intelex_url/api/v2/object/IncidentsObject(UID)", + } +} +``` + +Records returned from the API will contain a few properties that provide some useful information. + +Property | Description +--------- | ----------- +@odata.type|The the entity type of the record. Also contains the object system name the record belongs to +@odata.id|A URL that can be used to access the record via the [Object Data API](#object-data-api) + +## Pagination +> Example response with pagination link + +```json +{ + "@odata.nextLink": "https://intelex_url/api/v2/task/mytasks?$skip=500" +} +``` + +We've provided a convenient way to access more data in any request for sequential data where the number of records exceeds 500. Simply call the url in the nextLink parameter and we'll respond with the next set of data. + +## Relational Data +Tasks resources have relations to Employees or Locations. These relations are accessible via the API as navigation properties. + +Each task resource will have navigation properties that can be used to access its related data in either the Employee or Location objects: + +Resource | Available Navigation Properties +--------- | ----------- +mytasks | Employee +stafftasks | Employee +locationtasks | Employee, Location +alltasks | Employee + +You can use these navigation properties in [$expand]() queries to return the related data in-line with your tasks. + +## Requesting Tasks + +The following resources are similar to the application abs you find in the My Tasks Summary application. You will only be able to access the following resources if you have the correct permissions set for the 'Use Application Tab' security setting on the associated application tab in Intelex. + +### Requesting Task Resources + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "name": "string", + "kind": "string", + "url": "string" + } + ] +} +``` + +Returns the task resource endpoints that you can access + +#### GET /api/v2/task + +Attribute | Description +--------- | ----------- +name | The entity type of the record. +kind | Entity set or function +url | Endpoint for resource \ No newline at end of file diff --git a/source/includes/_task-api.md b/source/includes/_task-api.md new file mode 100644 index 00000000000..f49ef1d906b --- /dev/null +++ b/source/includes/_task-api.md @@ -0,0 +1,909 @@ +# Task API + +The Task API gives you the ability to retrieve your Intelex tasks. These tasks can be found in the My Tasks Summary application in your Intelex platform. Tasks are object data records that are assigned to an employee in the Intelex system. You can create tasks by [creating records](#create-a-record) and setting the workflow's person responsible or re-assign tasks by [updating a record's person responsible](#updating-person-responsible) + +The Task API is currently in beta. This means that we might make changes to the data returned or how requests are made with future Intelex releases. Once the beta tag is removed, breaking changes to this API will be [versioned](#versioning). + +## Task Metadata +> Example response with record metadata + +```json +{ + "value": { + "@odata.type": "#Intelex.IncidentsObject", + "@odata.id": "https://intelex_url/api/v2/object/IncidentsObject(UID)", + } +} +``` + +Records returned from the API will contain a few properties that provide some useful information. + +Property | Description +--------- | ----------- +@odata.type|The the entity type of the record. Also contains the object system name the record belongs to +@odata.id|A URL that can be used to access the record via the [Object Data API](#object-data-api) + +## Task Record Limits +> Example response with pagination link + +```json +{ + "@odata.nextLink": "https://intelex_url/api/v2/task/mytasks?$skip=500" +} +``` + +We've provided a convenient way to access more data in any request for sequential data where the number of records exceeds 500. Simply call the url in the nextLink parameter and we'll respond with the next set of data. + +## Task Relational Data +Tasks resources have relations to Employees or Locations. These relations are accessible via the API as navigation properties. + +Each task resource will have navigation properties that can be used to access its related data in either the Employee or Location objects: + +Resource | Available Navigation Properties +--------- | ----------- +mytasks | Employee +stafftasks | Employee +locationtasks | Employee, Location +alltasks | Employee + +You can use these navigation properties in [$expand]() queries to return the related data in-line with your tasks. + +## Requesting Tasks + +The following resources are similar to the application tabs you find in the My Tasks Summary application. You will only be able to access the following resources if you have the correct permissions set for the 'Use Application Tab' security setting on the associated application tab in Intelex. + +### Requesting Task Resources + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "name": "string", + "kind": "string", + "url": "string" + } + ] +} +``` + +Returns the task resource endpoints that you can access + +#### GET /api/v2/task + +Attribute | Description +--------- | ----------- +name | The entity type of the record +kind | Entity set or function +url | Endpoint for resource + +### Requesting My Tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/mytasks' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/mytasks"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationId": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +Returns your tasks + +#### GET /api/v2/task/mytasks + +Attribute | Description +--------- | ----------- +Id | Task ID +RespEmployeeName | Person Responsible for Task +DueDateType | Overdue, Upcoming, None +LocationId | Location ID +LocationName | Location Name +NetObjectId | Object ID +NetObjectType | System name of object +NetTaskId | Object record ID +NextDate | Next assigned due date for task +RecordDescription | Task description +Stage | Workflow stage name +TaskType | Type of task +LegacyRecordId | Intelex v5 task ID +LegacyRecordIdName | Intelex v5 task name +LegacyRespEmployeeId | Intelex v5 employee ID +LegacyTaskId | Intelex v5 record ID +WebLink | Web URL to access task view + +### Requesting My Staff's Tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/stafftasks' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/stafftasks"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationId": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +Returns all tasks assigned to employees that the user is supervisor of + +#### GET /api/v2/task/stafftasks + +Attribute | Description +--------- | ----------- +Id | Task ID +RespEmployeeName | Person Responsible for Task +DueDateType | Overdue, Upcoming, None +LocationId | Location ID +LocationName | Location Name +NetObjectId | Object ID +NetObjectType | System name of object +NetTaskId | Object record ID +NextDate | Next assigned due date for task +RecordDescription | Task description +Stage | Workflow stage name +TaskType | Type of task +LegacyRecordId | Intelex v5 task ID +LegacyRecordIdName | Intelex v5 task name +LegacyRespEmployeeId | Intelex v5 employee ID +LegacyTaskId | Intelex v5 record ID +WebLink | Web URL to access task view + +### Requesting Location Tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/locationtasks' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/locationtasks"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +Returns all tasks for a location. Default location is the user's logon location set in their user profile. Tasks returned will belong to the default location and its child locations. + + +#### GET /api/v2/task/locationtasks + +Attribute | Description +--------- | ----------- +Id | Task ID +RespEmployeeName | Person Responsible for Task +DueDateType | Overdue, Upcoming, None +LocationName | Location Name +NetObjectId | Object ID +NetObjectType | System name of object +NetTaskId | Object record ID +NextDate | Next assigned due date for task +RecordDescription | Task description +Stage | Workflow stage name +TaskType | Type of task +LegacyRecordId | Intelex v5 task ID +LegacyRecordIdName | Intelex v5 task name +LegacyRespEmployeeId | Intelex v5 employee ID +LegacyTaskId | Intelex v5 record ID +WebLink | Web URL to access task view + +##### Header Parameters + +Parameter | Description +--------- | ----------- +ActiveLocation | Provide the ID of the location you want to use as the active location for your request. Records returned will belong to the active location and its child locations + + +### Requesting All Tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/alltasks' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/alltasks"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationId": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +Returns all tasks in Intelex + +#### GET /api/v2/task/alltasks + +Attribute | Description +--------- | ----------- +Id | Task ID +RespEmployeeName | Person Responsible for Task +DueDateType | Overdue, Upcoming, None +LocationId | Location ID +LocationName | Location Name +NetObjectId | Object ID +NetObjectType | System name of object +NetTaskId | Object record ID +NextDate | Next assigned due date for task +RecordDescription | Task description +Stage | Workflow stage name +TaskType | Type of task +LegacyRecordId | Intelex v5 task ID +LegacyRecordIdName | Intelex v5 task name +LegacyRespEmployeeId | Intelex v5 employee ID +LegacyTaskId | Intelex v5 record ID +WebLink | Web URL to access task view + +### Requesting Task Types + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/types' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/types"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "Caption": "string", + "Name": "string", + "Description", + "Module": { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "Caption": "string", + "UrlCaption": "string", + "Description": "string" + } + } + ] +} +``` + +Returns types of tasks you can create. This data is used to determine which objects have 'quick task creation' enabled + +#### GET /api/v2/task/types + +Attribute | Description +--------- | ----------- +Id | Task type ID +Caption | System caption of object +Name | System name of object +Description | Description of object +Module.Captiom | System caption of application +Module.UrlCaptions | Navigation caption of application +Module.Description | Description of application + +## Querying Tasks + +You can use the following query options on any of the Task API resources + +### Selecting task fields + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/mytasks', + qs: { '$select': 'RecordDescription' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/mytasks?$select=RecordDescription"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "RecordDescription": "string" + } + ] +} +``` + +The $select system query option allows clients to request a limited set of fields for each task. + +#### GET /task/mytasks?$select={field_name} + +Option | Example Values +--------- | ----------- +Select a single field | $select=RecordDescription +Select mutliple fields | $select=RecordDescription, RespEmployeeName + +##### URL Parameters + +Parameter | Description +--------- | ----------- +field_name | Field name(s) to include in response + +### Counting task records + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/mytasks', + qs: { '$count': 'true' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/mytasks?$count=true"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "@odata.count": 1, + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +The $count system query option with a value of true specifies that the total count of items within a collection matching the request be returned along with the result. + +#### GET /task/mytasks?$count=true + +### Paginating tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/mytasks', + qs: { '$skip': '10', '$top': '5' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/mytasks?$skip=10&$top=5"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +The $top system query option requests the number of items in the queried collection to be included in the result. The $skip query option requests the number of items in the queried collection that are to be skipped and not included in the result. + +#### GET /task/mytasks?$top={top_n}&$skip={skip_n} + +##### Query Parameters +Parameter | Description +--------- | ----------- +top_n | Number of items to be included in the response +skip_n| Number of items to be skipped + +### Sorting tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/mytasks', + qs: { '$orderby': 'NextDate desc' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/mytasks?$orderby=NextDate desc"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + +The $orderby system query option allows clients to request tasks in either ascending order using 'asc' or descending order using 'desc'. Default is ascending. The request below sorts the collection by date in descending order. + +#### GET /task/mytasks?$orderby={field_name} + +Option | Example Values +-------- | -------- +Sort by descending|$orderby=NextDate desc +Sort by ascending|$orderby=NextDate asc +Sort by drop-down value |$orderby=RespEmployeeName +Sort by multiple fields|$orderby=NextDate, RecordDescription + +##### Query Parameters + +Parameter | Description +--------- | ----------- +field_name | Fields that you want to sort by + +### Filtering tasks + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/mytasks', + qs: { '$filter': 'RespEmployeeName eq \'Steve Rogers\'' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); + +``` + +```csharp +var client = new RestClient("https://cloud3.intelex.com/wabouchalha/api/v2/task/mytasks?%24filter=RespEmployeeName%20eq%20'Steve%20Rogers'"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string" + } + ] +} +``` + + +The $filter system query option allows clients to filter a collection of task. The expression specified with $filter is evaluated for each task in the collection, and only items where the expression evaluates to true are included in the response. There are built-in filter operators that can be used in order to retrieve the data you need + +#### GET /task/mytasks?$filter={filter_expression} + +##### Query Parameters + +Parameter | Description +--------- | ----------- +filter_expression | Filter expression used to query data + +##### Comparison Operators: +|Name|Description|Example Values| +|---|---|---| +|eq|Equal|DueDateType eq Enum.DueDateType'Overdue' +|ne|Not equal|RecordDescription ne null +|gt|Greater than|NextDate gt 2017-01-01 +|ge|Greater than or equal|NextDate ge 2017-01-01 +|lt|Less than|NextDate lt 2017-01-01 +|le|Less than or equal|NextDate le 2014-11-24T12:55:05.35-05:00 + +##### Logical Operators: +|Name|Description|Example Values| +|---|---|---| +|and|Logical and|RecordDescription ne null and RespEmployeeName eq 'Steve Rogers' +|or|Logical or|RecordDescription eq null or NextDate gt 2017-01-01 +|not|Logical not|not(contains(RecordDescription, 'accident')) + +##### Grouping Operators: +|Name|Description|Example Values| +|---|---|---| +|( )|Precedence grouping|RespEmployeeName eq 'Steve Rogers' and (contains(TaskType, 'Safety') or contains(RecordDescription, 'Safety')) + +##### Functions: +|Name|Description|Example Values| +|---|---|---| +|contains(Field, Value)|Sub-string search|contains(RecordDescription, 'accident')) + +##### Filtering using Relation Fields: +|Description|Example Values| +|---|---| +|Filtering by Employee name |Employee/Name eq 'Steve Rogers' +|Filtering by Location name|Location/Name eq 'Toronto' + +### Expanding related information + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://intelex_url/api/v2/task/locationtasks', + qs: { '$expand': 'Location' } }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/task/locationtasks?$expand=Location"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Example Response + +```json +{ + "value": [ + { + "@odata.type": "string", + "@odata.id": "string", + "Id": "string", + "RespEmployeeName": "string", + "DueDateType": "string", + "LocationName": "string", + "NetObjectId": "string", + "NetObjectType": "string", + "NetTaskId": "string", + "NextDate": "2017-06-25T04:00:00Z", + "RecordDescription": "string", + "Stage": "string", + "TaskType": "string", + "LegacyRecordId": "string", + "LegacyRecordIdname": "string", + "LegacyRespEmployeeId": "string", + "LegacyTaskId": "string", + "WebLink": "string", + "Location": { + "@odata.type": "string", + "@odata.id": "string", + "@odata.editLink": "string", + "Id": "string", + "DateCreated": "2015-01-28T16:24:19.63-05:00", + "DateModified": "2016-04-21T15:02:38.723-04:00", + "Address1": null, + "Address2": null, + "Area": null, + "BusinessUnits": null, + "City": null + } + } + ] +} +``` + +The $expand system query option specifies the related object records to be included in-line with requested tasks. The parameter accepts a comma-separated list of relation field names. Use the system name of the relation type field or lookup type field in your query. + +#### GET /task/mytasks?$expand={relation_field} + +|Option|Example Values| +| -------- | -------- | +|Expand Employee|$expand=Employee| +|Expand Employee and Location|$expand=Employee, Location| +|Expand all relations|$expand=*| +|Select expanded fields|$expand=Location($select=Name)| +|Sort expanded collection|$expand=Location($orderby=Name)| + +##### Query Parameters + +Parameter | Description +--------- | ----------- +relation_field | Relation field used to request related object data \ No newline at end of file diff --git a/source/includes/_user-mgmt-api.md b/source/includes/_user-mgmt-api.md new file mode 100644 index 00000000000..901faaa7b07 --- /dev/null +++ b/source/includes/_user-mgmt-api.md @@ -0,0 +1,7 @@ +# User Management API + +The User Management API provides the ability to externally manage employee and user acccess in Intelex. + +Functionality for this endpoint includes employee and user [creation](#add-data) and [modification](#modify-data) with the ability to archive employees and revoke user access. Requests may also optionally [assign and revoke group membership](#group-membership) to the employee. + +Requires Platform Version 6.6.16 or higher \ No newline at end of file diff --git a/source/includes/acts/delete_api.md b/source/includes/acts/delete_api.md new file mode 100644 index 00000000000..1de0c0df653 --- /dev/null +++ b/source/includes/acts/delete_api.md @@ -0,0 +1,472 @@ +## Remove or Delete data from Database Table + +This section outlines the available Delete APIs designed for modifying ACTS data by deleteing or removing the data. These APIs offer options for removing existing records from the mentioned tables. + +* To remove the existing records, use the primary key of the record. + +As per the current release, DELETE APIs End points are provided to delete from the following tables: + +* Analysis +* Analysis Compound +* Emission Factor +* Equipment Analysis +* Operation +* Regulation +* Requirement +* Requirement Limit + +DELETE requests to these endpoints should be formatted in JSON. + +### 1. Analysis Table + +This section guides you through the process of removing/deleting the existing records from the Analysis table using the designated API endpoint. + +**Analysis DELETE endpoint** + +`DELETE` /actsapi/v1/analysis + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/analysis', + headers: { 'content-type': 'application/json' }, + body: + { + [analysisId1, analysisId2, analysisId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp + +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/analysis"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [operationId1, operationId2, operationId3....] \r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` +> Input JSON Body + +```json + + { + [analysisId1, analysisId2, analysisId3....] + } + +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} + +``` + +### 2. Analysis Compound Table + +This section guides you through the process of removing/deleting the existing records from the Analysis Compound table using the designated API endpoint. + +**Analysis Compound DELETE endpoint** + +`DELETE` /actsapi/v1/analysiscompound + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/analysiscompound', + headers: { 'content-type': 'application/json' }, + body: + { + [analysisCompoundId1, analysisCompoundId2, analysisCompoundId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp + +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/analysiscompound"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [analysisCompoundId1, analysisCompoundId2, analysisCompoundId3....] \r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` +> Input JSON Body + +```json + + { + [analysisCompoundId1, analysisCompoundId2, analysisCompoundId3....] + } + +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} + +``` + + +### 3. Emission Factor Table + +This section guides you through the process of removing/deleting the existing records from the Emission Factor table using the designated API endpoint. + +**Emission Factor DELETE endpoint** + +`DELETE` /actsapi/v1/emissionfactor + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/emissionfactor', + headers: { 'content-type': 'application/json' }, + body: + { + "emissionFactorId": "number" + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp + +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/emissionfactor"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"emissionFactorId\": \"number\"\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` +> Input JSON Body + +```json + + { + "emissionFactorId": "number" + } + +``` +> Example Response + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 0 , + "deletedRowCount" : 1 , + "failureCount" : 0 , + "errorMessage" : [] +} + +``` + +### 4. Equipment Analysis Table + +This section guides you through the process of removing/deleting the existing records from the Equipment Analysis table using the designated API endpoint. + +**Equipment Analysis DELETE endpoint** + +`DELETE` /actsapi/v1/equipmentanalysis + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentanalysis', + headers: { 'content-type': 'application/json' }, + body: + { + [equipmentanalysisId1, equipmentanalysisId2, equipmentanalysisId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp + +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentanalysis"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [equipmentanalysisId1, equipmentanalysisId2, equipmentanalysisId3....] \r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` +> Input JSON Body + +```json + + { + [equipmentanalysisId1, equipmentanalysisId2, equipmentanalysisId3....] + } + +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} + +``` + +### 5. Operation Table + +This section guides you through the process of removing/deleting the existing records from the Operation table using the designated API endpoint. + +**Operation DELETE endpoint** + +`DELETE` /actsapi/v1/operation + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/operation', + headers: { 'content-type': 'application/json' }, + body: + { [operationId1, operationId2, operationId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp + +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/operation"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [operationId1, operationId2, operationId3....]\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json + + { + [operationId1, operationId2, operationId3....] + } + +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} + +``` + +### 6. Regulation Table + +This section guides you through the process of removing/deleting the existing records from the Regulation table using the designated API endpoint. + +**Regulation DELETE endpoint** + +`DELETE` /actsapi/v1/regulation + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/regulation', + headers: { 'content-type': 'application/json' }, + body: + { [regulationId1, regulationId2, regulationId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/regulation"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [regulationId1, regulationId2, regulationId3....]\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json + { + [regulationId1, regulationId2, regulationId3....] + } +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} +``` + +### 7. Requirement Table + +This section guides you through the process of removing/deleting the existing records from the Requirement table using the designated API endpoint. + +**Requirement DELETE endpoint** + +`DELETE` /actsapi/v1/requirement + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/requirement', + headers: { 'content-type': 'application/json' }, + body: + { [requirementId1, requirementId2, requirementId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/requirement"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [requirementId1, requirementId2, requirementId3....]\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json + { + [requirementId1, requirementId2, requirementId3....] + } +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} +``` + +### 8. Requirement Limit Table + +This section guides you through the process of removing/deleting the existing records from the Requirement Limit table using the designated API endpoint. + +**Requirement Limit DELETE endpoint** + +`DELETE` /actsapi/v1/requirementlimit + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'DELETE', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/requirementlimit', + headers: { 'content-type': 'application/json' }, + body: + { [requirementLimitId1, requirementLimitId2, requirementLimitId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/requirementlimit"); +var request = new RestRequest(Method.DELETE); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [requirementLimitId1, requirementLimitId2, requirementLimitId3....]\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json + { + [requirementLimitId1, requirementLimitId2, requirementLimitId3....] + } +``` +> Example Response + +```json +{ + "deletedRowCount": 1, + "notFoundCount": 0, + "failureCount": 0, + "errorMessage" : [] +} +``` \ No newline at end of file diff --git a/source/includes/acts/get_api.md b/source/includes/acts/get_api.md new file mode 100644 index 00000000000..5a7b492b30e --- /dev/null +++ b/source/includes/acts/get_api.md @@ -0,0 +1,2244 @@ +## Retrieve Data + +This section outlines the various GET APIs available for fetching data from different tables. Each API provides the capability to retrieve specific data based on provided parameters. Pagination support is available for managing large datasets effectively.The user can pass the set of parameters of same or different filter options at once. + +As per the current release, GET APIs End points are provided to fetch from the following tables: + +* Attribute Type +* Compound +* Emission +* Emission Category +* Emission Factor +* Emission Type +* Equipment +* Equipment Attribute +* Equipment Status +* Equipment Type +* Facility +* Facility Attribute +* Operation +* Operation Type +* Query +* Regulation +* Regulation Type +* Requirement +* Requirement Limit +* Unit +* Workflow +* Workflow Answer +* Workflow Equipment +* Workflow Facility +* Workflow Person +* Workflow Question +* Workflow Question Category +* Workflow Type + +### 1. Attribute Type Table + +This section outlines the process of retrieving data from the Attribute Type table using the dedicated API endpoint. The endpoint facilitates the retrieval of all data from the Attribute Type table or enables the selection of specific information by including Attribute Ids and Attribute Types. Additionally, the Attribute Type endpoint supports pagination to effectively manage larger datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/attributetype' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/attributetype"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "attributeTypeId": "number", + "attributeType": "string", + "dataTypeId": "number", + "dataTypeSize": "number", + "dataTypePrecision": "number", + "dataTypeFilter": "string", + "readonlyInd": "string", + "searchableInd": "string", + "remoteInd": "string", + "defaultValue": "string", + "alwaysEvaluateDefaultInd": "string", + "displayCondition": "string", + "disabledCondition": "string", + "validationCondition": "string", + "validationErrorText": "string", + "viewColumnName": "string", + "activeDate": "2011-01-01T00:00:00", + "inactiveDate": "2011-01-01T00:00:00", + "lastModifiedDate": "2020-10-08T13:35:31", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/attributetype + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +attributeTypeIds | int | Attribute ID is one of the filter parameter is a integer data type +attributeTypes | string | Attribute Types is for the project detail type + +### 2. Compound Table + +This section guides you through the process of fetching data from the Compound table using the dedicated API endpoint. The endpoint offers the flexibility to retrieve all data from the Compound table or selectively acquire information by including Compound Ids, Compound Type Ids, Compound Status Ids, Compound Names, External Identifiers, or CAS Numbers. Additionally, the Compound endpoint is equipped with pagination capabilities to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/compound' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/compound"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "compoundId": "number", + "compoundName": "string", + "compoundTypeId": "number", + "compoundStatusId": "number", + "activeDate": "2011-07-04T17:42:43", + "description": "string", + "alternateNames": "string", + "cas": "string", + "formula": "string", + "molecularWeight": "number", + "vpMolecularWeight": "number", + "vp40": "number", + "vp50": "number", + "vp60": "number", + "vp70": "number", + "vp80": "number", + "vp90": "number", + "vp100": "number", + "vpCoefA": "number", + "vpCoefB": "number", + "vpCoefC": "number", + "vp2A": "number", + "vp2B": "number", + "reid": "number", + "astmSlope": "number", + "vpA": "number", + "vpB": "number", + "vpXMin": "number", + "vpXMax": "number", + "density": "number", + "specificGravity": "number", + "supplier": "string", + "manufacturerId": "number", + "epaTanksCategory": "string", + "epaTanksId": "number", + "inactiveDate": "string", + "sortOrder": "number", + "lastModifiedDate": "2020-09-10T10:01:19", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/compound + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +compoundIds | int | Compound ID is one of the unique identifier for this compound record +compoundTypeIds | int | Compound Type Ids is the associated compound type and is a second filter parameter option +compoundstatusIds | int | Compound Status Ids is associated with compound status +compoundNames | string | Compound Names The name of the compound which is a string type data and is one among the parameter for filter option +externalIdentifier | int | External Identifiers is a unique identifier for this record to an external data system +cas | string | CAS Number is a Chemical Abstract Service number for the compound + +### 3. Emission Table + +This section elaborates on how to obtain data from the Emission table using the designated API endpoint. The endpoint allows you to retrieve all data from the Emission table or selectively acquire information by providing the Emission ID. Moreover, the Emission endpoint features pagination to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET' + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/emission' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/emission"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "activeDate": "2025-10-21T08:37:41.669Z", + "inactiveDate": "2025-10-21T08:37:41.669Z", + "lastModifiedDate": "2025-10-21T08:37:41.669Z", + "externalIdentifier": "string", + "comments": "string", + "emissionId": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "compoundId": "number", + "unitId": "number", + "emissionAmount": "number", + "controlledInd": "string", + "estimatedInd": "string", + "limitEmissionAmount": "number", + "limitUnitId": "number", + "calculationId": "number", + "calculation": "string", + "limitCalculationId": "number", + "limitCalculation": "string", + "dataLockTypeId": "number", + "badDataFlag": "boolean" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/emission + +**Query parameters** + +Attribute| Type | Description +-------- | ---- |------------ +PageNumber| int | Page number of the results to fetch. +PageSize| int | The number of results per page +emissionIds| int | Emission ID is one of the unique identifier for this emission record +emissionTypeIds| int | The unique identifier of the associated emission type +emissionCategoryIds| int | The unique identifier of the associated emission category +equipmentIds| int | The unique identifier of the associated equipment +unitIds| int | The unique identifier of the associated unit +compoundIds| int | The unique identifier of the associated compound +calculationIds| int | The unique identifier of the associated calculation +estimatedInd| string | Estimated Ind can be of value 'Y' or 'N' +badDataFlag| boolean | Bad Data flag can be of value true or false +externalIdentifier| string | External Identifier is a unique identifier for this record to an external data system +lastModifiedStartDate| datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate| datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeStartDate| datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeEndDate| datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveStartDate| datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveEndDate| datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + +### 4. Emission Category Table + +This section elaborates on how to obtain data from the Emission Category table using the designated API endpoint. The endpoint allows you to retrieve all data from the Emission Category table or selectively acquire information by providing the Emission Category ID. Moreover, the Emission Category endpoint features pagination to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/emissioncategory' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/emissioncategory"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "emissionCategoryId": "number", + "emissionCategory": "string", + "sortOrder": "number", + "lastModifiedDate": "2022-11-22T08:03:51", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/emissioncategory + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +emissionCategoryIds | int | Emission Category ID is one of the unique identifier for this emission category record and is one of the filter option provided for Emission Category +emissionCategoryTypes | string | Emission Category Types is for the project to emission category detail types + +### 5. Emission Factor Table + +This section elaborates on how to obtain data from the Emission Factor table using the designated API endpoint. The endpoint allows you to retrieve all data from the Emission Factor table or You can optionally fetch specific data by including the emission factor Ids, emission factor names, emission type Ids, emission category Ids, unit Ids, compound Ids, equipment Ids, last modified start date and last modified end date. The Emission Factor endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/emissionfactor' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/emissionfactor"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 10, + "maxAPIPageSize": 500, + "totalCount": 1, + "hasPrevious": false, + "hasNext": false, + "data": [ + { + "emissionFactorId": "number", + "emissionFactor": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "compoundId": "number", + "emissionFactorName": "string", + "unitId": "number", + "lastModifiedDate": "2018-08-22T15:33:44", + "externalIdentifier": "string", + "comments": "string", + "activeDate": "2014-01-01T00:00:00", + "inactiveDate": "2014-01-01T00:00:00", + "primaryInd": "string", + "reportableInd": "string", + "readOnlyInd": "string", + "dataLockTypeId": "number" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/emissionfactor + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +emissionFactorIDs | int | Emission Factor Ids are unique identifier for this Emission Factor record +emissionFactorNames | string | Emission Factor Names are one of the filter option and the parameter is for the names of the Emission Factors +emissionTypeIds | int | The unique identifier of the associated emission type +emissionCategoryIds | int | The unique identifier of the associated emission category +unitIds | int | The unique identifier of the associated unit +compoundIds | int | Compound ID is one of the unique identifier for this compound record +equipmentIds | int | The unique identifier of the associated equipment +lastModifiedStartDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + +### 6. Emission Type Table + +This section guides you through the process of fetching data from the Emission Type table using the dedicated API endpoint. The endpoint enables you to retrieve data from the entire Emission Type table or selectively obtain information by including Emission Type Ids. Additionally, the Emission Type endpoint is equipped with pagination capabilities to facilitate the handling of extensive datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/emissiontype' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/emissiontype"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "emissionTypeId": "number", + "emissionType": "string", + "sortOrder": "number", + "lastModifiedDate": "2022-11-22T08:03:41", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/emissiontype + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +emissionTypeIds | int | Emission Type ID is one of the type of emissions and is the one of the filter option provided for Emission Type +emissionTypes | string | Emission Types is for the project to emission detail types + + +### 7. Equipment Table + +This section provides guidance on retrieving data from the Equipment table using the designated API endpoint. The endpoint allows you to retrieve all data from the Equipment table or specify specific data based on equipment Ids. Additionally, the Equipment endpoint offers pagination support to facilitate the handling of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipment' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipment"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "equipmentId": "number", + "areaId": "number", + "facilityId": "number", + "equipmentTypeId": "number", + "sourceName": "string", + "equipmentStatusId": "number", + "modelId": "number", + "ownershipId": "number", + "ownerId": "number", + "serialNumber": "string", + "manufactureDate": "2013-09-03T00:00:00", + "internalName": "string", + "alternateName": "string", + "design": "string", + "originalSurveyDate": "2022-12-12T15:43:07", + "activeDate": "2013-09-03T00:00:00", + "inactiveDate": "2022-12-12T15:43:07", + "dataLockTypeId": "number", + "lastModifiedDate": "2022-12-12T15:43:07", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/equipment + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +equipmentIds | int | Equipment ID is one of the unique identifier for this equipment record +equipmentTypeIds | int | Equipment Type ID is one of the unique identifier for this equipment type record +equipmentStatusIds | int | Equipment Status ID is one of the unique identifier for this equipment status record +facilityIds | int | Facility ID is one of the unique identifier for this equipment status record +sourceNames | string | Source Names is one of the unique identifier for this equipment record +internalNames | string | Internal Names is one of the unique identifier for this equipment record +alternateNames | string | Alternate Names is one of the unique identifier for this equipment record +lastModifiedStartDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +externalIdentifier | string | External Identifier a unique identifier for this record to an external data system + + +### 8. Equipment Attribute Table + +All data from the Equipment Attribute table will be returned from the endpoint below. You can optionally fetch specific data by including the facility attribute Ids, facility names, emission type Ids, facility type Ids, unit Ids, equipment Ids, last modified start date and last modified end date. The facility attribute endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentattribute' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentattribute"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "equipmentAttributeId": "number", + "equipmentId": "number", + "attributeTypeId": "number", + "equipmentAttribute":"string", + "dataLockTypeId": "number", + "lastModifiedDate": "datetime", + "externalIdentifier": "string", + "comments":"string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/equipmentattribute + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +equipmentAttributeIds | int | EquipmentAttributeId one of the unique identifier for this Equipment record. +equipmentIds | int | EquipmentId must be numeric. +attributetypeIds | int | AttributeTypeId must be numeric. +equipmentattributes | string | Equipment Attribute is one of the filter option and the parameter is for the Equipment Attribute Type +lastModifiedStartDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + + +### 9. Equipment Status Table + +All data from the Equipment Status table will be returned from the endpoint below. You can optionally fetch specific data by including the equipment status ID and equipment status value. The Equipment Status endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentstatus' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentstatus"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "equipmentStatusId": "number", + "equipmentStatus": "string", + "colorId": "number", + "sortOrder": "number", + "lastModifiedDate": "2022-11-22T07:46:46", + "externalIdentifier": "string", + "comments": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/equipmentstatus + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +equipmentStatusIds | int | Equipment Status ID is one of the unique identifier for this equipment status record +equipmentStatus | string | Equipment Status is one of the identifier for the status of the equipment + + + +### 10. Equipment Type Table + +All data from the Equipment Type table will be returned from the endpoint below. You can optionally fetch specific data by including the equipment type ID and equipment types value. The Equipment type endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipmenttype' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipmenttype"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "equipmentTypeId": "number", + "equipmentType": "string", + "visibleInd": "string", + "equipmentAttributesInd": "string", + "emissionCalculationsInd": "string", + "containmentInd": "string", + "geometryInd": "string", + "emissionFactorsInd": "string", + "sampleLocationsInd": "string", + "equipmentAssociationsInd": "string", + "facilityAssociationsInd": "string", + "locationInformationInd": "string", + "fuelUseInd": "string", + "peopleAssociationsInd": "string", + "serviceScheduleInd": "string", + "serviceHistoryInd": "string", + "operationalDataCollectnInd": "string", + "pteOperationalDataInd": "string", + "scheduleInd": "string", + "correspondenceInd": "string", + "requirementsInd": "string", + "fileAttachmentsInd": "string", + "viewName": "string", + "sortOrder": "number", + "lastModifiedDate": "2022-04-14T09:15:47", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/equipmenttype + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +equipmentTypeIds | int | Equipment Type ID is one of the unique identifier for this equipment type record +equipmentTypes | string | Equipment Types is one of the filter option and the parameter is for the type of the equipment + + +### 11. Facility Table + +All data from the Facility table will be returned from the endpoint below. You can optionally fetch specific data by including the facility Ids, facility names, emission type Ids, facility type Ids, facility status Ids, county Ids, last modified start date and last modified end date. The facility endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/facility' }; +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/facility"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "facilityId": "number", + "facilityName": "string", + "areaId": "number", + "facilityTypeId": "number", + "facilityStatusId": "number", + "sortOrder": "number", + "facilityOwnershipId": "number", + "facilityOwnerId": "number", + "landOwnershipId": "number", + "landOwnerId": "number", + "operatorId": "number", + "countryId": "number", + "countyId": "number", + "offshoreBlockId": "number", + "meteorologicalId": "number", + "businessEntityId": "number", + "businessUnitId": "number", + "alternateName": "string", + "purchaseDate": "2023-06-25T04:00:00Z", + "previousOwnerId": "number", + "soldDate": "2023-06-25T04:00:00Z", + "soldToId": "number", + "activeDate": "2023-06-25T04:00:00Z", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "lastModifiedDate": "2023-06-25T04:00:00Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/facility + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +facilityIds | int | Facility ID is one of the unique identifier for this Facility record +facilityTypeIds | int | Facility Type ID is one of the unique identifier for this Facility record +facilityStatusIds | int | Facility Status ID is one of the unique identifier for this Facility record +countyIds | int | County ID is one of the unique identifier for this Facility record +facilityNames | string | Facility Name is the unique identifier of the associated facility type +alternateNames | string | Alternate Name is the unique identifier of the associated facility +externalidentifier | string | External Identifier a unique identifier for this record to an external data system +areaIds | int | Area ID is one of the unique identifier for this Facility record to determine the region +lastModifiedStartDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + + +### 12. Facility Attribute Table + +All data from the Facility Attribute table will be returned from the endpoint below. You can optionally fetch specific data by including the facility attribute Ids, facility names, emission type Ids, facility type Ids, facility attribute and last modified end date. The facility attribute endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/facilityattribute' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/facilityattribute"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "facilityAttributeId": "number", + "facilityId": "number", + "attributeTypeId": "number", + "facilityAttribute":"string", + "dataLockTypeId": "number", + "lastModifiedDate": "2023-03-30T07:27:06.295Z", + "externalIdentifier": "string", + "comments":"string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/facilityattribute + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +facilityAttributeIds | int | Facility ID is one of the unique identifier for this Facility record +facilityIds | int | Facility Name is the unique identifier of the associated facility type +attributetypeIds | int | Attribute Type ID is the unique identifier of the associated attribute type +facilityattributes | string | Facility Attribute is one of the filter option and the parameter is for the Facility Attribute Type +datalocktypeIds | int | Data Lock Type ID the unique identifier of the associated data lock type +lastModifiedStartDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +externalidentifier | string | External Identifier a unique identifier for this record to an external data system +comments | string | Comments any comments associated with this record + + +### 13. Operation Table + +All data from the Operation table will be returned from the endpoint below. You can optionally fetch specific data by including the operation Ids, operation type Ids, emission type Ids, emission category Ids, unit Ids, equipment Ids, last modified start date and last modified end date. The Operation endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/operation' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/operation"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "operationId": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "operationTypeId": "number", + "activeDate": "2023-06-25T04:00:00Z", + "unitId": "number", + "controlledInd": "string 1 Byte Y or N", + "estimatedInd": "string 1 Byte Y or N", + "invalidInd": "string 1 Byte Y or N", + "calculateEmissionsInd": "string 1 Byte Y or N", + "collectionDate": "2023-06-25T04:00:00Z", + "fieldEventId": "number", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "lastModifiedDate": "2023-06-25T04:00:00Z", + "externalIdentifier": "string", + "comments": "string", + "badDataFlag": "number(0,1)", + "operationAmount": "number" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/operation + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +operationIds | int | Operation Ids are unique identifier for this operation type record +operationTypeIds | string | Operation Type Ids is one of the filter option and the parameter is for the type of the Operation Type +emissionTypeIds | int | The unique identifier of the associated emission type +emissionCategoryIds | int | The unique identifier of the associated emission category +unitIds | int | The unique identifier of the associated unit +equipmentIds | int | The unique identifier of the associated equipment +lastModifiedStartDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | string | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + + +### 14. Operation Type Table + +All data from the Operation Type table will be returned from the endpoint below. You can optionally fetch specific data by including the operation type ids, operation types . The Operation Type endpoint supports pagination. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/operationtype' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/operationtype"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "operationTypeId": "number", + "operationType": "string", + "parentOperationTypeId": "number", + "compoundId": "number", + "applicabilityFormula": "string", + "sortOrder": "number", + "lastModifiedDate": "2020-09-01T15:55:25", + "externalIdentifier": "number", + "comments": "number", + "refId": "number" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/operationtype + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +operationTypeIDs | int | The unique identifier for this operation type record +operationTypes | int | The type of operational data + +### 15. Query Results + +The QueryResults API end point will allow the user to run the views saved in Query view tables and returns the dynamic results based on the specific query view id value. The QueryResults endpoint supports pagination. +Request must contain exactly one single queryViewId as a query parameter. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/queryresults', + headers: { 'content-type': 'application/json' }, + body: + { + "queryViewId": "number" + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/queryresults"); +var request = new RestRequest(Method.GET); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"queryViewId\": \"number\"\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 51, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 25052, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "equipment_id": "number", + "area_id": "number", + "facility_id": "number", + "equipment_type_id": "number", + "source_name": "string", + "equipment_status_id": "number", + "model_id": "number", + "ownership_id": "number", + "owner_id": "number", + "serial_number": "string", + "manufacture_date": "2023-03-30T07:27:06", + "internal_name": "string", + "alternate_name": "string", + "design": "string", + "original_survey_date": "2023-03-30T07:27:06", + "active_date": "2018-10-16T06:19:21", + "inactive_date": "2023-03-30T07:27:06", + "data_lock_type_id": "number", + "last_modified_date": "2023-03-30T04:07:57", + "external_identifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/queryresults + +**Query parameters** + +Attribute | Type | Required | Description +--------- | ---- | -------- | ----------- +PageNumber | int | No | Page number of the results to fetch. +PageSize | int | No | The number of results per page +queryViewId | int | Yes | The unique identifier for this query view record + +### 16. Regulation Table +This section elaborates on how to obtain data from the Regulation table using the designated API endpoint. The endpoint allows you to retrieve all data from the Regulation table or selectively acquire information by providing the Regulation ID. Moreover, the Regulation endpoint features pagination to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET' + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/regulation' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/regulation"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "activeDate": "2025-10-21T09:49:43.867Z", + "inactiveDate": "2025-10-21T09:49:43.867Z", + "lastModifiedDate": "2025-10-21T09:49:43.867Z", + "externalIdentifier": "string", + "comments": "string", + "regulationId": "number", + "agencyId": "number", + "regulationTypeId": "number", + "mediaId": "number", + "regulationName": "string", + "regulationStatusId": "number", + "applicationDate": "2025-10-21T09:49:43.867Z", + "completeDate": "2025-10-21T09:49:43.867Z", + "publicNoticeDate": "2025-10-21T09:49:43.867Z", + "issueDate": "2025-10-21T09:49:43.867Z", + "renewalDate": "2025-10-21T09:49:43.867Z", + "expirationDate": "2025-10-21T09:49:43.867Z", + "description": "string", + "applicabilityCriteria": "string", + "sortOrder": "number" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/regulation + +**Query parameters** + +Attribute | Type | Description | +--------- |------|-------------| +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +regulationIds | int | Regulation ID is one of the unique identifier for this regulation record +regulationNames| string | Regulation Names are one of the filter option and the parameter is for the name of the regulations +regulationTypeIds | int | The unique identifier of the associated regulation type +regulationStatusIds | int | The unique identifier of the associated regulation status +agencyIds | int | The unique identifier of the associated agency +mediaIds | int | The unique identifier of the associated media +applicationStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +applicationEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +completeStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +completeEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +publicNoticeStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +publicNoticeEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +issueStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +issueEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +renewalStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +renewalEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +expirationStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +expirationEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +externalIdentifier| string | External Identifier is a unique identifier for this record to an external data system +lastModifiedStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + + +### 17. Regulation Type Table +This section elaborates on how to obtain data from the Regulation Type table using the designated API endpoint. The endpoint allows you to retrieve all data from the Regulation Type table or selectively acquire information by providing the Regulation Type ID. Moreover, the Regulation Type endpoint features pagination to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET' + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/regulationType' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/regulationType"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "regulationTypeId": "number", + "regulationType": "string", + "regulationAttributesInd": "string", + "regulationTermInd": "string", + "requirementsInd": "string", + "requirementLimitsInd": "string", + "areaAssociationsInd": "string", + "facilityAssociationsInd": "string", + "facilityRequirementsInd": "string", + "equipmentAssociationsInd": "string", + "projectAssociationsInd": "string", + "regulationTaskAssigneesInd": "string", + "requirementTaskAssigneesInd": "string", + "areaTaskAssigneesInd": "string", + "facilityTaskAssigneesInd": "string", + "requirementEquipTaskAsnInd": "string", + "ownershipInterestInd": "string", + "correspondenceInd": "string", + "fileAttachmentsInd": "string", + "sortOrder": "number", + "lastModifiedDate": "2025-10-21T10:39:13.942Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/regulationType + +**Query parameters** + +Attribute | Type | Description | +--------- |------|-------------| +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +regulationTypeIds | int | Regulation Type ID is one of the unique identifier for this regulation type record +regulationTypes | string | Regulation Types is one of the filter option and the parameter is for the type of the regulation +externalIdentifier| string | External Identifier is a unique identifier for this record to an external data system +lastModifiedStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + +### 18. Requirement Table +This section elaborates on how to obtain data from the Requirement table using the designated API endpoint. The endpoint allows you to retrieve all data from the Requirement table or selectively acquire information by providing the Requirement ID. Moreover, the Requirement endpoint features pagination to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET' + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/requirement' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/requirement"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "requirementId": "number", + "regulationId": "number", + "requirementTypeId": "number", + "requirementName": "string", + "requirementFrequencyId": "number", + "requirementCategoryId": "number", + "regulationActivityId": "number", + "description": "string", + "associatedRequirements": "string", + "applicabilityCriteria": "string", + "sortOrder": "number", + "generateTaskInd": "string", + "taskText": "string", + "firstDueDate": "2025-10-21T10:58:41.085Z", + "generateFacilityTasksInd": "string", + "combineTasksInd": "string", + "attributeTypeId": "number", + "triggerOffset": "number", + "triggerOffsetType": "string", + "creationOffset": "number", + "dependentRequirementId": "number", + "conditionalFormula": "string", + "activeDate": "2025-10-21T10:58:41.085Z", + "inactiveDate": "2025-10-21T10:58:41.085Z", + "lastModifiedDate": "2025-10-21T10:58:41.085Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/requirement + +**Query parameters** + +Attribute | Type | Description | +--------- |------|-------------| +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +requirementIds | int | Requirement ID is one of the unique identifier for this requirement record +regulationIds | int | The unique identifier of the associated regulation +requirementTypeIds | int | The unique identifier of the associated requirement type +requirementNames | string | Requirement Names is one of the filter option and the parameter is for the name of the requirement +requirementCategoryIds | int | The unique identifier of the associated requirement category +regulationActivityIds | int | The unique identifier of the associated regulation activity +externalIdentifier| string | External Identifier is a unique identifier for this record to an external data system +lastModifiedStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + +### 19. Requirement Limit Table +This section elaborates on how to obtain data from the Requirement Limit table using the designated API endpoint. The endpoint allows you to retrieve all data from the Requirement Limit table or selectively acquire information by providing the Requirement Limit ID. Moreover, the Requirement Limit endpoint features pagination to facilitate efficient management of substantial datasets. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET' + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/requirementLimit' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/requirementLimit"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 3, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 1346, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "activeDate": "2025-10-21T11:09:26.877Z", + "inactiveDate": "2025-10-21T11:09:26.877Z", + "lastModifiedDate": "2025-10-21T11:09:26.877Z", + "externalIdentifier": "string", + "comments": "string", + "requirementLimitId": "number", + "requirementId": "number", + "requirementLimitTypeId": "number", + "compoundId": "number", + "compoundGroupTypeId": "number", + "unitId": "number", + "operator": "string", + "limitThreshold": "number", + "compareLimitInd": "string", + "compareDecimalPlaces": "number", + "compareOffset": "number", + "compareDays": "number", + "limitViolationText": "string", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "operationTypeId": "number", + "analysisTypeId": "number", + "analysisValueName": "string", + "customLimitThreshold": "string", + "sortOrder": "number" + } + ] +} +``` + +**API Endpoints** + +`GET` /actsapi/v1/requirementLimit + +**Query parameters** + +Attribute | Type | Description | +--------- |------|-------------| +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +requirementLimitIds | int | Requirement Limit ID is one of the unique identifier for this requirement limit record +requirementIds | int | The unique identifier of the associated requirement +requirementLimitTypeIds | int | The unique identifier of the associated requirement limit type +compoundIds | int | The unique identifier of the associated compound +compoundGroupTypeIds | int | The unique identifier of the associated compound group type +unitIds | int | The unique identifier of the associated unit +emissionTypeIds | int | The unique identifier of the associated emission type +emissionCategoryIds | int | The unique identifier of the associated emission category +operationTypeIds | int | The unique identifier of the associated operation type +analysisTypeIds | int | The unique identifier of the associated operation type +externalIdentifier| string | External Identifier is a unique identifier for this record to an external data system +lastModifiedStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +activeEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveStartDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +inactiveEndDate | datetime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + +### 20. Unit Table + +This section outlines how to retrieve data from the Unit table using the provided endpoint. You have the flexibility to fetch specific data by including unit Ids, unit type Ids, and units. The Unit type endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/unit' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/unit"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "unitId": "number", + "unit": "string", + "unitTypeId": 0, + "description": "string", + "alternateNames": "string", + "sortOrder": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/unit + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +unitIds | int | Unit ID is one of the unique identifier for this Unit record +unitTypeIds | int | Unit Type Ids is the unique identifier of the associated unit type +units | string | Units is one of the filter option and the parameter is for the Name of the Unit + +### 21. Workflow Table + +This section outlines how to retrieve data from the Workflow table using the provided endpoint. You have the flexibility to fetch specific data by including workflow Ids, workflow type Ids, workflow date for both start date and end date along with the last modified date. The workflow endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflow' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflow"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowId": "number", + "workflowTypeId": "number", + "workflowDate": "2017-02-13T22:15:30.203Z", + "dataLockTypeId": "1", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflow + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowIds | int | Workflow IDs are the unique identifier for workflows. +workflowTypeIds | int | Workflow Type IDs are the unique identifier for a workflow type. +workflowStartDate | dateTime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +workflowEndDate | dateTime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedStartDate | dateTime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | dateTime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +externalIdentifier | string | External Identifier a unique identifier for this record to an external data system + + +### 22. Workflow Answer Table + +This section outlines how to retrieve data from the Workflow Answer table using the provided endpoint. You have the flexibility to fetch specific data by including workflow Answer Ids, workflow Ids, workflow question Ids, category Answer Index, category Revision Index, question Answer Index, question Revision Index, workflow Answer, lastModifiedStartDate and lastModifiedEndDate. The Workflow Answer endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowanswer' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowanswer"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowAnswerId": "number", + "workflowId": "number", + "workflowQuestionId": "number", + "categoryAnswerIndex": "number", + "categoryRevisionIndex": "number", + "questionAnswerIndex": "number", + "questionRevisionIndex": "number", + "workflowAnswer": "2016-03-23", + "dataLockTypeId": "number", + "personId": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowanswer + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowAnswerIds | int | Workflow Answer IDs are the unique identifiers for the answers in the workflow. Answer IDs are associated with a unique Question ID. +workflowIds | int | Workflow IDs are the unique identifier for workflows (the named form or workflow type+date completed). +workflowQuestionIds | int | Workflow Question IDs are the unique identifiers for questions in the workflow. Question IDs are associated with a unique Workflow ID. +categoryAnswerIndex | int | Category Answer Index is the index for answers in the category. +categoryRevisionIndex | int | Category Revision Index is the list of category revisions. If the workflow itself is updated a new category revision ID is assigned. +questionAnswerIndex | int | Question Answer Index is the index for answers to a question. Answer IDs are associated with a unique Question ID. +questionRevisionIndex | int | Question Revision Index is the index for questions with revisions. If the question itself is updated a question revision ID is assigned. +workflowAnswer | string | Wokflow Answer is the answer to the question.. +lastModifiedStartDate | dateTime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" +lastModifiedEndDate | dateTime | Date time format "yyyy/mm/dd T hours:min:secZ - Ex : 2017-02-13T22:15:30Z" + +### 23. Workflow Equipment Table + +This section outlines how to retrieve data from the Workflow Equipment table using the provided endpoint. Equipment workflows are typically labeled Inspection. You have the flexibility to fetch specific data by including workflow Equipment Ids, workflow Ids, and Equipment Ids. The Workflow Equipment endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowEquipment' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowEquipment"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowEquipmentId": "number", + "workflowId": "number", + "equipmentId": "number", + "workflowQuestionId": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowEquipment + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowEquipmentIds | int | Workflow Equipment ID is the unique identifier for the associated equipment within the workflow. +workflowIds | int | Workflow Ids is the unique identifier of the associated workflow. +equipmentIds | string | Equipment IDs are the unique identifier of the associated equipment. + +### 24. Workflow Facility Table + +This section outlines how to retrieve data from the Workflow Facility table using the provided endpoint. Facility workflows are typically labeled Inspection. You have the flexibility to fetch specific data by including workflow Facility Ids, workflow Ids and facility Ids. The Workflow Facility endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowfacility' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowfacility"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowFacilityId": "number", + "workflowId": "number", + "facilityId": "number", + "workflowQuestionId": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowfacility + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowFacilityIds | int | Workflow Facility IDs are the unique identifier for the associated facility within the workflow. +workflowIds | int | Workflow IDs are the unique identifier for workflows (the named form or workflow type+date completed). +facilityIds | int | Facility IDs are the unique identifier for the associated facility. + + + +### 25. Workflow Person Table + +This section outlines how to retrieve data from the Workflow Person table using the provided endpoint. You have the flexibility to fetch specific data by including workflow person Ids, workflow Ids and person Ids. The Unit type endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowperson' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowperson"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowPersonId": "number", + "workflowId": "number", + "personId": "number", + "workflowQuestionId": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowperson + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowPersonIds | int | Workflow Person ID is the unique identifier for the associated person within the workflow. +workflowIds | int | Workflow IDs are the unique identifier for workflows (the named form or workflow type+date completed). +personIds | int | Person IDs are the assigned values for associated person(s) and can be used as a filter. + +### 26. Workflow Question Table + +This section outlines how to retrieve data from the Workflow Question table using the provided endpoint. You have the flexibility to fetch specific data by including workflow Question Ids, workflow question categoy Ids, data type Ids, required Inds and questions. The Workflow Question endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowquestion' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowquestion"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowQuestionId": "number", + "workflowQuestionCategoryId": "number", + "question": "string", + "dataTypeId": "number", + "dataTypeSize": "number", + "dataTypePrecision": "number", + "dataTypeFilter": "string", + "workflowAnswerListId": "number", + "workflowAnswerList": "string", + "defaultValue": "string", + "alwaysEvaluateDefaultInd": "string", + "displayInd": "string", + "displayCondition": "string", + "disabledInd": "string", + "disabledCondition": "string", + "requiredInd": "string", + "validationCondition": "string", + "validationErrorText": "string", + "repeatInd": "string", + "repeatDeleteInd": "string", + "repeatDeleteConfirmInd": "string", + "reviseInd": "string", + "associateEntityInd": "string", + "allowCopyInd": "string", + "workflowTypeId": "number", + "viewColumnName": "string", + "sensitiveDataInd": "string", + "xmlDescription": "string", + "sortOrder": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowquestion + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowQuestionIds | int | Workflow Question ID are the unique identifiers for the workflow question record. +workflowQuestionCategoryIds | int | Workflow Question Category Ids are the unique identifiers for the associated workflow question category. +dataTypeIds | int | Data Type IDs are the unique identifiers for the associated data type. +requiredInds | string | Required Inds is the value if an answer is required before saving the form. +questions | string | Questions are the question content values included on the form. + +### 27. Workflow Question Category Table + +This section outlines how to retrieve data from the Workflow Question Category table using the provided endpoint. You have the flexibility to fetch specific data by including workflow question category Ids, workflow type Ids and workflow question category. The Workflow Question Category endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowquestioncategory' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowquestioncategory"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowQuestionCategoryId": "number", + "workflowTypeId": "number", + "parentQuestionCategoryId": "number", + "workflowQuestionCategory": "string", + "autoExpandInd": "string", + "displayInd": "string", + "displayCondition": "string", + "disabledInd": "string", + "disabledCondition": "string", + "repeatInd": "string", + "repeatDeleteInd": "string", + "repeatDeleteConfirmInd": "string", + "reviseInd": "string", + "xmlDescription": "string", + "sortOrder": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowquestioncategory + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowQuestionCategoryIds | int | Workflow Question Category Ids are the unique identifiers for the associated workflow question category. +workflowTypeIds | int | Workflow Type IDs are the unique identifiers for the associated workflow type. +workflow question category | string | Workflow Question Category is the category of the form type. + + +### 28. Workflow Type Table + +This section outlines how to retrieve data from the Workflow Type table using the provided endpoint. You have the flexibility to fetch specific data by including workflow Ids, workflow type Ids, and workflows. The Unit type endpoint also supports pagination for managing large datasets effectively. + +> Example Request + +```javascript +var request = require("request"); + +var options = { method: 'GET', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowtype' }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowtype"); +var request = new RestRequest(Method.GET); +IRestResponse response = client.Execute(request); +``` + +> Response Schema + +```json +{ + "currentPage": 1, + "totalPages": 1, + "currentPageSize": 500, + "maxAPIPageSize": 500, + "totalCount": 337, + "hasPrevious": false, + "hasNext": true, + "data": [ + { + "workflowTypeId": "number", + "workflowType": "string", + "workflowCategoryId": "number", + "remoteInd": "string", + "addCondition": "string", + "openCondition": "string", + "workflowAssociationsInd": "string", + "fileAttachmentsInd": "string", + "allowCopyInd": "string", + "viewName": "string", + "xmlDescription": "string", + "sortOrder": "number", + "lastModifiedDate": "2017-02-13T22:15:30.203Z", + "externalIdentifier": "string", + "comments": "string", + "refId": "string" + } + ] +} + +``` + +**API Endpoints** + +`GET` /actsapi/v1/workflowtype + +**Query parameters** + +Attribute | Type | Description +--------- | ---- | ----------- +PageNumber | int | Page number of the results to fetch. +PageSize | int | The number of results per page +workflowTypeIds | int | Workflow Type IDs are the unique identifier for a workflow type. +workflowCategoryIds | int | Workflow Category IDs are the unique identifier for the associated workflow category. +workflowTypes | string | Workflow Types are the assigned values for the type of workflow and can be used as a filter. + + + diff --git a/source/includes/acts/post_api.md b/source/includes/acts/post_api.md new file mode 100644 index 00000000000..a01dda3b808 --- /dev/null +++ b/source/includes/acts/post_api.md @@ -0,0 +1,2021 @@ +## Add or Modify Data + +This section outlines the available POST APIs designed for modifying ACTS data. These APIs let you update existing records and insert new records. POSTs should be formatted in JSON. + +* To insert new records, set the primary key to 0 +* To update existing records, use the primary key of the record. + + + +As per the current release, POST APIs End points are provided to add or update the following tables: + +* Analysis +* Analysis Compound +* Emission Factor +* Emissions Recalculate By Equipment +* Emissions Recalculate By Operation +* Equipment +* Equipment Analysis +* Equipment Attribute +* Facility +* Facility Attribute +* Operation +* Regulation +* Requirement +* Requirement Limit +* Workflow +* Workflow Answer +* Workflow Equipment +* Workflow Facility +* Workflow Person + +POST requests to these endpoints should be formatted in JSON. + +### 1. Analysis Table + +This section guides you through the process of modifying existing Analysis records or adding new entries to the Analysis table using the designated API endpoint. For inserting a new record, please pass the primary key field AnalysisId as 0 in the request body. + +**Analysis POST endpoint** + +`POST` /actsapi/v1/analysis + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/analysis', + headers: { 'content-type': 'application/json' }, + body: + [ +{ + "analysisId": "number", + "analysisName": "string", + "analysisDate": "2024-11-01T12:58:49Z", + "analysisTypeId": "number", + "analysisStatusId": "number", + "alternateName": "string", + "vendorId": "number", + "vendorAnalysisNumber": "string", + "vendorJobNumber": "string", + "vendorId2": "number", + "vendorAnalysisNumber2": "string", + "vendorJobNumber2": "string", + "reviewedById": "number", + "reviewedDate": "2024-11-01T12:58:49Z", + "submitDate": "2024-11-01T12:58:49Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" +} +], + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/analysis"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[ {\r\n \"analysisId\": \"number\",\r\n \"analysisName\": \"string\",\r\n + \"analysisDate\": \"2024-11-01T12:58:49Z\",\r\n \"analysisTypeId\": \"number\",\r\n \"analysisStatusId\": \"number\",\r\n + \"alternateName\": \"string\",\r\n \"vendorId\": \"number\",\r\n \"vendorAnalysisNumber\": \"string\",\r\n \"vendorJobNumber\": \"string\",\r\n \"vendorId2\": \"number\",\r\n \"vendorAnalysisNumber2\": \"string\",\r\n \"vendorJobNumber2\": \"string\",\r\n + \"reviewedById\": \"number\",\r\n \"reviewedDate\": \"2024-11-01T12:58:49Z\",\r\n \"submitDate\": \"2024-11-01T12:58:49Z\",\r\n + \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"}\r\n]", + ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "analysisId": "number", + "analysisName": "string", + "analysisDate": "2024-11-01T12:58:49Z", + "analysisTypeId": "number", + "analysisStatusId": "number", + "alternateName": "string", + "vendorId": "number", + "vendorAnalysisNumber": "string", + "vendorJobNumber": "string", + "vendorId2": "number", + "vendorAnalysisNumber2": "string", + "vendorJobNumber2": "string", + "reviewedById": "number", + "reviewedDate": "2024-11-01T12:58:49Z", + "submitDate": "2024-11-01T12:58:49Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" +} +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "deletedRowCount" : 0 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update due to invalid analysisId + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 0 , + "deletedRowCount" : 0 , + "failureCount" : 1 , + "errorMessage" : [ + "External Identifier : , Error: An error occurred while saving the entity changes. See the inner exception for details. " + ] +} + +``` + +### 2. Analysis Compound Table + +This section guides you through the process of modifying existing Analysis Compound records or adding new entries to the Analysis Compound table using the designated API endpoint. For inserting a new record, please pass the primary key field AnalysisCompoundId as 0 in the request body. + +**Analysis Compound POST endpoint** + +`POST` /actsapi/v1/analysiscompound + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/analysiscompound', + headers: { 'content-type': 'application/json' }, + body: + [ +{ + "analysisCompoundId": "number", + "analysisId": "number", + "compoundId": "number", + "operator": "string", + "analysisValue": "number", + "unitId": "number", + "resultText": "string", + "analysisDate": "2011-07-19T00:00:00z", + "dilutionFactor": "number", + "reportingLimit": "number", + "method": "string", + "methodDetectionLimit": "number", + "qualifier": "string", + "reportableInd": "string", + "dataLockTypeId": "number", + "sortOrder": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/analysiscompound"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[ {\r\n \"analysisCompoundId\": \"number\",\r\n \"analysisId\": \"number\",\r\n + \"compoundId\": \"number\",\r\n \"operator\": \"string\",\r\n \"analysisValue\": \"number\",\r\n \"unitId\": \"number\",\r\n + \"resultText\": \"string\",\r\n \"analysisDate\": \"2011-07-19T00:00:00z\",\r\n \"dilutionFactor\": \"number\",\r\n + \"reportingLimit\": \"number\",\r\n \"method\": \"string\",\r\n \"methodDetectionLimit\": \"number\",\r\n + \"qualifier\": \"string\",\r\n \"reportableInd\": \"string\",\r\n \"dataLockTypeId\": \"number\",\r\n \"sortOrder\": \"number\",\r\n + \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\" }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ +{ + "analysisCompoundId": "number", + "analysisId": "number", + "compoundId": "number", + "operator": "string", + "analysisValue": "number", + "unitId": "number", + "resultText": "string", + "analysisDate": "2011-07-19T00:00:00z", + "dilutionFactor": "number", + "reportingLimit": "number", + "method": "string", + "methodDetectionLimit": "number", + "qualifier": "string", + "reportableInd": "string", + "dataLockTypeId": "number", + "sortOrder": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "deletedRowCount" : 0 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update due to invalid analysisCompoundId + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 0 , + "deletedRowCount" : 0 , + "failureCount" : 1 , + "errorMessage" : [ + "External Identifier : , Error: An error occurred while saving the entity changes. See the inner exception for details. " + ] +} + +``` + +### 3. Emission Factor Table + +This section guides you through the process of modifying existing Emission Factor records or adding new entries to the Emission Factor table using the designated API endpoint. For inserting a new record, please pass the primary key field emissionFactorId as 0 in the request body. + +**Emission Factor POST endpoint** + +`POST` /actsapi/v1/emissionfactor + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/emissionfactor', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "emissionFactorId": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "compoundId": "number", + "emissionFactorName": "string", + "activeDate": "2023-06-25T04:00:00Z", + "emissionFactor": "number", + "unitId": "number", + "viewColumnName": "string", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/emissionfactor"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[ {\r\n \"emissionFactorId\": \"number\",\r\n \"equipmentId\": \"number\",\r\n \"emissionTypeId\": \"number\",\r\n \"emissionCategoryId\": \"number\",\r\n \"compoundId\": \"number\",\r\n \"emissionFactorName\": \"string\",\r\n \"activeDate\": \"2023-06-25T04:00:00Z\",\r\n \"emissionFactor\": \"number\",\r\n \"unitId\": \"number\",\r\n \"viewColumnName\": \"string\",\r\n \"inactiveDate\": \"2023-06-25T04:00:00Z\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "emissionFactorId": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "compoundId": "number", + "emissionFactorName": "string", + "activeDate": "2023-06-25T04:00:00Z", + "emissionFactor": "number", + "unitId": "number", + "viewColumnName": "string", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "deletedRowCount" : 0 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update due to invalid EmissionFactorId + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 0 , + "deletedRowCount" : 0 , + "failureCount" : 1 , + "errorMessage" : [ + "External Identifier : , Error: An error occurred while saving the entity changes. See the inner exception for details. " + ] +} + +``` + +### 4. Emissions Recalculate By Equipment + +This section guides you through the process of an on-demand update to the emissions calculation for a specific equipment using the designated API endpoint. While this API endpoint is a child of the Equipment table, adding or updating an equipment will not cause an update on its own. + +**Equipment/EmissionCalculation POST endpoint** + +`POST` /actsapi/v1/equipment/emissioncalculation + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipment/emissioncalculation', + headers: { 'content-type': 'application/json' }, + body: + { [equipmentId1, equipmentId2, equipmentId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipment/emissioncalculation"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [equipmentId1, equipmentId2, equipmentId3....]\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +{ + [equipmentId1, equipmentId2, equipmentId3....] + } +``` +> Example Response + +```json +{ + "processedIds": [ + "34", + "36" + ], + "invalidIds": [ + "1234" + ], + "errorMessages": [] +} + +``` + +> Example Output when data is missing + +```json +{ + "processedIds": [], + "invalidIds": [], + "errorMessages": [ + "Equipment ids are missing." + ] +} + +``` + +### 5. Emissions Recalculate By Operation + +This section guides you through the process of an on-demand update to the emissions calculation for a specific operation using the designated API endpoint. While this API endpoint is a child of the Operation table, adding or updating an operation with the API will not cause an update on its own. + +**Operation/EmissionCalculation POST endpoint** + +`POST` /actsapi/v1/operation/emissioncalculation + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/operation/emissioncalculation', + headers: { 'content-type': 'application/json' }, + body: + { [operationId1, operationId2, operationId3....] + }, + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/operation/emissioncalculation"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n [operationId1, operationId2, operationId3....]\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +{ + [operationId1, operationId2, operationId3....] +} +``` +> Example Response + +```json +{ + "processedIds": [ + "34", + "36" + ], + "invalidIds": [ + "1234" + ], + "errorMessages": [] +} + +``` + +> Example Output when data is missing + +```json +{ + "processedIds": [], + "invalidIds": [], + "errorMessages": [ + "Operation ids are missing." + ] +} + +``` + + +### 6. Equipment Table + +This section guides you through the process of modifying existing equipment records or adding new entries to the Equipment table using the designated API endpoint. + +**Equipment POST endpoint** + +`POST` /actsapi/v1/equipment + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipment', + headers: { 'content-type': 'application/json' }, + body: + [ { + "equipmentId": "number", + "areaId": "number", + "facilityId": "number", + "equipmentTypeId": "number", + "sourceName": "string ", + "equipmentStatusId": "number", + "modelId": "number", + "ownershipId": "number", + "ownerId": "number", + "serialNumber": "number", + "manufactureDate": "2023-06-25T04:00:00Z", + "internalName": "string", + "alternateName": "string", + "design": "string", + "originalSurveyDate": "2023-06-25T04:00:00Z", + "activeDate": "2023-06-25T04:00:00Z", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + }], + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipment"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", " [ {\r\n \"equipmentId\": \"number\",\r\n \"areaId\": \"number\",\r\n \"facilityId\": \"number\",\r\n \"equipmentTypeId\": \"number\",\r\n \"sourceName\": \"string \",\r\n \"equipmentStatusId\": \"number\",\r\n \"modelId\": \"number\",\r\n \"ownershipId\": \"number\",\r\n \"ownerId\": \"number\",\r\n \"serialNumber\": \"number\",\r\n \"manufactureDate\": \"2023-06-25T04:00:00Z\",\r\n \"internalName\": \"string\",\r\n \"alternateName\": \"string\",\r\n \"design\": \"string\",\r\n \"originalSurveyDate\": \"2023-06-25T04:00:00Z\",\r\n \"activeDate\": \"2023-06-25T04:00:00Z\",\r\n \"inactiveDate\": \"2023-06-25T04:00:00Z\",\r\n\t \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "equipmentId": "number", + "areaId": "number", + "facilityId": "number", + "equipmentTypeId": "number", + "sourceName": "string ", + "equipmentStatusId": "number", + "modelId": "number", + "ownershipId": "number", + "ownerId": "number", + "serialNumber": "number", + "manufactureDate": "2023-06-25T04:00:00Z", + "internalName": "string", + "alternateName": "string", + "design": "string", + "originalSurveyDate": "2023-06-25T04:00:00Z", + "activeDate": "2023-06-25T04:00:00Z", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Equipment ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 7. Equipment Analysis Table + +This section outlines the process of adding new entries or modifying existing records within the Equipment Analysis table using the dedicated API endpoint. + +**Equipment Analysis POST Endpoint** + +`POST` /actsapi/v1/equipmentanalysis + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentanalysis', + headers: { 'content-type': 'application/json' }, + body: + + [ + { + "equipmentAnalysisId": "number", + "equipmentId": "number", + "analysisId": "number", + "analysisAssociationTypeId": "number", + "activeDate": "2014-04-01T00:00:00z", + "inactiveDate": "2025-04-01T00:00:00z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentanalysis"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", " [\r\n { \r\n\ "equipmentAnalysisId\": \"number\",\r\n \"equipmentId\": \"number\",\r\n + \"analysisId\": \"number\",\r\n \"analysisAssociationTypeId\": \"number\",\r\n \"activeDate\": \"2014-04-01T00:00:00z\",\r\n + \"inactiveDate\": \"2025-04-01T00:00:00z\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\" \r\n }\r\n]", + ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json + [ + { + "equipmentAnalysisId": "number", + "equipmentId": "number", + "analysisId": "number", + "analysisAssociationTypeId": "number", + "activeDate": "2014-04-01T00:00:00z", + "inactiveDate": "2025-04-01T00:00:00z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 0 , + "failureCount" : 1 , + "errorMessage" : [ + "EquipmentAnalysis ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 8. Equipment Attribute Table + +This section outlines the process of adding new entries or modifying existing records within the Equipment Attribute table using the dedicated API endpoint. + +**Equipment Attribute POST Endpoint** + +`POST` /actsapi/v1/equipmentattribute + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentattribute', + headers: { 'content-type': 'application/json' }, + body: + + [ + { + "equipmentAttributeId": "number", + "equipmentId": "number", + "attributeTypeId": "number", + "equipmentAttribute":"string", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments":"string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/equipmentattribute"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", " [\r\n { \r\n"equipmentAttributeId\": \"number\",\r\n \"equipmentId\": \"number\",\r\n \"attributeTypeId\": \"number\",\r\n \"equipmentAttribute\":\"string\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\":\"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json + [ + { + "equipmentAttributeId": "number", + "equipmentId": "number", + "attributeTypeId": "number", + "equipmentAttribute":"string", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments":"string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "EquipmentAttribute ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + + + +### 9. Facility Table + +This section outlines the process of adding new entries or modifying existing records within the Facility table using the dedicated API endpoint. + +**Facility POST Endpoint** + +`POST` /actsapi/v1/facility + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/facility', + headers: { 'content-type': 'application/json' }, + body: + [{ + "facilityId": "number", + "facilityName": "string", + "areaId": "number", + "facilityTypeId": "number", + "facilityStatusId": "number", + "sortOrder": "number", + "facilityOwnershipId": "number", + "facilityOwnerId": "number", + "landOwnershipId": "number", + "landOwnerId": "number", + "operatorId": "number", + "countryId": "number", + "countyId": "number", + "offshoreBlockId": "number", + "meteorologicalId": "number", + "businessEntityId": "number", + "businessUnitId": "number", + "alternateName": "string", + "purchaseDate": "2023-06-25T04:00:00Z", + "previousOwnerId": "number", + "soldDate": "2023-06-25T04:00:00Z", + "soldToId": "number", + "activeDate": "2023-06-25T04:00:00Z", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + }], + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/facility"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[{\r\n \"facilityId\": \"number\",\r\n \"facilityName\": \"string\",\r\n \"areaId\": \"number\",\r\n \"facilityTypeId\": \"number\",\r\n \"facilityStatusId\": \"number\",\r\n \"sortOrder\": \"number\",\r\n \"facilityOwnershipId\": \"number\",\r\n \"facilityOwnerId\": \"number\",\r\n \"landOwnershipId\": \"number\",\r\n \"landOwnerId\": \"number\",\r\n \"operatorId\": \"number\",\r\n \"countryId\": \"number\",\r\n \"countyId\": \"number\",\r\n \"offshoreBlockId\": \"number\",\r\n \"meteorologicalId\": \"number\",\r\n \"businessEntityId\": \"number\",\r\n \"businessUnitId\": \"number\",\r\n \"alternateName\": \"string\",\r\n \"purchaseDate\": \"2023-06-25T04:00:00Z\",\r\n \"previousOwnerId\": \"number\",\r\n \"soldDate\": \"2023-06-25T04:00:00Z\",\r\n \"soldToId\": \"number\",\r\n \"activeDate\": \"2023-06-25T04:00:00Z\",\r\n \"inactiveDate\": \"2023-06-25T04:00:00Z\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "facilityId": "number", + "facilityName": "string", + "areaId": "number", + "facilityTypeId": "number", + "facilityStatusId": "number", + "sortOrder": "number", + "facilityOwnershipId": "number", + "facilityOwnerId": "number", + "landOwnershipId": "number", + "landOwnerId": "number", + "operatorId": "number", + "countryId": "number", + "countyId": "number", + "offshoreBlockId": "number", + "meteorologicalId": "number", + "businessEntityId": "number", + "businessUnitId": "number", + "alternateName": "string", + "purchaseDate": "2023-06-25T04:00:00Z", + "previousOwnerId": "number", + "soldDate": "2023-06-25T04:00:00Z", + "soldToId": "number", + "activeDate": "2023-06-25T04:00:00Z", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` + +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Facility ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 10. Facility Attribute Table + +This section outlines the process of adding new entries or modifying existing records within the Facility Attribute table using the dedicated API endpoint. + +**Facility Attribute POST Endpoint** + +`POST` /actsapi/v1/facilityattribute + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/facilityattribute', + headers: { 'content-type': 'application/json' }, + body: + [ + { "facilityAttributeId": "number", + "facilityId": "number", + "attributeTypeId": "number", + "facilityAttribute":"string", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments":"string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/facilityattribute"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[\r\n { \r\n"facilityAttributeId\": \"number\",\r\n \"facilityId\": \"number\",\r\n \"attributeTypeId\": \"number\",\r\n \"facilityAttribute\":\"string\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\":\"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "facilityAttributeId": "number", + "facilityId": "number", + "attributeTypeId": "number", + "facilityAttribute":"string", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments":"string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "FacilityAttribute ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 11. Operation Table + +This section outlines the process of adding new entries or modifying existing records within the Operation table using the dedicated API endpoint. + +**Operation POST Endpoint** + +`POST` /actsapi/v1/operation + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/operation', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "operationId": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "operationTypeId": "number", + "activeDate": "2023-06-25T04:00:00Z", + "unitId": "number", + "controlledInd": "string", + "estimatedInd": "string", + "invalidInd": "string", + "calculateEmissionsInd": "string", + "collectionDate": "2023-06-25T04:00:00Z", + "fieldEventId": "number", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string", + "badDataFlag": "number(1,0)", + "operationAmount": "number" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/operation"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[\r\n {\r\n \"operationId\": \"number\",\r\n \"equipmentId\": \"number\",\r\n \"emissionTypeId\": \"number\",\r\n \"emissionCategoryId\": \"number\",\r\n \"operationTypeId\": \"number\",\r\n \"activeDate\": \"2023-06-25T04:00:00Z\",\r\n \"unitId\": \"number\",\r\n \"controlledInd\": \"string\",\r\n \"estimatedInd\": \"string\",\r\n \"invalidInd\": \"string\",\r\n \"calculateEmissionsInd\": \"string\",\r\n \"collectionDate\": \"2023-06-25T04:00:00Z\",\r\n \"fieldEventId\": \"number\",\r\n \"inactiveDate\": \"2023-06-25T04:00:00Z\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\",\r\n \"badDataFlag\": \"number(1,0)\",\r\n \"operationAmount\": \"number\"\r\n } \r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` +> Input JSON Body + +```json +[ + { + "operationId": "number", + "equipmentId": "number", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "operationTypeId": "number", + "activeDate": "2023-06-25T04:00:00Z", + "unitId": "number", + "controlledInd": "string", + "estimatedInd": "string", + "invalidInd": "string", + "calculateEmissionsInd": "string", + "collectionDate": "2023-06-25T04:00:00Z", + "fieldEventId": "number", + "inactiveDate": "2023-06-25T04:00:00Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string", + "badDataFlag": "number(1,0)", + "operationAmount": "number" + } +] + +``` + +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Operation ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 12. Regulation Table + +This section outlines the process of adding new entries or modifying existing records within the Regulation table using the dedicated API endpoint. + +**Regulation POST Endpoint** + +`POST` /actsapi/v1/regulation + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/regulation', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "activeDate": "2025-10-21T15:14:09.542Z", + "inactiveDate": "2025-10-21T15:14:09.543Z", + "externalIdentifier": "string", + "comments": "string", + "regulationId": "number", + "agencyId": "number", + "regulationTypeId": "number", + "mediaId": "number", + "regulationName": "string", + "regulationStatusId": "number", + "applicationDate": "2025-10-21T15:14:09.543Z", + "completeDate": "2025-10-21T15:14:09.543Z", + "publicNoticeDate": "2025-10-21T15:14:09.543Z", + "issueDate": "2025-10-21T15:14:09.543Z", + "renewalDate": "2025-10-21T15:14:09.543Z", + "expirationDate": "2025-10-21T15:14:09.543Z", + "description": "string", + "applicabilityCriteria": "string", + "sortOrder": "number" + } + ], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/regulation"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[{\"activeDate\":\"2025-10-21T15:14:09.542Z\",\"inactiveDate\":\"2025-10-21T15:14:09.543Z\",\"externalIdentifier\":\"string\",\"comments\":\"string\",\"regulationId\":\"number\",\"agencyId\":\"number\",\"regulationTypeId\":\"number\",\"mediaId\":\"number\",\"regulationName\":\"string\",\"regulationStatusId\":\"number\",\"applicationDate\":\"2025-10-21T15:14:09.543Z\",\"completeDate\":\"2025-10-21T15:14:09.543Z\",\"publicNoticeDate\":\"2025-10-21T15:14:09.543Z\",\"issueDate\":\"2025-10-21T15:14:09.543Z\",\"renewalDate\":\"2025-10-21T15:14:09.543Z\",\"expirationDate\":\"2025-10-21T15:14:09.543Z\",\"description\":\"string\",\"applicabilityCriteria\":\"string\",\"sortOrder\":\"number\"}]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "activeDate": "2025-10-21T15:14:09.542Z", + "inactiveDate": "2025-10-21T15:14:09.543Z", + "externalIdentifier": "string", + "comments": "string", + "regulationId": "number", + "agencyId": "number", + "regulationTypeId": "number", + "mediaId": "number", + "regulationName": "string", + "regulationStatusId": "number", + "applicationDate": "2025-10-21T15:14:09.543Z", + "completeDate": "2025-10-21T15:14:09.543Z", + "publicNoticeDate": "2025-10-21T15:14:09.543Z", + "issueDate": "2025-10-21T15:14:09.543Z", + "renewalDate": "2025-10-21T15:14:09.543Z", + "expirationDate": "2025-10-21T15:14:09.543Z", + "description": "string", + "applicabilityCriteria": "string", + "sortOrder": "number" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2, + "updatedRowCount" : 3, + "failureCount" : 0, + "errorMessage" : [] +} +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount": 0, + "updatedRowCount": 0, + "failureCount": 1, + "errorMessage": [ + "Not found RegulationIds: 123041" + ] +} +``` + +### 13. Requirement Table + +This section outlines the process of adding new entries or modifying existing records within the Requirement table using the dedicated API endpoint. + +**Requirement POST Endpoint** + +`POST` /actsapi/v1/requirement + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/requirement', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "requirementId": "number", + "regulationId": "number", + "requirementTypeId": "number", + "requirementName": "string", + "requirementFrequencyId": "number", + "requirementCategoryId": "number", + "regulationActivityId": "number", + "description": "string", + "associatedRequirements": "string", + "applicabilityCriteria": "string", + "sortOrder": "number", + "generateTaskInd": "string", + "taskText": "string", + "firstDueDate": "2024-01-03T08:16:24.155Z", + "generateFacilityTasksInd": "string", + "combineTasksInd": "string", + "attributeTypeId": "number", + "triggerOffset": "number", + "triggerOffsetType": "string", + "creationOffset": "number", + "dependentRequirementId": "number", + "conditionalFormula": "string", + "activeDate": "2024-01-03T08:16:24.155Z", + "inactiveDate": "2024-01-03T08:16:24.155Z", + "externalIdentifier": "string", + "comments": "string" + } + ], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/requirement"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[{\"requirementId\":\"number\",\"regulationId\":\"number\",\"requirementTypeId\":\"number\",\"requirementName\":\"string\",\"requirementFrequencyId\":\"number\",\"requirementCategoryId\":\"number\",\"regulationActivityId\":\"number\",\"description\":\"string\",\"associatedRequirements\":\"string\",\"applicabilityCriteria\":\"string\",\"sortOrder\":\"number\",\"generateTaskInd\":\"string\",\"taskText\":\"string\",\"firstDueDate\":\"2024-01-03T08:16:24.155Z\",\"generateFacilityTasksInd\":\"string\",\"combineTasksInd\":\"string\",\"attributeTypeId\":\"number\",\"triggerOffset\":\"number\",\"triggerOffsetType\":\"string\",\"creationOffset\":\"number\",\"dependentRequirementId\":\"number\",\"conditionalFormula\":\"string\",\"activeDate\":\"2024-01-03T08:16:24.155Z\",\"inactiveDate\":\"2024-01-03T08:16:24.155Z\",\"externalIdentifier\":\"string\",\"comments\":\"string\"}]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "requirementId": "number", + "regulationId": "number", + "requirementTypeId": "number", + "requirementName": "string", + "requirementFrequencyId": "number", + "requirementCategoryId": "number", + "regulationActivityId": "number", + "description": "string", + "associatedRequirements": "string", + "applicabilityCriteria": "string", + "sortOrder": "number", + "generateTaskInd": "string", + "taskText": "string", + "firstDueDate": "2024-01-03T08:16:24.155Z", + "generateFacilityTasksInd": "string", + "combineTasksInd": "string", + "attributeTypeId": "number", + "triggerOffset": "number", + "triggerOffsetType": "string", + "creationOffset": "number", + "dependentRequirementId": "number", + "conditionalFormula": "string", + "activeDate": "2024-01-03T08:16:24.155Z", + "inactiveDate": "2024-01-03T08:16:24.155Z", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2, + "updatedRowCount" : 3, + "failureCount" : 0, + "errorMessage" : [] +} +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount": 0, + "updatedRowCount": 0, + "failureCount": 1, + "errorMessage": [ + "RequirementId: 103356 does not exist" + ] +} + +``` + +### 14. Requirement Limit Table + +This section outlines the process of adding new entries or modifying existing records within the Requirement Limit table using the dedicated API endpoint. + +**Requirement Limit POST Endpoint** + +`POST` /actsapi/v1/requirementLimit + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/requirementLimit', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "activeDate": "2025-10-21T15:34:20.173Z", + "inactiveDate": "2025-10-21T15:34:20.173Z", + "externalIdentifier": "string", + "comments": "string", + "requirementLimitId": "number", + "requirementId": "number", + "requirementLimitTypeId": "number", + "compoundId": "number", + "compoundGroupTypeId": "number", + "unitId": "number", + "operator": "string", + "limitThreshold": "number", + "compareLimitInd": "string", + "compareDecimalPlaces": "number", + "compareOffset": "number", + "compareDays": "number", + "limitViolationText": "string", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "operationTypeId": "number", + "analysisTypeId": "number", + "analysisValueName": "string", + "customLimitThreshold": "string", + "sortOrder": "number" + } + ], + json: true }; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/requirementLimit"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[{\"activeDate\":\"2025-10-21T15:34:20.173Z\",\"inactiveDate\":\"2025-10-21T15:34:20.173Z\",\"externalIdentifier\":\"string\",\"comments\":\"string\",\"requirementLimitId\":\"number\",\"requirementId\":\"number\",\"requirementLimitTypeId\":\"number\",\"compoundId\":\"number\",\"compoundGroupTypeId\":\"number\",\"unitId\":\"number\",\"operator\":\"string\",\"limitThreshold\":\"number\",\"compareLimitInd\":\"string\",\"compareDecimalPlaces\":\"number\",\"compareOffset\":\"number\",\"compareDays\":\"number\",\"limitViolationText\":\"string\",\"emissionTypeId\":\"number\",\"emissionCategoryId\":\"number\",\"operationTypeId\":\"number\",\"analysisTypeId\":\"number\",\"analysisValueName\":\"string\",\"customLimitThreshold\":\"string\",\"sortOrder\":\"number\"}]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "activeDate": "2025-10-21T15:34:20.173Z", + "inactiveDate": "2025-10-21T15:34:20.173Z", + "externalIdentifier": "string", + "comments": "string", + "requirementLimitId": "number", + "requirementId": "number", + "requirementLimitTypeId": "number", + "compoundId": "number", + "compoundGroupTypeId": "number", + "unitId": "number", + "operator": "string", + "limitThreshold": "number", + "compareLimitInd": "string", + "compareDecimalPlaces": "number", + "compareOffset": "number", + "compareDays": "number", + "limitViolationText": "string", + "emissionTypeId": "number", + "emissionCategoryId": "number", + "operationTypeId": "number", + "analysisTypeId": "number", + "analysisValueName": "string", + "customLimitThreshold": "string", + "sortOrder": "number" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 1, + "updatedRowCount" : 0, + "failureCount" : 0, + "errorMessage" : [] +} +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount": 0, + "updatedRowCount": 0, + "failureCount": 1, + "errorMessage": [ + "Not found RequirementLimitIds: 12345" + ] +} +``` + +### 15. Workflow Table + +This section outlines the process of adding new entries or modifying existing records within the Workflow table using the dedicated API endpoint. + +**Workflow POST Endpoint** + +`POST` /actsapi/v1/workflow + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflow', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "workflowId": "number", + "workflowTypeId": "number", + "workflowDate": "2024-01-03T08:16:24.155Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflow"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", " [\r\n {\r\n \"workflowId\": \"number\",\r\n \"workflowTypeId\": \"number\",\r\n \"workflowDate\": \"2024-01-03T08:16:24.155Z\",\r\n \"dataLockTypeId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "workflowId": "number", + "workflowTypeId": "number", + "workflowDate": "2024-01-03T08:16:24.155Z", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Workflow Id : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 16. Workflow Answer Table + +This section outlines the process of adding new entries or modifying existing records within the Workflow Answer table using the dedicated API endpoint. + +**Workflow Answer POST Endpoint** + +`POST` /actsapi/v1/workflowanswer + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowanswer', + headers: { 'content-type': 'application/json' }, + body: + [{ + "workflowAnswerId": "number", + "workflowId": "number", + "workflowQuestionId": "number", + "categoryAnswerIndex": "number", + "categoryRevisionIndex": "number", + "questionAnswerIndex": "number", + "questionRevisionIndex": "number", + "workflowAnswer": "string", + "dataLockTypeId": "number", + "personId": "number", + "externalIdentifier": "string", + "comments": "string" + }], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowanswer"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[{\r\n \"workflowAnswerId\": \"number\",\r\n \"workflowId\": \"number\",\r\n \"workflowQuestionId\": \"number\",\r\n \"categoryAnswerIndex\": \"number\",\r\n \"categoryRevisionIndex\": \"number\",\r\n \"questionAnswerIndex\": \"number\",\r\n \"questionRevisionIndex\": \"number\",\r\n \"workflowAnswer\": \"string\",\r\n \"dataLockTypeId\": \"number\",\r\n \"personId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[{ + "workflowAnswerId": "number", + "workflowId": "number", + "workflowQuestionId": "number", + "categoryAnswerIndex": "number", + "categoryRevisionIndex": "number", + "questionAnswerIndex": "number", + "questionRevisionIndex": "number", + "workflowAnswer": "string", + "dataLockTypeId": "number", + "personId": "number", + "externalIdentifier": "string", + "comments": "string" + }] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Workflow Answer Id : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 17. Workflow Equipment Table + +This section outlines the process of adding new entries or modifying existing records within the Workflow Equipment table using the dedicated API endpoint. + +**Workflow Equipment POST Endpoint** + +`POST` /actsapi/v1/workflowequipment + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowequipment', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "workflowEquipmentId": "number", + "workflowId": "number", + "equipmentId": "number", + "workflowQuestionId": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowequipment"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[\r\n {\r\n \"workflowEquipmentId\": \"number\",\r\n \"workflowId\": \"number\",\r\n \"equipmentId\": \"number\",\r\n \"workflowQuestionId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "workflowEquipmentId": "number", + "workflowId": "number", + "equipmentId": "number", + "workflowQuestionId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Workflow Equipment Id : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 18. Workflow Facility Table + +This section outlines the process of adding new entries or modifying existing records within the Workflow Facility table using the dedicated API endpoint. + +**Workflow Facility POST Endpoint** + +`POST` /actsapi/v1/workflowfacility + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowfacility', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "workflowFacilityId": "number", + "workflowId": "number", + "facilityId": "number", + "workflowQuestionId": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/workflowfacility"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[\r\n {\r\n \"workflowFacilityId\": \"number\",\r\n \"workflowId\": \"number\",\r\n \"facilityId\": \"number\",\r\n \"workflowQuestionId\": \"number\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "workflowFacilityId": "number", + "workflowId": "number", + "facilityId": "number", + "workflowQuestionId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json + +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Workflow Facility Id : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### 19. Workflow Person Table + +This section outlines the process of adding new entries or modifying existing records within the Workflow Person table using the dedicated API endpoint. + +**Workflow Person POST Endpoint** + +`POST` /actsapi/v1/workflowperson + +> Example Request & JSON Input Body + +```javascript +var request = require("request"); + +var options = { method: 'POST', + url: 'https://[tenant].actsapi.intelex.com/actsapi/v1/workflowperson', + headers: { 'content-type': 'application/json' }, + body: + [ + { + "workflowPersonId": "number", + "workflowId": "number", + "personId": "number", + "workflowQuestionId": "number", + "externalIdentifier": "string", + "comments": "string" + } +], + json: true }; + + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://[tenant].actsapi.intelex.com/actsapi/v1/Workflowperson"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "[\r\n {\r\n \"workflowPersonId\": \"number\",\r\n \"workflowId\": \"number\",\r\n \"personId\": \"number\",\r\n \"workflowQuestionId\": \"number\",\r\n \"lastModifiedDate\": \"2024-01-03T08:16:24.155Z\",\r\n \"externalIdentifier\": \"string\",\r\n \"comments\": \"string\"\r\n }\r\n]", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +> Input JSON Body + +```json +[ + { + "workflowPersonId": "number", + "workflowId": "number", + "personId": "number", + "workflowQuestionId": "number", + "externalIdentifier": "string", + "comments": "string" + } +] +``` +> Example Response + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json + +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Workflow Person Id : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + +### JSON body for both Insert & Update + +#### JSON Input body for Insert + +If the primary id is zero - "0" then the data we are passing is handled as an insert, shown in the example below, where "equipmentAttributeId" is passed as "0". + +Parameter | Description +--------- | ----------- +equipmentAttributeId | equipmentAttributeId for insert we do pass the input as zero "0" +equipmentId | equipmentId accepts the numbers as input +attributeTypeId | attributeTypeId accepts the numbers as input +equipmentAttribute | equipmentAttribute accepts the string data as input +dataLockTypeId | dataLockTypeId accepts the numbers as input +externalIdentifier | externalIdentifier accepts the string data as input +comments | comments accepts the string data as input + +> Example Input JSON Body For Insert + +```json +[ + { + "equipmentAttributeId": 0, + "equipmentId": "number", + "attributeTypeId": "number", + "equipmentAttribute":"string", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments":"string" + } +] +``` + +> Example Input JSON Body For Update + +#### JSON Input body for Update + +If the primary id is an existing ID - "#####" then the data we are passing is handled as an update, shown in the example below, where "equipmentAttributeId" is passed as "164". + +Parameter | Description +--------- | ----------- +equipmentAttributeId | equipmentAttributeId for update we do pass the input as integer like "164" +equipmentId | equipmentId accepts the numbers as input +attributeTypeId | attributeTypeId accepts the numbers as input +equipmentAttribute | equipmentAttribute accepts the string data as input +dataLockTypeId | dataLockTypeId accepts the numbers as input +externalIdentifier | externalIdentifier accepts the string data as input +comments | comments accepts the string data as input + + +```json +[ + { + "equipmentAttributeId": 164, + "equipmentId": "number", + "attributeTypeId": "number", + "equipmentAttribute":"string", + "dataLockTypeId": "number", + "externalIdentifier": "string", + "comments":"string" + } +] +``` + +> Example Output For Both Update and Insert + +```json +{ + "insertedRowCount" : 2 , + "updatedRowCount" : 3 , + "failureCount" : 0 , + "errorMessage" : [] + +} + +``` + +> Example Output For When Data Get's Failed To Insert or Update + +```json +{ + "insertedRowCount" : 0 , + "updatedRowCount" : 1 , + "failureCount" : 1 , + "errorMessage" : [ + "Operation ID : 0, Error: An error occurred while saving the entity changes. See the inner exception for details " + ] +} + +``` + diff --git a/source/includes/acts/reference.md b/source/includes/acts/reference.md new file mode 100644 index 00000000000..0f0b7d3a0bd --- /dev/null +++ b/source/includes/acts/reference.md @@ -0,0 +1,60 @@ +## Reference + +The Intelex ACTS API provides endpoints in ACTS, with it's own URL for access. If you currently use the Intelex API, you will not be able to use the ACTS API unless you have Admin access to ACTS. At the same time, you can use the ACTS API without any permission for Intelex V6. + +Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, Token based authentication and HTTP verbs, which are understood by off-the-shelf HTTP clients. JSON is returned by all API responses, including errors. + +### Getting Started with ACTS API + +>API Endpoint - In the URL the tenant is the individual unique tenants based on the tenants they are specifying + +``` +https://[tenant].actsapi.intelex.com/actsapi/v1/ +``` + +To begin using the Intelex API you will need: + +* A valid Intelex ACTS user account +* The full URL to your Intelex ACTS API and system +* The full URL to authentication endpoint +* Understanding of the Intelex ACTS Application. + +### ACTS API Authentication + +>Example Requests: + +```CSharp +Body for Authentication Endpoint +{"client_id":"Client ID Data", +"client_secret":"Client Secret Data", +"audience":"https://*.intelex.com/ACTSAPI", +"grant_type":"client_credentials"} +``` + +>Example Response: + +```json +{ + "access_token": "Generated Bearer Access Token Used For Validation", + "expires_in": "Token Expiry Time In Seconds", + "token_type": "Bearer" +} +``` + +Intelex ACTS API uses tokens based authentication. Only ACTS Admin users can access the API. + +During the authentication process, the client provides the 'client id' and 'client secret' to the authentication endpoint, along with the audience and grant type, as demonstrated above. In response, the API furnishes an access token that comes with a specified time limit. This authentication is exclusively applicable to admin users. After successful authentication, users gain unrestricted access to all ACTS API endpoints till the token expiration. + +All interactions with the API are required to occur via HTTPS, and any API requests lacking proper authentication will result in failure. Data security is meticulously overseen by the ACTS platform, ensuring that API requests grant identical administrative access as enjoyed by authenticated ACTS admin users. + +The user authentication endpoint uses a POST to generate the access token [bearer token]. + +### ACTS API Versioning + +When we make any new changes to the API, we release new versions. The current version of the ACTS API is v1 and can be determined with our API base path /actsapi/v1/. + +>Example API endpoint : https://[tenant].actsapi.intelex.com/actsapi/v1/[endpoint-name] + +### ACTS API Software & Certificate Version Details + +The ACTS API SSL Certification is incompatible with following version of the python 3.10 + . If we use the python version < 3.10 the SSL handshake works for ACTS API.Currently this is considered as one of the limitation. diff --git a/source/includes/user-mgmt/get-api.md b/source/includes/user-mgmt/get-api.md new file mode 100644 index 00000000000..a852301d8d6 --- /dev/null +++ b/source/includes/user-mgmt/get-api.md @@ -0,0 +1,10 @@ +## Retrieve Data + +To retrieve data relevant to Employees and Users that are being managed through the User Management API, please refer to the [Object Data API](#object-data-api) section. + +The applicable User Management [System Objects](#system-objects) that can be accessed will be `SysEmployeeEntity` and `SysUserEntity`. + +Please note: There are some SysUserEntity fields that can be set/updated but are marked as sensitive so they will not be returned when retrieving SysUserEntities. **This is not an exhaustive list and columns marked as sensitive could change in the future**: + +* `SecondaryPassword` +* `DateSecondaryPasswordModified` \ No newline at end of file diff --git a/source/includes/user-mgmt/post-patch-api.md b/source/includes/user-mgmt/post-patch-api.md new file mode 100644 index 00000000000..a30ee156ef1 --- /dev/null +++ b/source/includes/user-mgmt/post-patch-api.md @@ -0,0 +1,724 @@ +## Add or Modify Data + +This section outlines the available POST and PATCH endpoints designed for modifying employee and user data. These endpoints support updating existing records and inserting new records. Requests should be formatted in JSON. + +> User Management API Endpoint + +``` +https://intelex_url/api/v2/EmployeeUserAccess +``` + +### Add Data + +> Example Request + +```javascript +var request = require("request"); + +var options = { + method: 'POST', + url: 'https://intelex_url/api/v2/EmployeeUserAccess', + headers: { 'content-type': 'application/json' }, + body: + { + "EmployeeNumber": "001", + "HomeLocationCode": "001", + "FirstName": "John", + "LastName": "Doe", + "UserId": "jdoe", + "LoginLocationCode": "001", + "LicenseType": "Full Access" + } +}; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/EmployeeUserAccess"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"EmployeeNumber\": \"001\",\r\n \"HomeLocationCode\": \"001\",\r\n \"FirstName\": \"John\",\r\n \"LastName\": \"Doe\",\r\n \"UserId\": \"jdoe\",\r\n \"LoginLocationCode\": \"001\",\r\n \"LicenseType\": \"Full Access\"\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +#### POST /EmployeeUserAccess + +##### Body Parameters + +| Parameter | Description | +| ---------- | ---------------------------------------------------------------------------------------------------------------- | +| field_name | The value you want to set for an employee or user field. Replace _field_name_ with the name of the employee or user field | + +See [Request Payload Field Reference](#request-payload-field-reference) for detailed field information. + +A successful POST to the EmployeeUserAccess endpoint will respond with a 201 Created response code and a json body containing the Id for the created employee and user records. + +> Example Response + +```json +{ + "Id": "43d1b046-156a-4715-bf96-10f71690a528" +} +``` + +### Modify Data + +> Example Request + +```javascript +var request = require("request"); + +var options = { + method: 'PATCH', + url: 'https://intelex_url/api/v2/EmployeeUserAccess', + headers: { 'content-type': 'application/json' }, + body: + { + "EmployeeNumber": "001", + "FirstName": "Jon", + "IsLocked": true + } +}; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); +``` + +```csharp +var client = new RestClient("https://intelex_url/api/v2/EmployeeUserAccess"); +var request = new RestRequest(Method.POST); +request.AddHeader("content-type", "application/json"); +request.AddParameter("application/json", "{\r\n \"EmployeeNumber\": \"001\",\r\n \"FirstName\": \"Jon\",\r\n \"IsLocked\": true\r\n}", ParameterType.RequestBody); +IRestResponse response = client.Execute(request); +``` + +#### PATCH /EmployeeUserAccess({id}) + +##### URL Parameters + +| Parameter | Description | +| ---------------------- | -------------------------------------------------- | +| employee_id _(optional)_ | The Intelex UID of the employee/user being updated | + +NOTE: You may also provide a valid Id or EmployeeNumber in the payload as the identifier used to update the record. + +##### Body Parameters + +| Parameter | Description | +| ---------- | ---------------------------------------------------------------------------------------------------------------- | +| field_name | The value you want to set for and employee or user field. Replace _field_name_ with the name of the employee or user field | + +See [Request Payload Field Reference](#request-payload-field-reference) for detailed field information. + +A successful PATCH to the EmployeeUserAccess endpoint will respond with a 204 No Content response code. + +### Request Payload Field Reference + +#### Settings Flags + +Settings flags are payload fields that configure various behaviors of the user management API request. + +Some settings flags may be ignored if the flag is not relevant to the request type. For example, RevokeUserAccess is only applicable to an existing user, so is only applicable in an update (PATCH) request. + +All flags default to false unless otherwise noted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescription
IgnoreUserAccess +
  • Skips user access creation. Employee record will still be created.
  • +
    SendEmail +
  • Send a password reset email upon successful user creation.
  • +
  • Only respected if user access is requested. I.e. IgnoreUserAccess = false
  • +
    RevokeUserAccess +
  • Existing users only.
  • +
  • Revokes access for the specified user.
  • +
  • Revokes API access for the specified user (if applicable).
  • +
    ArchiveIfTasksAssigned +
  • Existing users only.
  • +
  • Only respected if Flag = I in Employee Fields.
  • +
  • Allows Employees who have tasks assigned to them to be archived.
  • +
  • If ArchiveIfTasksAssigned is not set and the specified employee has tasks assigned, the request will fail with an error and the associated user will be locked.
  • +
    DoNotAddGroupAssignments +
  • Existing employees only.
  • +
  • Do not assign employee membership to the groups specified in the Groups field.
  • +
    RemoveFromUnlistedGroups +
  • Existing employees only.
  • +
  • Remove employee membership from any previously assigned groups that are not specified in the Groups field.
  • +
  • This field is still respected if DoNotAddGroupAssignments is set.
  • +
    + +#### Employee Fields + +Payload fields that are associated with the employee record to be created or updated. + +Properties denoted with a \* are required and must be included in the payload. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PropertyDescription
    Flag +
  • Indicates whether employee should be archived in the system:
  • +
      +
    • A = Active employee (default)
    • +
    • I = Inactive (archived) employee
    • +
    +
  • Archiving an an employee will also remove the associated user's access, if available.
  • +
  • Only existing employees can be archived. You cannot create a new "Inactive" employee.
  • +
    EmployeeNumber* +
  • Primary Key; Unique identifier of employee.
  • +
    HomeLocationCode* +
  • Location Code of the home location of this employee.
  • +
  • This is the Location field on the employee profile.
  • +
    Prefix +
  • Prefix of employee (e.g., Mr., Mrs., Ms.)
  • +
    FirstName* +
  • First name of employee.
  • +
    LastName* +
  • Last name of employee.
  • +
    MiddleName +
  • Middle name of employee.
  • +
    DisplayName +
  • Display name of employee.
  • +
  • If present, cannot be blank ("") or empty (" ").
  • +
  • If not present or null in create payload, defaults to FirstName + LastName.
  • +
  • If not present or null in update payload, value will not be updated.
  • +
    Suffix +
  • Suffix of employee (e.g., Jr., Sr.)
  • +
    Email +
  • Email address of employee.
  • +
    IsSupervisor +
  • Indicates whether employee has direct reports or not.
  • +
  • Valid values are Y or N
  • +
    EmployeeType +
  • Type of Employee.
  • +
  • Must be the Name of a valid SysEmployeeType record.
  • +
    DateOfHire +
  • Date of hire of employee.
  • +
  • Please speak with your consultant to confirm the date format for your subdomain.
  • +
    SupervisorNumber +
  • Employee Number of supervisor of employee.
  • +
    PositionTitle +
  • Job title of employee.
  • +
    Notes +
  • Open text field found in employee profile.
  • +
    Contractor +
  • Indicates whether employee is a contractor.
  • +
  • Valid values are Y or N
  • +
    Company +
  • Company name of employee.
  • +
    ContractorName +
  • Contractor company name of employee.
  • +
    ContractExpiry +
  • Contract expiration date of employee.
  • +
  • Please speak with your consultant to confirm the date format for your subdomain.
  • +
    InsuranceExpiry +
  • Insurance expiration date of employee.
  • +
  • Please speak with your consultant to confirm the date format for your subdomain.
  • +
    ContractorNotes +
  • Open text field found in employee profile.
  • +
    StreetAddress +
  • Street address of employee.
  • +
    City +
  • City of employee.
  • +
    State +
  • State of employee.
  • +
    ZipCode +
  • Zip code (or postal code) of employee.
  • +
    Gender +
  • Gender of employee.
  • +
    DateOfBirth +
  • Date of birth of employee.
  • +
  • Please speak with your consultant to confirm the date format for your subdomain.
  • +
    SSN +
  • Social security number of employee.
  • +
    EmergencyContact +
  • Emergency contact information of employee.
  • +
    EmergencyPhone +
  • Emergency phone number of employee.
  • +
    PersonResponsible +
  • Mandatory for Document Control (all platform versions) and Reassign Task (6.2.5 or lower) feature.
  • +
  • For clients on 6.2.5 or lower, it is recommended to default this value to 1, if not being used.
  • +
  • See V6 System Administrator User Guide on Intelex Exchange for additional details.
  • +
  • For New Employee:
  • +
      +
    • 1: Add to Home Locations & all Locations below
    • +
    • 2: Add to Home Location only
    • +
    • 3: Do not add to Person Responsible List (PRL)
    • +
    +
  • For Existing Employee:
  • +
      +
    • 1: Clear PRL for this employee then add employee to Home Location & all Locations below
    • +
    • 2: Clear PRL for this employee then add employee to Home Location only (does not keep manually added Locations)
    • +
    • 3: Clear PRL for this employee (do not add)
    • +
    • 4: Leave PRL as is (no change)
    • +
    • 5: Replace current Home Location with new Home Location (and keep manually added locations)
    • +
    +
    PhoneNumber +
  • Phone number of employee.
  • +
    HourlyWage +
  • Hourly wage of employee.
  • +
    JobCode +
  • Job Code for employee.
  • +
    WorkStatus +
  • [Legal] Work status of employee.
  • +
    Groups +
  • Semicolon (;) delimited list of elements that this employee is a member of (excluding Everyone group).
  • +
  • Each element can be the Caption or GUID of any Group or Location Role.
  • +
  • Groups includes Security Groups, Roles, Location Roles and Training Workgroups.
  • +
  • If an element is invalid, the request will fail with validation errors in the response.
  • +
  • Notation for Location Role: RoleNameOrGUID(LocationCodeOrGUID)
  • +
    + +#### User Fields + +Payload fields that are associated with the user record to be created or updated if requested (IgnoreUserAccess = false). + +If user access is requested, properties denoted with a \* are required and must be included in the payload. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PropertyDescription
    UserId* +
  • Used by employee to login to the Intelex system; must be unique.
  • +
  • Recommendation: Email address of employee.
  • +
  • Set to email ID for SSO.
  • +
    IsLocked +
  • Locks or unlocks the user
  • +
    Password +
  • Password that employee users to log in to the Intelex system.
  • +
  • Ignores Account Policy rules.
  • +
  • Password is not required if implementing SSO.
  • +
    SecondaryPassword +
  • For Electronic Signatures only.
  • +
  • Stores a secondary password that can be used by electronic signatures.
  • +
    ForcePasswordChange +
  • If set to true, user will be forced to change his/her password upon his/her next successful log in.
  • +
  • User access updated through EDIS will leave Force Password Change untouched if it the flag is anything other than the characters mentioned above.
  • +
  • 1 = User will be forced to change his/her password on next log in (also accepts values "Y", "y", "T", "t").
  • +
  • 0 (or null) = User will NOT be forced to change his/her password (also accepts values "N", "n", "F", "f").
  • +
    LoginLocationCode* +
  • Location Code of the login location of this employee.
  • +
  • This is the Logon Location field on the user profile.
  • +
    TimeZone +
  • Time Zone for the User.
  • +
  • Example: (UTC-05:00) Eastern Time (US & Canada)
  • +
    LicenseType* +
  • Identifies specific V6 license type assigned in License Type field in user profile.
  • +
  • Valid values are:
  • +
      +
    • Concurrent Access
    • +
    • Full Access
    • +
    • System Administrator
    • +
    +
    CultureName +
  • For clients who have purchased additional languages.
  • +
  • Identifies culture assigned in Culture field in user profile.
  • +
  • "Automatic" will set to "Determine Automatically".
  • +
  • Inactive cultures won't be assigned to a user.
  • +
    LongDate +
  • d, dd = day; ddd, dddd = day of week; M, MM = month; yy, yyyy = year
  • +
    LongTime +
  • h, hh = hour (12-hour format); H, HH = hour (24-hour format); m = minutes; s = seconds; tt = A.M. or P.M.
  • +
    ShortDate +
  • d, dd = day; ddd, dddd = day of week; M, MM = month; yy, yyyy = year
  • +
    ShortTime +
  • h, hh = hour (12-hour format); H, HH = hour (24-hour format); m = minutes; s = seconds; tt = A.M. or P.M.
  • +
    + +> Example Request Body + +```json +{ + "SendEmail": true, + "IgnoreUserAccess": false, + + "Flag": "A", + "EmployeeNumber": "001", + "HomeLocationCode": "001", + "Prefix": "Mr.", + "FirstName": "John", + "LastName": "Doe", + "MiddleName": "Joe", + "DisplayName": "John Doe", + "Suffix": "III", + "Email": "john.doe@intelex.com", + "IsSupervisor": "Y", + "EmployeeType": "Hourly", + "DateOfHire": "2019-11-25", + "SupervisorNumber": "001", + "PositionTitle": "Line Worker", + "Notes": "Notes for me", + "Contractor": "Y", + "Company": "Intelex", + "ContractorName": "Contractor Name", + "ContractExpiry": "2026-12-30", + "InsuranceExpiry": "2026-12-31", + "ContractorNotes": "Notes for the Contractor", + "StreetAddress": "70 University Ave #800", + "City": "Toronto", + "State": "Ontario", + "ZipCode": "M5J 2M4", + "Gender": "M", + "DateOfBirth": "1999-06-23", + "SSN": "111-11-1111", + "EmergencyContact": "Jane Doe", + "EmergencyPhone": "123-456-7890", + "PersonResponsible": 1, + "PhoneNumber": "111-111-1111", + "HourlyWage": "25", + "JobCode": "jc12", + "WorkStatus": "full time", + + "UserId": "jdoe", + "IsLocked": false, + "Password": "1234", + "SecondaryPassword": "5678", + "ForcePasswordChange": false, + "LoginLocationCode": "001", + "TimeZone": "Eastern Standard Time", + "LicenseType": "Full Access", + "CultureName": "English (United States)", + "LongDate": "dddd, MMMM dd, yyyy", + "LongTime": "h:mm:ss tt", + "ShortDate": "M/d/yyyy", + "ShortTime": "h:mm tt", + + "Groups": "Claims Administrator(01E4C606-2F03-4044-B6B1-079AE288D82A);7F50AC4D-93F4-4DF9-90AF-00D7DF663720" +} +``` + +### Payload Validation + +Fields in the payload will be checked for validity before creating or updating the employee and user records. + +#### Create (POST) Payload Validation + +Example payload validations for creation include: + +
      +
    • Required fields that are not included in the payload
    • +
    • Invalid external identifiers that do not exist (E.g. SupervisorNumber, LoginLocationCode)
    • +
    • Duplicate primary key identifiers (E.g. EmployeeNumber, DisplayName)
    • +
    + +#### Update (PATCH) Payload Validation + +Example payload validations for modification include: + +
      +
    • Required identifier fields (Id, EmployeeNumber) not included in the request
    • +
    • Required fields that are empty ("") in the payload
    • +
    • Invalid external identifiers that do not exist (E.g. SupervisorNumber, LoginLocationCode)
    • +
    • Duplicate primary key identifiers (E.g. EmployeeNumber, DisplayName)
    • +
    + +> Example Response With Validation Errors + +```json +{ + "error": { + "messages": [ + "Cannot create employee - Invalid value for IsSupervisor. Please use either 'Y' or 'N'", + "There is an existing employee with the same employee number.", + "Home location with code 001 is not found." + ] + } +} +``` + +### Group Membership + +Group membership for an employee may also be managed via the User Management API with use of the Groups field. The Groups field expects a semi-colon delimited list of groups in one of the following formats: +
      +
    • GroupId
    • +
    • GroupName
    • +
    • RoleId(LocationId) (for a Location Role)
    • +
    • RoleId(LocationCode) (for a Location Role)
    • +
    • RoleName(LocationId) (for a Location Role)
    • +
    • RoleName(LocationCode) (for a Location Role)
    • +
    + +"Groups" include Security Groups, Roles, Location Roles and Training Workgroups, or any object that inherits from the Group Entity. + +#### Roles and Location Roles + +If an entry is a role and no location is defined for the entry (E.g. As RoleId(LocationId)), a location role will be assigned using the LoginLocationCode value. If LoginLocationCode is invalid or not present in the payload, the Role will be assigned without a location. + +Roles with AllowManySubjects set to false will unassign any existing members from the role before assigning membership to the target employee. + +#### Group Membership Settings + +See [Settings Flags](#settings-flags) for details on DoNotAddGroupAssignments and RemoveFromUnlistedGroups fields. + +#### Group Validation + +Groups are validated before membership is assigned. If any validations fail, error messages will be returned in the response. + +Example group validations include: +
      +
    • Group Id or Name does not exist.
    • +
    • Group for a LocationRole (GroupId(LocationId), in this case GroupId) does not exist.
    • +
    • Group Id or Name for a location role (Role(Location)), is not a Role. E.g. If you try to use the ID of a SysSecurityGroup as a role in a location role, the parsing will fail.
    • +
    • Location code does not exist or is invalid.
    • +
    + +> Example Groups Payload + +```json +{ + "Groups": "7F50AC4D-93F4-4DF9-90AF-00D7DF663720;Insurance;36D48405-36EA-42C8-B11B-CA50DAB377DD(01E4C606-2F03-4044-B6B1-079AE288D82A);BD5797DD-D015-429C-89E6-1A79C3EB7B79(056);Claims Administrator(01E4C606-2F03-4044-B6B1-079AE288D82A);Claims Administrator(001)" +} +``` + +> Example Response With Group Validation Errors + +```json +{ + "error": { + "messages": [ + "The Location Role 'Role123(Loc123)' is invalid. Please ensure that the Role (Role123) is the Name or ID of a valid and existing Role.", + "Group '36D48405-36EA-42C8-B11B-CA50DAB377DD' is invalid. Group with ID '36D48405-36EA-42C8-B11B-CA50DAB377DD' does not exist.", + "Group 'Role456(Loc456)' is invalid. Location with Code 'Loc456' is archived or does not exist." + ] + } +} +``` \ No newline at end of file diff --git a/source/index.html.md b/source/index.html.md new file mode 100644 index 00000000000..cedab96fd17 --- /dev/null +++ b/source/index.html.md @@ -0,0 +1,23 @@ +--- +title: Intelex API Reference + +language_tabs: + - javascript: JavaScript + - csharp: C# + +includes: + - api-reference + - object-data-api + - task-api + - user-mgmt-api + - user-mgmt/get-api + - user-mgmt/post-patch-api + - acts-api + - acts/reference + - acts/get_api + - acts/post_api + - acts/delete_api + - dev-support + +search: true +--- diff --git a/source/index.md b/source/index.md deleted file mode 100644 index 4c1fa8c9f7d..00000000000 --- a/source/index.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: API Reference - -language_tabs: - - shell - - ruby - - python - -toc_footers: - - Sign Up for a Developer Key - - Documentation Powered by Slate - -includes: - - errors - -search: true ---- - -# Introduction - -Welcome to the Kittn API! You can use our API to access Kittn API endpoints, which can get information on various cats, kittens, and breeds in our database. - -We have language bindings in Shell, Ruby, and Python! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. - -This example API documentation page was created with [Slate](http://github.com/tripit/slate). Feel free to edit it and use it as a base for your own API's documentation. - -# Authentication - -> To authorize, use this code: - -```ruby -require 'kittn' - -api = Kittn::APIClient.authorize!('meowmeowmeow') -``` - -```python -import kittn - -api = kittn.authorize('meowmeowmeow') -``` - -```shell -# With shell, you can just pass the correct header with each request -curl "api_endpoint_here" - -H "Authorization: meowmeowmeow" -``` - -> Make sure to replace `meowmeowmeow` with your API key. - -Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](http://example.com/developers). - -Kittn expects for the API key to be included in all API requests to the server in a header that looks like the following: - -`Authorization: meowmeowmeow` - - - -# Kittens - -## Get All Kittens - -```ruby -require 'kittn' - -api = Kittn::APIClient.authorize!('meowmeowmeow') -api.kittens.get -``` - -```python -import kittn - -api = kittn.authorize('meowmeowmeow') -api.kittens.get() -``` - -```shell -curl "http://example.com/api/kittens" - -H "Authorization: meowmeowmeow" -``` - -> The above command returns JSON structured like this: - -```json -[ - { - "id": 1, - "name": "Fluffums", - "breed": "calico", - "fluffiness": 6, - "cuteness": 7 - }, - { - "id": 2, - "name": "Isis", - "breed": "unknown", - "fluffiness": 5, - "cuteness": 10 - } -] -``` - -This endpoint retrieves all kittens. - -### HTTP Request - -`GET http://example.com/api/kittens` - -### Query Parameters - -Parameter | Default | Description ---------- | ------- | ----------- -include_cats | false | If set to true, the result will also include cats. -available | true | If set to false, the result will include kittens that have already been adopted. - - - -## Get a Specific Kitten - -```ruby -require 'kittn' - -api = Kittn::APIClient.authorize!('meowmeowmeow') -api.kittens.get(2) -``` - -```python -import kittn - -api = kittn.authorize('meowmeowmeow') -api.kittens.get(2) -``` - -```shell -curl "http://example.com/api/kittens/2" - -H "Authorization: meowmeowmeow" -``` - -> The above command returns JSON structured like this: - -```json -{ - "id": 2, - "name": "Isis", - "breed": "unknown", - "fluffiness": 5, - "cuteness": 10 -} -``` - -This endpoint retrieves a specific kitten. - - - -### HTTP Request - -`GET http://example.com/kittens/` - -### URL Parameters - -Parameter | Description ---------- | ----------- -ID | The ID of the kitten to retrieve - diff --git a/source/javascripts/app/_lang.js b/source/javascripts/app/_lang.js index 1a124bb68ae..992180b7690 100644 --- a/source/javascripts/app/_lang.js +++ b/source/javascripts/app/_lang.js @@ -1,3 +1,5 @@ +//= require ../lib/_jquery + /* Copyright 2008-2013 Concur Technologies, Inc. @@ -28,9 +30,11 @@ under the License. $(".lang-selector a").removeClass('active'); $(".lang-selector a[data-language-name='" + language + "']").addClass('active'); for (var i=0; i < languages.length; i++) { - $(".highlight." + languages[i]).hide(); + $(".highlight.tab-" + languages[i]).hide(); + $(".lang-specific." + languages[i]).hide(); } - $(".highlight." + language).show(); + $(".highlight.tab-" + language).show(); + $(".lang-specific." + language).show(); global.toc.calculateHeights(); diff --git a/source/javascripts/app/_search.js b/source/javascripts/app/_search.js index 91f38a04edf..5ace538d887 100644 --- a/source/javascripts/app/_search.js +++ b/source/javascripts/app/_search.js @@ -1,4 +1,5 @@ //= require ../lib/_lunr +//= require ../lib/_jquery //= require ../lib/_jquery.highlight (function () { 'use strict'; diff --git a/source/javascripts/app/_toc.js b/source/javascripts/app/_toc.js index d84bf8e197a..a54c5f82360 100644 --- a/source/javascripts/app/_toc.js +++ b/source/javascripts/app/_toc.js @@ -1,5 +1,7 @@ +//= require ../lib/_jquery //= require ../lib/_jquery_ui //= require ../lib/_jquery.tocify +//= require ../lib/_imagesloaded.min (function (global) { 'use strict'; @@ -10,7 +12,7 @@ var makeToc = function() { global.toc = $("#toc").tocify({ - selectors: 'h1, h2', + selectors: 'h1, h2, h3', extendPage: false, theme: 'none', smoothScroll: false, @@ -37,14 +39,19 @@ // Hack to make already open sections to start opened, // instead of displaying an ugly animation - function animate () { + function animate() { setTimeout(function() { toc.setOption('showEffectSpeed', 180); }, 50); } - $(makeToc); - $(animate); - + $(function() { + makeToc(); + animate(); + setupLanguages($('body').data('languages')); + $('.content').imagesLoaded( function() { + global.toc.calculateHeights(); + }); + }); })(window); diff --git a/source/javascripts/lib/_imagesloaded.min.js b/source/javascripts/lib/_imagesloaded.min.js new file mode 100644 index 00000000000..d66f658937d --- /dev/null +++ b/source/javascripts/lib/_imagesloaded.min.js @@ -0,0 +1,7 @@ +/*! + * imagesLoaded PACKAGED v3.1.8 + * JavaScript is all like "You images are done yet or what?" + * MIT License + */ + +(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s}); \ No newline at end of file diff --git a/source/javascripts/lib/_jquery.js b/source/javascripts/lib/_jquery.js new file mode 100644 index 00000000000..b78120e6a1c --- /dev/null +++ b/source/javascripts/lib/_jquery.js @@ -0,0 +1,9831 @@ +/*! + * jQuery JavaScript Library v2.2.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-08T20:02Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +//"use strict"; +var arr = []; + +var document = window.document; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "2.2.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + }, + + isPlainObject: function( obj ) { + + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android<4.0, iOS<6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf( "use strict" ) === 1 ) { + script = document.createElement( "script" ); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE9-11+ + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +// JSHint would error on this code due to the Symbol not being defined in ES5. +// Defining this global in .jshintrc would create a danger of using the global +// unguarded in another place, it seems safer to just disable JSHint for these +// three lines. +/* jshint ignore: start */ +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} +/* jshint ignore: end */ + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.1 + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-10-17 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + return m ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + } ); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + // Support: Blackberry 4.6 + // gEBID returns nodes no longer in the document (#6963) + if ( elem && elem.parentNode ) { + + // Inject the element directly into the jQuery object + this.length = 1; + this[ 0 ] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( pos ? + pos.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnotwhite = ( /\S+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ) ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( function() { + + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. + // If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // Add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .progress( updateFunc( i, progressContexts, progressValues ) ) + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ); + } else { + --remaining; + } + } + } + + // If we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +} ); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +} ); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE9-10 only + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[ 0 ], key ) : emptyGet; +}; +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + register: function( owner, initial ) { + var value = initial || {}; + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable, non-writable property + // configurability must be true to allow the property to be + // deleted with the delete operator + } else { + Object.defineProperty( owner, this.expando, { + value: value, + writable: true, + configurable: true + } ); + } + return owner[ this.expando ]; + }, + cache: function( owner ) { + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( !acceptData( owner ) ) { + return {}; + } + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + owner[ this.expando ] && owner[ this.expando ][ key ]; + }, + access: function( owner, key, value ) { + var stored; + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase( key ) ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key === undefined ) { + this.register( owner ); + + } else { + + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <= 35-45+ + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data, camelKey; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // with the key as-is + data = dataUser.get( elem, key ) || + + // Try to find dashed key if it exists (gh-2779) + // This is for 2.2.x only + dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() ); + + if ( data !== undefined ) { + return data; + } + + camelKey = jQuery.camelCase( key ); + + // Attempt to get data from the cache + // with the key camelized + data = dataUser.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + camelKey = jQuery.camelCase( key ); + this.each( function() { + + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = dataUser.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + dataUser.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf( "-" ) > -1 && data !== undefined ) { + dataUser.set( this, key, value ); + } + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || + !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([\w:-]+)/ ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE9 + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE9-11+ + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0-4.3, Safari<=5.1 + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari<=5.1, Android<4.2 + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<=11+ + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE9 +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Support (at least): Chrome, IE9 + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push( { elem: cur, handlers: matches } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split( " " ), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " + + "screenX screenY toElement" ).split( " " ), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - + ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - + ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome<28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android<4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://code.google.com/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +function manipulationTarget( elem, content ) { + if ( jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <= 35-45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); + + +var iframe, + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ + +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + display = jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = ( iframe || jQuery( "