diff --git a/.bowerrc b/.bowerrc index 6f66a8895..7b707d10a 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,6 +1,7 @@ { + "directory": "public/bower_components", "scripts": { - "postinstall": "grunt", - "postuninstall": "grunt" + "postinstall": "grunt default genlicense", + "postuninstall": "grunt default genlicense" } } diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..6ce330c74 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +node_modules +tmp +application/config/email.php +application/config/database.php +*.patch +patches/ +.idea/ +git-svn-diff.py +*.bash +.swp +.buildpath +.project +.settings/* +*.swp +*.rej +*.orig +*~ +*.~ +*.log +application/sessions/* diff --git a/.gitattributes b/.gitattributes index 32d68b41c..b89b92b39 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,5 @@ dist/ merge=ours application/language/**/*.php merge=ours text=auto +application/config/config.php ident +application/views/partial/footer.php ident diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..5724e9d51 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,37 @@ +### IMPORTANT IMPORTANT IMPORTANT + +Chose what you want to report: New Feature or Bug. +If you remove the template when submitting a Bug your issue will be closed as we cannot help without basic information. + + +### New Feature / Enhacement + +For New Features or Enhacements please remove all the template text and clearly write your proposal. +It's important to state whether you expect the community to implement it or you will contribute the work. +Please bear in mind that we will implement new features only on the current code, there is no support for old versions. + + +### Issue / Question / Bug + +Before submitting an issue please make sure you remove the first section of the template and you tick (add a x between the square brakets) and agree with all the following check boxes: + +- [] Checked the current issues database and no similar issue was already discussed +- [] Read the README, WHATS_NEW and UPGRADE +- [] Read the FAQ (https://github.com/jekkos/opensourcepos#faq) for any known install and/or upgrade gotchas (in specific PHP has php5-gd, php-intl and sockets installed) +- [] Reporting an issue of an unmodified OSPOS installation +- [] PHP version is at least 5.5 and not 7.x +- [] MySQL version is 5.5 or 5.6 and not 5.7 +- [] Ran any database upgrade scripts (e.g. database/2.4_to_3.0.sql) +- [] Know the version of OSPOS and git commit hash (check the footer of your OSPOS) and will add to my issue report +- [] Know the name and version of OS, Web server and MySQL and will add to my issue report + +### Installation information + + +### Expected behaviour + + +### Actual behaviour + + +### Steps to reproduce the issue \ No newline at end of file diff --git a/.gitignore b/.gitignore index 544c9b50c..2060815f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ node_modules -bower_components tmp application/config/email.php application/config/database.php +application/sessions/* +application/logs/* +application/uploads/* +public/license/.licenses +public/bower_components *.patch patches/ .idea/ @@ -18,4 +22,3 @@ git-svn-diff.py *~ *.~ *.log -application/sessions/* diff --git a/.htaccess b/.htaccess index 9ebf33bfe..e824912de 100755 --- a/.htaccess +++ b/.htaccess @@ -1,50 +1,60 @@ -RewriteEngine On - -# Option 2: To rewrite "domain.com -> www.domain.com" uncomment the following lines. -# RewriteCond %{HTTPS} !=on -# RewriteCond %{HTTP_HOST} !^www\..+$ [NC] -# RewriteCond %{HTTP_HOST} (.+)$ [NC] -# RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L] - -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule ^(.*)$ index.php?/$1 [L] - # disable directory browsing # For security reasons, Option all cannot be overridden. -#Options All -Indexes Options +ExecCGI +Includes +IncludesNOEXEC +SymLinksIfOwnerMatch -Indexes # prevent folder listing IndexIgnore * -# secure htaccess file - - order allow,deny - deny from all - +# Apache 2.4 + + # secure htaccess file + + Require all denied + -# prevent access to PHP error log - - order allow,deny - deny from all - satisfy All - + # prevent access to PHP error log + + Require all denied + -# prevent access to generate_languages.php - - order deny,allow - deny from all - allow from 127.0.0.1 - -# My IP(s) -# allow from xxx.xxx.xxx.xxx + # prevent access to LICENSE + + Require all denied + - - - - - ExpiresActive On - ExpiresDefault "access plus 1 week" - + # prevent access to csv, txt and md files + + Require all denied + + + +# Apache 2.2 + + # secure htaccess file + + Order allow,deny + Deny from all + Satisfy all + + + # prevent access to PHP error log + + Order allow,deny + Deny from all + Satisfy all + + + # prevent access to LICENSE + + Order allow,deny + Deny from all + Satisfy all + + + # prevent access to csv, txt and md files + + Order allow,deny + Deny from all + Satisfy all + diff --git a/.travis.yml b/.travis.yml index 7a5999869..34b15172f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,19 @@ -sudo: false +sudo: true # Required to install packages -language: node_js +branches: + except: + - weblate -node_js: - - "4.1" - -services: +services: - docker - before_install: - - docker build -t jekkos/opensourcepos . - - docker run -d jekkos/opensourcepos - + - curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin script: - - docker exec -t -i $(docker ps | tail -n 1 | cut -d' ' -f1) /bin/sh -c "while ! curl http://localhost/index.php | grep username; do sleep 1; done; cd app && grunt mochaWebdriver:test" - + - docker-compose build +env: + - TAG=$(echo ${TRAVIS_BRANCH} | sed s/feature\\///) after_success: - - docker login -e="$DOCKER_EMAIL" -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - - docker push jekkos/opensourcepos + - '[ -n ${DOCKER_USERNAME} ] && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" && docker tag opensourcepos_php "jekkos/opensourcepos:$TAG" && docker tag opensourcepos_sqlscript jekkos/opensourcepos:sqlscript && docker push "jekkos/opensourcepos:$TAG" && docker push jekkos/opensourcepos:sqlscript' + diff --git a/Dockerfile b/Dockerfile index 157627df3..d536ef467 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,24 @@ -FROM ubuntu:utopic +FROM php:5-apache MAINTAINER jekkos -RUN sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list -RUN apt-get update -RUN apt-get -y upgrade -RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-client mysql-server apache2 libapache2-mod-php5 pwgen python-setuptools vim-tiny php5-mysql php5-gd php5-apcu nodejs npm curl -RUN easy_install supervisor -ADD ./docker/foreground.sh /etc/apache2/foreground.sh -ADD ./docker/supervisord.conf /etc/supervisord.conf -RUN chmod 755 /etc/apache2/foreground.sh -# Install dependencies -RUN apt-get install -y --no-install-recommends software-properties-common -RUN apt-get install -y python git +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + php5-apcu \ + libicu-dev \ + libgd-dev \ + libmcrypt-dev -# Get latest Ospos source from Git -ADD . /app -RUN ln -s /usr/bin/nodejs /usr/bin/node -RUN cd app && npm install -RUN npm install -g grunt-cli -RUN ln -s /usr/local/bin/grunt /usr/bin/grunt +RUN a2enmod rewrite +RUN docker-php-ext-install mysql mysqli bcmath intl gd sockets mbstring mcrypt +RUN echo "date.timezone = \"\${PHP_TIMEZONE}\"" > /usr/local/etc/php/conf.d/timezone.ini +RUN echo -e “$(hostname -i)\t$(hostname) $(hostname).localhost†>> /etc/hosts -RUN ln -fs /app/* /var/www/html -ADD ./docker/start_container.sh /start_container.sh -RUN chmod 755 /start_container.sh -EXPOSE 80 3306 -CMD ["/bin/bash", "/start_container.sh"] +WORKDIR /app +COPY . /app +RUN ln -s /app/*[^public] /var/www && rm -rf /var/www/html && ln -nsf /app/public /var/www/html +RUN chmod 755 /app/public/uploads && chown -R www-data:www-data /app/public/uploads + +RUN cp application/config/database.php.tmpl application/config/database.php && \ + sed -i -e "s/\(localhost\)/web/g" test/ospos.js && \ + sed -i -e "s/\(user.*\?=.\).*\(.\)$/\1getenv('MYSQL_USERNAME')\2/g" application/config/database.php && \ + sed -i -e "s/\(password.*\?=.\).*\(.\)$/\1getenv('MYSQL_PASSWORD')\2/g" application/config/database.php && \ + sed -i -e "s/\(database.*\?=.\).*\(.\)$/\1getenv('MYSQL_DB_NAME')\2/g" application/config/database.php && \ + sed -i -e "s/\(hostname.*\?=.\).*\(.\)$/\1getenv('MYSQL_HOST_NAME')\2/g" application/config/database.php diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 000000000..9d09afd74 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,9 @@ +FROM jekkos/opensourcepos:master +MAINTAINER jekkos + +RUN mkdir -p /app/bower_components && ln -s /app/bower_components /var/www/html/bower_components +RUN yes | pecl install xdebug \ + && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \ + && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \ + && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini + diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 000000000..93b72144e --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,11 @@ +FROM digitallyseamless/nodejs-bower-grunt:5 +MAINTAINER jekkos + +# apt-get install curl + +COPY Gruntfile.js . +COPY package.json . +COPY test . +RUN npm install + +CMD ['while ! curl web/index.php | grep username; do sleep 1; done; grunt mochaWebdriver:test'] diff --git a/Gruntfile.js b/Gruntfile.js index 1a7902504..8f2542def 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,201 +1,229 @@ module.exports = function(grunt) { grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - wiredep: { - task: { - ignorePath: '../../../', - src: ['application/views/partial/header.php'] - } - }, - wiredep_templates: { - task: { - ignorePath: '../../../../', - src: ['templates/*/views/partial/header.php'] - } - }, - bower_concat: { - all: { - mainFiles: { - 'bootswatch-dist': ['bootstrap/dist/js/bootstrap.js'], - 'bootstrap-table': [ "src/bootstrap-table.js", "src/bootstrap-table.css", "dist/extensions/export/bootstrap-table-export.js"] - }, - dest: { - 'js': 'tmp/opensourcepos_bower.js', - 'css': 'tmp/opensourcepos_bower.css' - } - } - }, - bowercopy: { + pkg: grunt.file.readJSON('package.json'), + wiredep: { + task: { + ignorePath: '../../../public/', + src: ['application/views/partial/header.php'] + } + }, + bower_concat: { + all: { + mainFiles: { + 'bootstrap-table': [ "src/bootstrap-table.js", "src/bootstrap-table.css", "dist/extensions/export/bootstrap-table-export.js", "dist/extensions/mobile/bootstrap-table-mobile.js"] + }, + dest: { + 'js': 'tmp/opensourcepos_bower.js', + 'css': 'tmp/opensourcepos_bower.css' + } + } + }, + bowercopy: { options: { - // Bower components folder will be removed afterwards - // clean: true + report: false }, - targetdist: { + targetdistbootswatch: { options: { - destPrefix: 'dist' + srcPrefix: 'public/bower_components/bootswatch', + destPrefix: 'public/dist/bootswatch' }, files: { - 'jquery-ui.css': 'jquery-ui/themes/base/jquery-ui.css', - 'bootstrap.min.css': 'bootswatch-dist/css/bootstrap.min.css' + 'cerulean/bootstrap.min.css': 'cerulean/bootstrap.min.css', + 'cosmo/bootstrap.min.css': 'cosmo/bootstrap.min.css', + 'cyborg/bootstrap.min.css': 'cyborg/bootstrap.min.css', + 'darkly/bootstrap.min.css': 'darkly/bootstrap.min.css', + 'flatly/bootstrap.min.css': 'flatly/bootstrap.min.css', + 'journal/bootstrap.min.css': 'journal/bootstrap.min.css', + 'paper/bootstrap.min.css': 'paper/bootstrap.min.css', + 'readable/bootstrap.min.css': 'readable/bootstrap.min.css', + 'sandstone/bootstrap.min.css': 'sandstone/bootstrap.min.css', + 'slate/bootstrap.min.css': 'slate/bootstrap.min.css', + 'spacelab/bootstrap.min.css': 'spacelab/bootstrap.min.css', + 'superhero/bootstrap.min.css': 'superhero/bootstrap.min.css', + 'united/bootstrap.min.css': 'united/bootstrap.min.css', + 'yeti/bootstrap.min.css': 'yeti/bootstrap.min.css', + 'fonts': 'fonts' } - }/*, - targettmp: { + }, + targetlicense: { options: { - destPrefix: 'tmp' + srcPrefix: './' }, files: { - // add here anything that should be copied in a tmp directory + 'public/license': 'LICENSE' } - }*/ - }, - cssmin: { - target: { - files: { - 'dist/<%= pkg.name %>.min.css': ['tmp/opensourcepos_bower.css', 'css/*.css', '!css/login.css', '!css/invoice_email.css'] - } - } - }, - concat: { - js: { - options: { - separator: ';' - }, - files: { - 'dist/<%= pkg.name %>.js': ['tmp/opensourcepos_bower.js', 'js/jquery*', 'js/*.js'] - } - }, - sql: { - options: { - banner: '-- >> This file is autogenerated from tables.sql and constraints.sql. Do not modify directly << --' - }, - files: { - 'database/database.sql': ['database/tables.sql', 'database/constraints.sql'], - 'database/migrate_phppos_dist.sql': ['database/tables.sql', 'database/phppos_migrate.sql', 'database/constraints.sql'] - } - } - }, - uglify: { - options: { - banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' - }, - dist: { - files: { - 'dist/<%= pkg.name %>.min.js': ['dist/<%= pkg.name %>.js'] - } - } - }, - jshint: { - files: ['Gruntfile.js', 'js/*.js'], - options: { - // options here to override JSHint defaults - globals: { - jQuery: true, - console: true, - module: true, - document: true - } - } - }, - tags: { - css_header: { - options: { - scriptTemplate: '', - openTag: '', - closeTag: '', - absolutePath: true - }, - src: ['css/*.css', '!css/login.css', '!css/invoice_email.css'], - dest: 'application/views/partial/header.php', - dest: 'templates/spacelab/views/partial/header.php' - }, - mincss_header: { - options: { - scriptTemplate: '', - openTag: '', - closeTag: '', - absolutePath: true - }, - src: ['dist/*.css'], - dest: 'application/views/partial/header.php', - }, - mincss_header_templates: { - options: { - scriptTemplate: '', - openTag: '', - closeTag: '', - absolutePath: true - }, - src: ['dist/*.css', '!dist/bootstrap.min.css'], - dest: 'templates/spacelab/views/partial/header.php' - }, - css_login: { - options: { - scriptTemplate: '', - openTag: '', - closeTag: '', - absolutePath: true - }, - src: ['dist/bootstrap.min.css', 'css/login.css'], - dest: 'application/views/login.php' - }, - js: { - options: { - scriptTemplate: '', - openTag: '', - closeTag: '', - absolutePath: true - }, - src: ['js/jquery*', 'js/*.js'], - dest: 'application/views/partial/header.php' - }, - minjs: { - options: { - scriptTemplate: '', - openTag: '', - closeTag: '', - absolutePath: true - }, - src: ['dist/*min.js'], - dest: 'application/views/partial/header.php' - } - }, - mochaWebdriver: { - options: { - timeout: 1000 * 60 * 3 - }, - test : { - options: { - usePhantom: true, - usePromises: true - }, - src: ['test/**/*.js'] - } - }, - watch: { - files: ['<%= jshint.files %>'], - tasks: ['jshint'] - }, - cachebreaker: { - dev: { - options: { - match: [ { - 'opensourcepos.min.js': 'dist/opensourcepos.min.js', - 'opensourcepos.min.css': 'dist/opensourcepos.min.css', - 'bootstrap.min.css': 'dist/bootstrap.min.css' - } ], - replacement: 'md5' - }, - files: { - src: ['**/header.php', '**/login.php'] - } - } - } + }, + }, + cssmin: { + target: { + files: { + 'public/dist/<%= pkg.name %>.min.css': ['tmp/opensourcepos_bower.css', 'public/css/*.css', '!public/css/login.css', '!public/css/invoice_email.css', '!public/css/barcode_font.css', '!public/css/style.css'] + } + } + }, + concat: { + js: { + options: { + separator: ';' + }, + files: { + 'tmp/<%= pkg.name %>.js': ['tmp/opensourcepos_bower.js', 'public/js/jquery*', 'public/js/*.js'] + } + }, + sql: { + options: { + banner: '-- >> This file is autogenerated from tables.sql and constraints.sql. Do not modify directly << --' + }, + files: { + 'database/database.sql': ['database/tables.sql', 'database/constraints.sql'], + 'database/migrate_phppos_dist.sql': ['database/tables.sql', 'database/phppos_migrate.sql', 'database/constraints.sql'] + } + } + }, + uglify: { + options: { + banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' + }, + dist: { + files: { + 'public/dist/<%= pkg.name %>.min.js': ['tmp/<%= pkg.name %>.js'] + } + } + }, + jshint: { + files: ['Gruntfile.js', 'public/js/*.js'], + options: { + // options here to override JSHint defaults + globals: { + jQuery: true, + console: true, + module: true, + document: true + } + } + }, + tags: { + css_header: { + options: { + scriptTemplate: '', + openTag: '', + closeTag: '', + ignorePath: '../../../public/' + }, + src: ['public/css/*.css', '!public/css/login.css', '!public/css/invoice_email.css', '!public/css/barcode_font.css'], + dest: 'application/views/partial/header.php', + }, + mincss_header: { + options: { + scriptTemplate: '', + openTag: '', + closeTag: '', + ignorePath: '../../../public/' + }, + src: ['public/dist/*.css', '!public/dist/login.css', '!public/dist/invoice_email.css', '!public/dist/barcode_font.css'], + dest: 'application/views/partial/header.php', + }, + css_login: { + options: { + scriptTemplate: '', + openTag: '', + closeTag: '', + ignorePath: '../../public/' + }, + src: ['public/dist/login.css'], + dest: 'application/views/login.php' + }, + js: { + options: { + scriptTemplate: '', + openTag: '', + closeTag: '', + ignorePath: '../../../public/' + }, + src: ['public/js/jquery*', 'public/js/*.js'], + dest: 'application/views/partial/header.php' + }, + minjs: { + options: { + scriptTemplate: '', + openTag: '', + closeTag: '', + ignorePath: '../../../public/' + }, + src: ['public/dist/*min.js'], + dest: 'application/views/partial/header.php' + } + }, + mochaWebdriver: { + options: { + timeout: 1000 * 60 * 3 + }, + test : { + options: { + usePhantom: true, + usePromises: true + }, + src: ['test/**/*.js'] + } + }, + watch: { + files: ['<%= jshint.files %>'], + tasks: ['jshint'] + }, + cachebreaker: { + dev: { + options: { + match: [ { + 'opensourcepos.min.js': 'public/dist/opensourcepos.min.js', + 'opensourcepos.min.css': 'public/dist/opensourcepos.min.css' + } ], + replacement: 'md5' + }, + files: { + src: ['application/views/partial/header.php', 'application/views/login.php'] + } + } + }, + clean: { + license: ['public/bower_components/**/bower.json'] + }, + license: { + all: { + // Target-specific file lists and/or options go here. + options: { + // Target-specific options go here. + directory: 'public/bower_components', + output: 'public/license/bower.LICENSES' + }, + }, + }, + 'bower-licensechecker': { + options: { + /*directory: 'path/to/bower',*/ + acceptable: [ 'MIT', 'BSD', 'LICENSE.md' ], + printTotal: true, + warn: { + nonBower: true, + noLicense: true, + allGood: true, + noGood: true + }, + log: { + outFile: 'public/license/.licenses', + nonBower: true, + noLicense: true, + allGood: true, + noGood: true, + } + } + } }); require('load-grunt-tasks')(grunt); grunt.loadNpmTasks('grunt-mocha-webdriver'); grunt.registerTask('default', ['wiredep', 'bower_concat', 'bowercopy', 'concat', 'uglify', 'cssmin', 'tags', 'cachebreaker']); + grunt.registerTask('genlicense', ['clean:license', 'license', 'bower-licensechecker']); }; diff --git a/COPYING b/LICENSE similarity index 75% rename from COPYING rename to LICENSE index afe147953..bfcec65eb 100644 --- a/COPYING +++ b/LICENSE @@ -5,11 +5,12 @@ Copyright (c) 2012 Alain Copyright (c) 2013 Rob Garrison Copyright (c) 2013 Parq Copyright (c) 2013 Ramel -Copyright (c) 2014-2016 jekkos -Copyright (c) 2015-2016 FrancescoUK (aka daN4cat) +Copyright (c) 2013-2017 jekkos +Copyright (c) 2015-2017 FrancescoUK (aka daN4cat) Copyright (c) 2015 Aamir Shahzad (aka asakpke), RoshanTech.com Copyright (c) 2015 Toni Haryanto (aka yllumi) Copyright (c) 2016 Ramkrishna Mondal (aka RamkrishnaMondal) +Copyright (c) 2016 Rinaldy@dbarber (aka rnld26) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -21,9 +22,15 @@ subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +You cannot claim copyright or ownership of the Software. + +Footer signatures "You are using Open Source Point Of Sale" and/or "Open Source Point Of Sale" +with version, hash and URL link to the original distribution of the code MUST BE RETAINED, +MUST BE VISIBLE IN EVERY PAGE and CANNOT BE MODIFIED. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index c2329ee48..a6ced3c2d 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,62 @@ +[![Build Status](https://travis-ci.org/jekkos/opensourcepos.svg?branch=master)](https://travis-ci.org/jekkos/opensourcepos) +[![Join the chat at https://gitter.im/jekkos/opensourcepos](https://badges.gitter.im/jekkos/opensourcepos.svg)](https://gitter.im/jekkos/opensourcepos?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![devDependency Status](https://david-dm.org/jekkos/opensourcepos/dev-status.svg)](https://david-dm.org/jekkos/opensourcepos#info=devDependencie) +[![Dependency Status](https://gemnasium.com/badges/github.com/jekkos/opensourcepos.svg)](https://gemnasium.com/github.com/jekkos/opensourcepos) +[![GitHub version](https://badge.fury.io/gh/jekkos%2Fopensourcepos.svg)](https://badge.fury.io/gh/jekkos%2Fopensourcepos) +[![Translation status](http://weblate.jpeelaer.net/widgets/ospos/-/svg-badge.svg)](http://weblate.jpeelaer.net/engage/ospos/?utm_source=widget) + Introduction ------------ -Open Source Point of Sale is a web based point of sale system written in the PHP language. -It uses MySQL as the data storage back-end and has a simple user interface. +Open Source Point of Sale is a web based point of sale system. +The main features are: +* Stock management +* Sale register with transactions logging +* Receipt and invoice printing and emailing +* Suppliers and Customers database +* Multiuser with permission control +* Reporting +* Gift card +* Receivings +* Barcode generation and printing +* Messaging +* Multilanguage +* Different UI themes -This is the latest version 3.0.0 and it's based on Bootstrap 3 using Bootswatch theme Flatly as default, and CodeIgniter 3.0.6. +The software is written in PHP language, it uses MySQL or MariaDB as data storage back-end and has a simple but intuitive user interface. -Badges ------- -[![Build Status](https://travis-ci.org/jekkos/opensourcepos.svg?branch=master)](https://travis-ci.org/jekkos/opensourcepos) -[![Join the chat at https://gitter.im/jekkos/opensourcepos](https://badges.gitter.im/jekkos/opensourcepos.svg)](https://gitter.im/jekkos/opensourcepos?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +The latest version 3.0.2 is a complete overhaul of the original software. +It is now based on Bootstrap 3.x using Bootswatch themes, and still uses CodeIgniter 3.x as framework. +It also has improved functionality and security. + +Deployed to a Cloud it can be defined as a SaaS (Software as as Service) type of solution. + +License +------- + +Open Source Point of Sale is licensed under MIT terms with an important addition: + +_The footer signature "You are using Open Source Point Of Sale" with version, +hash and link to the original distribution of the code MUST BE RETAINED, +MUST BE VISIBLE IN EVERY PAGE and CANNOT BE MODIFIED._ + +Also worth noting: + +_The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software._ + +For more details please read the file __LICENSE__. + +It's important to understand that althought you are free to use the software the copyright stays and the license agreement applies in all cases. +Therefore any actions like: + +- Removing LICENSE and any license files is prohibited +- Authoring the footer notice replacing it with your own or even worse claiming the copyright is absolutely prohibited +- Claiming full ownership of the code is prohibited + +In short you are free to use the software but you cannot claim any property on it. + +Any person or company found breaching the license agreement will be chased up. Keep the Machine Running ------------------------ @@ -21,60 +68,101 @@ Server Requirements ------------------- PHP version 5.5 or newer is recommended but PHP 7.x is not fully supported yet. -Reporting Bugs --------------- -Since OSPOS 3.0.0 is a version under development, please make sure you always run the latest 2.4_to_3.0.sql database upgrade script. -Please DO NOT post issues if you have not done that before running OSPOS 3.0. -Please also make sure you have updated all the files from latest master. +PHP needs to have `php-gd`, `php-bcmath`, `php-intl`, `php-sockets` and `php-mcrypt` installed and enabled. -Bug reports must follow this schema: +MySQL 5.5 or 5.6 are fine but MySQL 5.7 is not supported yet. -1. OS name and version running your Web Server (e.g. Linux Ubuntu 15.0) -2. Web Server name and version (e.g. Apache 2.4) -3. Database name and version (e.g. MySQL 5.6) -3. PHP version (e.g. PHP 5.5) -4. Language selected in OSPOS (e.g. English, Spanish) -5. Any configuration of OSPOS that you changed -6. Exact steps to reproduce the issue (test case) +Apache 2.2 and 2.4 are working both fine. -If above information is not provided in full, your issue will be tagged as pending. -If missing information is not provided within a week we will close your issue. - -Installation ------------- +Local install +------------- 1. Create/locate a new mysql database to install open source point of sale into 2. Execute the file database/database.sql to create the tables needed 3. unzip and upload Open Source Point of Sale files to web server 4. Copy application/config/database.php.tmpl to application/config/database.php 5. Modify application/config/database.php to connect to your database 6. Modify application/config/config.php encryption key with your own -7. Go to your point of sale install via the browser +7. Go to your point of sale install public dir via the browser 8. LOGIN using -username: admin -password:pointofsale + * username: admin + * password: pointofsale 9. Enjoy +10. Oops an issue? Please read the FAQ first thing :-) -FAQ ---- -If a blank page (HTTP status 500) shows after search completion or receipt generation, then double check php5-gd presence in your php installation. On windows check in php.ini whether the lib is installed. On Ubuntu issue `sudo apt-get install php5-gd`. Also have a look at the Dockerfile for a complete list of recommended packages. +P.S.: For more info about a local install based on Raspberry PI please read our wiki -13/01/2016: Install using Docker --------------------------------- +Local install using Docker +-------------------------- From now on ospos can be deployed using Docker on Linux, Mac or Windows. This setup dramatically reduces the number of possible issues as all setup is now done in a Dockerfile. Docker runs natively on mac and linux, but will require more overhead on windows. Please refer to the docker documentation for instructions on how to set it up on your platform. To build and run the image, issue following commands in a terminal with docker installed - docker build -t me/ospos https://github.com/jekkos/opensourcepos.git - docker run -d -p 80:80 me/ospos + docker-compose build + docker-compose up -Docker will clone the latest master into the image and start a LAMP stack with the application configured. If you like to persist your changes in this install, then you can use two docker data containers to store database and filesystem changes. In this case you will need following command (first time only) +Cloud install +------------- +A quick option would be to install directly to [Digitalocean](https://m.do.co/c/ac38c262507b) using their preconfigured LAMP stack. +Create a DO account first, add a droplet with preconfigured LAMP and follow the instructions for Local Install below. You will be running a provisioned VPS within minutes. - docker run -d -v /app --name="ospos" -v /var/lib/mysql --name="ospos-sql" -p 127.0.0.1:80:80 me/ospos +Cloud install using Docker +-------------------------- +If you want to run a quick demo of ospos or run it permanently in the cloud, then we +suggest using Docker cloud together with the DigitalOcean hosting platform. This way all the +configuration is done automatically and the install will just work. -After stopping the created container for the first time, this command will be replaced with +If you choose *DigitalOcean* [through this link](https://m.do.co/c/ac38c262507b), you will get a *$10 credit* for a first +month of uptime on the platform. A full setup will only take about 2 minutes by following steps below. - docker run -d -v /app --volumes-from="ospos" -v /var/lib/mysql --volumes-from="ospos-sql" -p 127.0.0.1:80:80 me/ospos +1. Create a [Digitalocean account](https://m.do.co/c/ac38c262507b) +2. Create a [docker cloud account](https://cloud.docker.com) +3. Login to docker cloud +4. Associate your docker cloud account with your previously created digital ocean account under settings +5. Create a new node on DigitalOcean through the `Infrastructure > Nodes` tab. Fill in a name (ospos) and choose a region near to you. We recommend to choose a node with minimum 1G RAM for the whole stack +6. Click [![Deploy to Docker Cloud](https://files.cloud.docker.com/images/deploy-to-dockercloud.svg)](https://cloud.docker.com/stack/deploy/?repo=https://github.com/jekkos/opensourcepos) +7. Othewise create a new stack under `Applications > Stacks` and paste the [contents of docker-cloud.yml](https://github.com/jekkos/opensourcepos/blob/master/docker-cloud.yml) from the source repository in the text field and hit `Create and deploy` +8. Find your website url under `Infrastructure > Nodes > > Endpoints > web` +9. Login with default username/password admin/pointofsale +10. DNS name for this server can be easily configured in the DigitalOcean control panel -Both the data and mysql directories will be persisted in a separate docker container and can be mounted within any other container using the last command. A more extensive setup guide can be found at [this site](http://www.opensourceposguide.com/guide/gettingstarted/installation) +More info [on maintaining a docker](https://github.com/jekkos/opensourcepos/wiki/Docker-cloud-maintenance) install can be found on the wiki +Reporting Bugs +-------------- +If you are taking a release candidate code please make sure you always run the latest database upgrade script and you took the latest code from master. +Please DO NOT post issues if you have not done those step. +Bug reports must follow this schema: + +1. Ospos **version string with git commit hash** (see ospos footer) +2. OS name and version running your Web Server (e.g. Linux Ubuntu 15.0) +3. Web Server name and version (e.g. Apache 2.4) +4. Database name and version (e.g. =< MySQL 5.6) +5. PHP version (e.g. PHP 5.5) +6. Language selected in OSPOS (e.g. English, Spanish) +7. Any configuration of OSPOS that you changed +8. Exact steps to reproduce the issue (test case) +9. Optionally some screenshots to illustrate each step + +If above information is not provided in full, your issue will be tagged as pending. +If missing information is not provided within a week we will close your issue. + +FAQ +--- +* If a blank page (HTTP status 500) shows after search completion or receipt generation, then double check `php5-gd` presence in your php installation. On windows check in php.ini whether the lib is installed. On Ubuntu issue `sudo apt-get install php5-gd`. Also have a look at the Dockerfile for a complete list of recommended packages. + +* If sales and receiving views don't show properly, please make sure BCMath lib (`php-bcmath`) is installed. On windows check php.ini and make sure php_bcmath extension is not commented out + +* If the following error is seen in sales module `Message: Class 'NumberFormatter' not found` then you don't have `php5-intl` extension installed. Please check the [wiki](https://github.com/jekkos/opensourcepos/wiki/Localisation-support#php5-intl-extension-installation) to resolve this issue on your platform. If you use WAMP, please read [issue #949](https://github.com/jekkos/opensourcepos/issues/949) + +* If you are getting the error `Message: Can't use method return value in write context` that means that you are probably using PHP7 which is not completely supported yet. Check your hosting configuration to verify whether you have a supported PHP version installed + +* If you read errors containing messages with Socket word in it, please make sure you have installed PHP Sockets support (e.g. go to PHP.ini and make sure all the needed modules are not commented out. This means `php5-gd`, `php-intl` and `php-sockets`. Restart the web server) + +* If you get various errors at item creation, opening views or reports, or having issues at login please make sure you are not using MySQL 5.7 as it's not supported yet + +* If you installed your OSPOS under a web server subdir, please edit public/.htaccess and go to the lines with comment `if in web root` and `if in subdir comment above line, uncomment below one and replace with your path` and follow the instruction on the second comment line. If you face more issues please read [issue #920](https://github.com/jekkos/opensourcepos/issues/920) for more help + +* If the avatar pictures are not shown in Items or at Item save time you get an error, please make sure your public and subdirs are assigned to the correct owner and the access permission is set to 755 + +* If you have problems with the encryption support or you get an error please make sure `php5-mcrypt` is installed diff --git a/UPGRADE.txt b/UPGRADE.txt index 6723f907e..1a8317f1f 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -4,11 +4,12 @@ How to Upgrade 2. Make sure you have a copy of application/config/config.php and application/config/database.php 3. Remove all directories 4. Install the new OSPOS -5. Run the database upgrade scripts from database/ (check which ones you need according to the version you are upgrading from) +5. Run the database upgrade scripts from database/ dir (check which ones you need according to the version you are upgrading from) 6. Take the saved old config.php and upgrade the new config.php with any additional changes you made in the old. Take time to understand if new config rules require some changes (e.g. encryption keys) 7. Copy application/config/database.php.tmpl to application/config/database.php 8. Take the saved old database.php and change the new database.php to contain all the configuration you had in the old setup. Please try not to use the old layout, use the new one and just copy the content of the config variables -9. Once new code is in place, database is updated and config files are sorted you are good to start the new OSPOS -10. If any issue please check GitHub issues as somebody else might have had your problem already or post a question +9. Restore the content of the old uploads/ folder into public/uploads/ one +10. Once new code is in place, database is updated and config files are sorted you are good to start the new OSPOS +11. If any issue please check FAQ and/or GitHub issues as somebody else might have had your problem already or post a question diff --git a/WHATS_NEW.txt b/WHATS_NEW.txt index 0b337ba4f..44c9436f1 100644 --- a/WHATS_NEW.txt +++ b/WHATS_NEW.txt @@ -1,3 +1,46 @@ +Version 3.0.2 +----------- ++ Fixed error when performing scans multiple times in a row ++ Fixed summary reports ++ Protect Employee privacy printing just the first letter of the family name ++ Updates to language translations ++ Various Dockers support improvements ++ Minor bugfixes + +Version 3.0.1 +----------- ++ *CodeIgniter 3.1.2 Upgrade* ++ *Substantial database performance improvements* ++ *Improved security: email and sms passwords encryption, removed phpinfo.php* ++ *Set code to be production and not development in index.php* ++ *Reports improvements, fixed table sorting, tax calculation and made profit to be net profit* ++ Better Apache 2.4 support in .htaccess ++ Updates to language translations ++ Fixed excel template download links ++ Fixed employee name in Sale receipt and invoice reprinting ++ Fixed 2.3.2_to_2.3.3.sql database upgrade script mistake ++ Fixed phppos to ospos database migration script ++ Minor bugfixes and some general code clean up + +Version 3.0.0 +----------- ++ *CodeIgniter 3.1 Upgrade* ++ Major UI overhaul based on *Boostrap 3.0 and Bootswatch Themes* ++ New tabular views with advanced filtering using *Bootstrap Tables* ++ New graphical reports with no more Adobe flash dependency ++ Redesign of all modal dialogs ++ Updated Sales register with simplified payment flow ++ *Improved security: MySQL injection, XSS, CSFR, BCrypt password encryption, safer project layout* ++ Support for TXT messaging (interfacing to specific support required) ++ Email configuration ++ Improved Localisation support ++ Improved Store Config page ++ Docker container ready for Cloud installation ++ Composer PHP support ++ More languages and integration with Weblate for continuous translation ++ About 280 closed issues under 3.0.0 release label, too many to produce a meaningful list ++ Various code cleanup, refactoring, optimisation and etc. + Version 2.4 ----------- + *CodeIgniter 3.0.5* Upgrade (please read UPGRADE.txt) diff --git a/application/config/autoload.php b/application/config/autoload.php index 1da59fcb7..090828883 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -58,7 +58,7 @@ $autoload['packages'] = array(); | | $autoload['libraries'] = array('user_agent' => 'ua'); */ -$autoload['libraries'] = array('database', 'form_validation', 'session', 'user_agent', 'pagination', 'sms'); +$autoload['libraries'] = array('database', 'form_validation', 'session', 'user_agent', 'pagination', 'encryption'); /* | ------------------------------------------------------------------- @@ -72,6 +72,12 @@ $autoload['libraries'] = array('database', 'form_validation', 'session', 'user_a | Prototype: | | $autoload['drivers'] = array('cache'); +| +| You can also supply an alternative property name to be assigned in +| the controller: +| +| $autoload['drivers'] = array('cache' => 'cch'); +| */ $autoload['drivers'] = array(); diff --git a/application/config/config.php b/application/config/config.php index c82190a6c..c8c1d6bb6 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -1,19 +1,50 @@ - '', - 'function' => 'load_config', - 'filename' => 'load_config.php', - 'filepath' => 'hooks' +$hook['post_controller_constructor'][] = array( + 'class' => '', + 'function' => 'load_config', + 'filename' => 'load_config.php', + 'filepath' => 'hooks' ); + +$hook['post_controller_constructor'][] = array( + 'class' => '', + 'function' => 'load_stats', + 'filename' => 'load_stats.php', + 'filepath' => 'hooks' + ); + +// 'post_controller' indicated execution of hooks after controller is finished +$hook['post_controller'] = array( + 'class' => '', + 'function' => 'db_log_queries', + 'filename' => 'db_log.php', + 'filepath' => 'hooks' + ); \ No newline at end of file diff --git a/application/config/routes.php b/application/config/routes.php index 1b3b03950..25bfbf19f 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -56,9 +56,9 @@ $route['no_access/([^/]+)/([^/]+)'] = 'no_access/index/$1/$2'; $route['sales/index/([^/]+)'] = 'sales/manage/$1'; $route['sales/index/([^/]+)/([^/]+)'] = 'sales/manage/$1/$2'; $route['sales/index/([^/]+)/([^/]+)/([^/]+)'] = 'sales/manage/$1/$2/$3'; -$route['reports/(summary_:any)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3'; +$route['reports/(summary_:any)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3/$4'; $route['reports/summary_:any'] = 'reports/date_input'; -$route['reports/(graphical_:any)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3'; +$route['reports/(graphical_:any)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3/$4'; $route['reports/graphical_:any'] = 'reports/date_input'; $route['reports/(inventory_:any)/([^/]+)'] = 'reports/$1/$2'; $route['reports/inventory_summary'] = 'reports/inventory_summary_input'; diff --git a/application/config/theme.php b/application/config/theme.php deleted file mode 100644 index 807e85503..000000000 --- a/application/config/theme.php +++ /dev/null @@ -1,15 +0,0 @@ - 'Crazy Webcrawler', 'adsbot-google' => 'AdsBot Google', 'feedfetcher-google' => 'Feedfetcher Google', - 'curious george' => 'Curious George' + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot' ); diff --git a/application/controllers/Barcode.php b/application/controllers/Barcode.php deleted file mode 100644 index 9e9655ded..000000000 --- a/application/controllers/Barcode.php +++ /dev/null @@ -1,16 +0,0 @@ -load->view('barcode'); - } - -} -?> \ No newline at end of file diff --git a/application/controllers/Config.php b/application/controllers/Config.php index 12535f7ad..e7a2cf7ac 100644 --- a/application/controllers/Config.php +++ b/application/controllers/Config.php @@ -1,130 +1,376 @@ -load->library('barcode_lib'); } - - function index() + + /* + * This function loads all the licenses starting with the first one being OSPOS one + */ + private function _licenses() + { + $i = 0; + $bower = FALSE; + $composer = FALSE; + $license = array(); + + $license[$i]['title'] = 'Open Source Point Of Sale ' . $this->config->item('application_version'); + + if(file_exists('license/LICENSE')) + { + $license[$i]['text'] = $this->xss_clean(file_get_contents('license/LICENSE', NULL, NULL, 0, 2000)); + } + else + { + $license[$i]['text'] = 'LICENSE file must be in OSPOS license directory. You are not allowed to use OSPOS application until the distribution copy of LICENSE file is present.'; + } + + // read all the files in the dir license + $dir = new DirectoryIterator('license'); + + foreach($dir as $fileinfo) + { + // license files must be in couples: .version (name & version) & .license (license text) + if($fileinfo->isFile()) + { + if($fileinfo->getExtension() == 'version') + { + ++$i; + + $basename = 'license/' . $fileinfo->getBasename('.version'); + + $license[$i]['title'] = $this->xss_clean(file_get_contents($basename . '.version', NULL, NULL, 0, 100)); + + $license_text_file = $basename . '.license'; + + if(file_exists($license_text_file)) + { + $license[$i]['text'] = $this->xss_clean(file_get_contents($license_text_file , NULL, NULL, 0, 2000)); + } + else + { + $license[$i]['text'] = $license_text_file . ' file is missing'; + } + } + elseif($fileinfo->getBasename() == 'bower.LICENSES') + { + // set a flag to indicate that the JS Plugin bower.LICENSES file is available and needs to be attached at the end + $bower = TRUE; + } + elseif($fileinfo->getBasename() == 'composer.LICENSES') + { + // set a flag to indicate that the composer.LICENSES file is available and needs to be attached at the end + $composer = TRUE; + } + } + } + + // attach the licenses from the LICENSES file generated by bower + if($composer) + { + ++$i; + $license[$i]['title'] = 'Composer Libraries'; + $license[$i]['text'] = ''; + + $file = file_get_contents('license/composer.LICENSES'); + $array = json_decode($file, true); + + foreach($array as $key => $val) + { + if(is_array($val) && $key == 'dependencies') + { + foreach($val as $key1 => $val1) + { + if(is_array($val1)) + { + $license[$i]['text'] .= 'component: ' . $key1 . "\n"; + + foreach($val1 as $key2 => $val2) + { + if(is_array($val2)) + { + $license[$i]['text'] .= $key2 . ': '; + + foreach($val2 as $key3 => $val3) + { + $license[$i]['text'] .= $val3 . ' '; + } + + $license[$i]['text'] .= "\n"; + } + else + { + $license[$i]['text'] .= $key2 . ': ' . $val2 . "\n"; + } + } + + $license[$i]['text'] .= "\n"; + } + else + { + $license[$i]['text'] .= $key1 . ': ' . $val1 . "\n"; + } + } + } + } + + $license[$i]['text'] = $this->xss_clean($license[$i]['text']); + } + + // attach the licenses from the LICENSES file generated by bower + if($bower) + { + ++$i; + $license[$i]['title'] = 'JS Plugins'; + $license[$i]['text'] = ''; + + $file = file_get_contents('license/bower.LICENSES'); + $array = json_decode($file, true); + + foreach($array as $key => $val) + { + if(is_array($val)) + { + $license[$i]['text'] .= 'component: ' . $key . "\n"; + + foreach($val as $key1 => $val1) + { + if(is_array($val1)) + { + $license[$i]['text'] .= $key1 . ': '; + + foreach($val1 as $key2 => $val2) + { + $license[$i]['text'] .= $val2 . ' '; + } + + $license[$i]['text'] .= "\n"; + } + else + { + $license[$i]['text'] .= $key1 . ': ' . $val1 . "\n"; + } + } + + $license[$i]['text'] .= "\n"; + } + } + + $license[$i]['text'] = $this->xss_clean($license[$i]['text']); + } + + return $license; + } + + private function _themes() + { + $themes = array(); + + // read all themes in the dist folder + $dir = new DirectoryIterator('dist/bootswatch'); + + foreach($dir as $dirinfo) + { + if($dirinfo->isDir() && !$dirinfo->isDot() && $dirinfo->getFileName() != 'fonts') + { + $themes[$dirinfo->getFileName()] = $dirinfo->getFileName(); + } + } + + asort($themes); + + return $themes; + } + + public function index() { - $location_names = array(); $data['stock_locations'] = $this->Stock_location->get_all()->result_array(); $data['support_barcode'] = $this->barcode_lib->get_list_barcodes(); - $data['logo_exists'] = $this->Appconfig->get('company_logo') != ''; + $data['logo_exists'] = $this->config->item('company_logo') != ''; + + $data = $this->xss_clean($data); + + // load all the license statements, they are already XSS cleaned in the private function + $data['licenses'] = $this->_licenses(); + $data['themes'] = $this->_themes(); $this->load->view("configs/manage", $data); } - function save_info() + public function save_info() { $upload_success = $this->_handle_logo_upload(); $upload_data = $this->upload->data(); - + $batch_save_data = array( - 'company'=>$this->input->post('company'), - 'address'=>$this->input->post('address'), - 'phone'=>$this->input->post('phone'), - 'email'=>$this->input->post('email'), - 'fax'=>$this->input->post('fax'), - 'website'=>$this->input->post('website'), - 'return_policy'=>$this->input->post('return_policy') + 'company' => $this->input->post('company'), + 'address' => $this->input->post('address'), + 'phone' => $this->input->post('phone'), + 'email' => $this->input->post('email'), + 'fax' => $this->input->post('fax'), + 'website' => $this->input->post('website'), + 'return_policy' => $this->input->post('return_policy') ); if (!empty($upload_data['orig_name'])) { // XSS file image sanity check - if ($this->security->xss_clean($upload_data['raw_name'], TRUE) === TRUE) + if ($this->xss_clean($upload_data['raw_name'], TRUE) === TRUE) { $batch_save_data['company_logo'] = $upload_data['raw_name'] . $upload_data['file_ext']; } } $result = $this->Appconfig->batch_save($batch_save_data); - $success = $upload_success && $result ? true : false; + $success = $upload_success && $result ? TRUE : FALSE; $message = $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'); - $message = $upload_success ? $message : $this->upload->display_errors(); + $message = $upload_success ? $message : strip_tags($this->upload->display_errors()); - echo json_encode(array('success'=>$success, 'message'=>$message)); + echo json_encode(array('success' => $success, 'message' => $message)); } - function save_general() + public function save_general() { $batch_save_data = array( - 'default_tax_1_rate'=>$this->input->post('default_tax_1_rate'), - 'default_tax_1_name'=>$this->input->post('default_tax_1_name'), - 'default_tax_2_rate'=>$this->input->post('default_tax_2_rate'), - 'default_tax_2_name'=>$this->input->post('default_tax_2_name'), - 'tax_included'=>$this->input->post('tax_included') != null, - 'receiving_calculate_average_price'=>$this->input->post('receiving_calculate_average_price') != null, - 'lines_per_page'=>$this->input->post('lines_per_page'), - 'default_sales_discount'=>$this->input->post('default_sales_discount'), - 'custom1_name'=>$this->input->post('custom1_name'), - 'custom2_name'=>$this->input->post('custom2_name'), - 'custom3_name'=>$this->input->post('custom3_name'), - 'custom4_name'=>$this->input->post('custom4_name'), - 'custom5_name'=>$this->input->post('custom5_name'), - 'custom6_name'=>$this->input->post('custom6_name'), - 'custom7_name'=>$this->input->post('custom7_name'), - 'custom8_name'=>$this->input->post('custom8_name'), - 'custom9_name'=>$this->input->post('custom9_name'), - 'custom10_name'=>$this->input->post('custom10_name') + 'theme' => $this->input->post('theme'), + 'default_tax_1_rate' => parse_decimals($this->input->post('default_tax_1_rate')), + 'default_tax_1_name' => $this->input->post('default_tax_1_name'), + 'default_tax_2_rate' => parse_decimals($this->input->post('default_tax_2_rate')), + 'default_tax_2_name' => $this->input->post('default_tax_2_name'), + 'tax_included' => $this->input->post('tax_included') != NULL, + 'receiving_calculate_average_price' => $this->input->post('receiving_calculate_average_price') != NULL, + 'lines_per_page' => $this->input->post('lines_per_page'), + 'default_sales_discount' => $this->input->post('default_sales_discount'), + 'notify_horizontal_position' => $this->input->post('notify_horizontal_position'), + 'notify_vertical_position' => $this->input->post('notify_vertical_position'), + 'custom1_name' => $this->input->post('custom1_name'), + 'custom2_name' => $this->input->post('custom2_name'), + 'custom3_name' => $this->input->post('custom3_name'), + 'custom4_name' => $this->input->post('custom4_name'), + 'custom5_name' => $this->input->post('custom5_name'), + 'custom6_name' => $this->input->post('custom6_name'), + 'custom7_name' => $this->input->post('custom7_name'), + 'custom8_name' => $this->input->post('custom8_name'), + 'custom9_name' => $this->input->post('custom9_name'), + 'custom10_name' => $this->input->post('custom10_name'), + 'statistics' => $this->input->post('statistics') != NULL, ); $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? true : false; + $success = $result ? TRUE : FALSE; - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - function save_locale() + public function check_number_locale() { - $batch_save_data = array( - 'currency_symbol'=>$this->input->post('currency_symbol'), - 'currency_side'=>$this->input->post('currency_side') != null, - 'language'=>$this->input->post('language'), - 'timezone'=>$this->input->post('timezone'), - 'dateformat'=>$this->input->post('dateformat'), - 'timeformat'=>$this->input->post('timeformat'), - 'thousands_separator'=>$this->input->post('thousands_separator'), - 'decimal_point'=>$this->input->post('decimal_point'), - 'currency_decimals'=>$this->input->post('currency_decimals'), - 'tax_decimals'=>$this->input->post('tax_decimals'), - 'quantity_decimals'=>$this->input->post('quantity_decimals'), - 'country_codes'=>$this->input->post('country_codes') + $number_locale = $this->input->post('number_locale'); + $fmt = new \NumberFormatter($number_locale, \NumberFormatter::CURRENCY); + $currency_symbol = empty($this->input->post('currency_symbol')) ? $fmt->getSymbol(\NumberFormatter::CURRENCY_SYMBOL) : $this->input->post('currency_symbol'); + if ($this->input->post('thousands_separator') == "false") + { + $fmt->setAttribute(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL, ''); + } + $fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $currency_symbol); + $number_local_example = $fmt->format(1234567890.12300); + echo json_encode(array( + 'success' => $number_local_example != FALSE, + 'number_locale_example' => $number_local_example, + 'currency_symbol' => $currency_symbol, + 'thousands_separator' => $fmt->getAttribute(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL) != '' + )); + } + + public function save_locale() + { + $exploded = explode(":", $this->input->post('language')); + $batch_save_data = array( + 'currency_symbol' => $this->input->post('currency_symbol'), + 'language_code' => $exploded[0], + 'language' => $exploded[1], + 'timezone' => $this->input->post('timezone'), + 'dateformat' => $this->input->post('dateformat'), + 'timeformat' => $this->input->post('timeformat'), + 'thousands_separator' => $this->input->post('thousands_separator'), + 'number_locale' => $this->input->post('number_locale'), + 'currency_decimals' => $this->input->post('currency_decimals'), + 'tax_decimals' => $this->input->post('tax_decimals'), + 'quantity_decimals' => $this->input->post('quantity_decimals'), + 'country_codes' => $this->input->post('country_codes'), + 'payment_options_order' => $this->input->post('payment_options_order') ); $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? true : false; + $success = $result ? TRUE : FALSE; - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - - function save_message() + + public function save_email() { + $password = ''; + + if($this->_check_encryption()) + { + $password = $this->encryption->encrypt($this->input->post('smtp_pass')); + } + + $batch_save_data = array( + 'protocol' => $this->input->post('protocol'), + 'mailpath' => $this->input->post('mailpath'), + 'smtp_host' => $this->input->post('smtp_host'), + 'smtp_user' => $this->input->post('smtp_user'), + 'smtp_pass' => $password, + 'smtp_port' => $this->input->post('smtp_port'), + 'smtp_timeout' => $this->input->post('smtp_timeout'), + 'smtp_crypto' => $this->input->post('smtp_crypto') + ); + + $result = $this->Appconfig->batch_save($batch_save_data); + $success = $result ? TRUE : FALSE; + + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + } + + public function save_message() + { + $password = ''; + + if($this->_check_encryption()) + { + $password = $this->encryption->encrypt($this->input->post('msg_pwd')); + } + $batch_save_data = array( - 'msg_msg'=>$this->input->post('msg_msg'), - 'msg_uid'=>$this->input->post('msg_uid'), - 'msg_pwd'=>$this->input->post('msg_pwd'), - 'msg_src'=>$this->input->post('msg_src') + 'msg_msg' => $this->input->post('msg_msg'), + 'msg_uid' => $this->input->post('msg_uid'), + 'msg_pwd' => $password, + 'msg_src' => $this->input->post('msg_src') ); $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? true : false; + $success = $result ? TRUE : FALSE; - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - function stock_locations() + public function stock_locations() { $stock_locations = $this->Stock_location->get_all()->result_array(); + + $stock_locations = $this->xss_clean($stock_locations); - $this->load->view('partial/stock_locations', array('stock_locations'=>$stock_locations)); + $this->load->view('partial/stock_locations', array('stock_locations' => $stock_locations)); } - function _clear_session_state() + private function _clear_session_state() { $this->load->library('sale_lib'); $this->sale_lib->clear_sale_location(); @@ -135,7 +381,7 @@ class Config extends Secure_area $this->receiving_lib->clear_all(); } - function save_locations() + public function save_locations() { $this->db->trans_start(); @@ -147,7 +393,7 @@ class Config extends Secure_area $location_id = preg_replace("/.*?_(\d+)$/", "$1", $key); unset($deleted_locations[$location_id]); // save or update - $location_data = array('location_name'=>$value); + $location_data = array('location_name' => $value); if ($this->Stock_location->save($location_data, $location_id)) { $this->_clear_session_state(); @@ -165,78 +411,78 @@ class Config extends Secure_area $success = $this->db->trans_status(); - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - function save_barcode() + public function save_barcode() { $batch_save_data = array( - 'barcode_type'=>$this->input->post('barcode_type'), - 'barcode_quality'=>$this->input->post('barcode_quality'), - 'barcode_width'=>$this->input->post('barcode_width'), - 'barcode_height'=>$this->input->post('barcode_height'), - 'barcode_font'=>$this->input->post('barcode_font'), - 'barcode_font_size'=>$this->input->post('barcode_font_size'), - 'barcode_first_row'=>$this->input->post('barcode_first_row'), - 'barcode_second_row'=>$this->input->post('barcode_second_row'), - 'barcode_third_row'=>$this->input->post('barcode_third_row'), - 'barcode_num_in_row'=>$this->input->post('barcode_num_in_row'), - 'barcode_page_width'=>$this->input->post('barcode_page_width'), - 'barcode_page_cellspacing'=>$this->input->post('barcode_page_cellspacing'), - 'barcode_generate_if_empty'=>$this->input->post('barcode_generate_if_empty') != null, - 'barcode_content'=>$this->input->post('barcode_content') + 'barcode_type' => $this->input->post('barcode_type'), + 'barcode_quality' => $this->input->post('barcode_quality'), + 'barcode_width' => $this->input->post('barcode_width'), + 'barcode_height' => $this->input->post('barcode_height'), + 'barcode_font' => $this->input->post('barcode_font'), + 'barcode_font_size' => $this->input->post('barcode_font_size'), + 'barcode_first_row' => $this->input->post('barcode_first_row'), + 'barcode_second_row' => $this->input->post('barcode_second_row'), + 'barcode_third_row' => $this->input->post('barcode_third_row'), + 'barcode_num_in_row' => $this->input->post('barcode_num_in_row'), + 'barcode_page_width' => $this->input->post('barcode_page_width'), + 'barcode_page_cellspacing' => $this->input->post('barcode_page_cellspacing'), + 'barcode_generate_if_empty' => $this->input->post('barcode_generate_if_empty') != NULL, + 'barcode_content' => $this->input->post('barcode_content') ); $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? true : false; + $success = $result ? TRUE : FALSE; - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - function save_receipt() + public function save_receipt() { $batch_save_data = array ( - 'receipt_show_taxes'=>$this->input->post('receipt_show_taxes') != null, - 'receipt_show_total_discount'=>$this->input->post('receipt_show_total_discount') != null, - 'receipt_show_description'=>$this->input->post('receipt_show_description') != null, - 'receipt_show_serialnumber'=>$this->input->post('receipt_show_serialnumber') != null, - 'print_silently'=>$this->input->post('print_silently') != null, - 'print_header'=>$this->input->post('print_header') != null, - 'print_footer'=>$this->input->post('print_footer') != null, - 'print_top_margin'=>$this->input->post('print_top_margin'), - 'print_left_margin'=>$this->input->post('print_left_margin'), - 'print_bottom_margin'=>$this->input->post('print_bottom_margin'), - 'print_right_margin'=>$this->input->post('print_right_margin') + 'receipt_template' => $this->input->post('receipt_template'), + 'receipt_show_taxes' => $this->input->post('receipt_show_taxes') != NULL, + 'receipt_show_total_discount' => $this->input->post('receipt_show_total_discount') != NULL, + 'receipt_show_description' => $this->input->post('receipt_show_description') != NULL, + 'receipt_show_serialnumber' => $this->input->post('receipt_show_serialnumber') != NULL, + 'print_silently' => $this->input->post('print_silently') != NULL, + 'print_header' => $this->input->post('print_header') != NULL, + 'print_footer' => $this->input->post('print_footer') != NULL, + 'print_top_margin' => $this->input->post('print_top_margin'), + 'print_left_margin' => $this->input->post('print_left_margin'), + 'print_bottom_margin' => $this->input->post('print_bottom_margin'), + 'print_right_margin' => $this->input->post('print_right_margin') ); $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? true : false; + $success = $result ? TRUE : FALSE; - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - function save_invoice() + public function save_invoice() { $batch_save_data = array ( - 'invoice_enable'=>$this->input->post('invoice_enable') != null, - 'sales_invoice_format'=>$this->input->post('sales_invoice_format'), - 'recv_invoice_format'=>$this->input->post('recv_invoice_format'), - 'use_invoice_template'=>$this->input->post('use_invoice_template') != null, - 'invoice_default_comments'=>$this->input->post('invoice_default_comments'), - 'invoice_email_message'=>$this->input->post('invoice_email_message') + 'invoice_enable' => $this->input->post('invoice_enable') != NULL, + 'sales_invoice_format' => $this->input->post('sales_invoice_format'), + 'recv_invoice_format' => $this->input->post('recv_invoice_format'), + 'invoice_default_comments' => $this->input->post('invoice_default_comments'), + 'invoice_email_message' => $this->input->post('invoice_email_message') ); $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? true : false; + $success = $result ? TRUE : FALSE; - echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } public function remove_logo() { $result = $this->Appconfig->batch_save(array('company_logo' => '')); - echo json_encode(array('success'=>$result)); + echo json_encode(array('success' => $result)); } private function _handle_logo_upload() @@ -254,28 +500,85 @@ class Config extends Secure_area $this->upload->do_upload('company_logo'); return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '

'.$this->lang->line('upload_no_file_selected').'

'); - } + } + + private function _check_encryption() + { + $encryption_key = $this->config->item('encryption_key'); + + // check if the encryption_key config item is the default one + if($encryption_key == '' || $encryption_key == 'YOUR KEY') + { + // Config path + $config_path = APPPATH . 'config/config.php'; + + // Open the file + $config = file_get_contents($config_path); + + // $key will be assigned a 32-byte (256-bit) hex-encoded random key + $key = bin2hex($this->encryption->create_key(32)); + + // replace the empty placeholder with a real randomly generated encryption key + if($encryption_key == '') + { + $config = str_replace("['encryption_key'] = '';", "['encryption_key'] = '" . $key . "';", $config); + } + else + { + $config = str_replace("['encryption_key'] = 'YOUR KEY';", "['encryption_key'] = '" . $key . "';", $config); + } + + // set the encryption key in the config item + $this->config->set_item('encryption_key', $key); + + // Write the new config.php file + $handle = fopen($config_path, 'w+'); + + // Chmod the file + @chmod($config_path, 0777); + + $result = FALSE; + + // Verify file permissions + if(is_writable($config_path)) + { + // Write the file + $result = (fwrite($handle, $config) === FALSE) ? FALSE : TRUE; + } + + // Chmod the file + @chmod($config_path, 0444); + + fclose($handle); + + return $result; + } + + return TRUE; + } - function backup_db() + public function backup_db() { $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - if($this->Employee->has_module_grant('config',$employee_id)) + if($this->Employee->has_module_grant('config', $employee_id)) { $this->load->dbutil(); + $prefs = array( 'format' => 'zip', 'filename' => 'ospos.sql' ); - $backup =& $this->dbutil->backup($prefs); + $backup = $this->dbutil->backup($prefs); $file_name = 'ospos-' . date("Y-m-d-H-i-s") .'.zip'; - $save = 'uploads/'.$file_name; + $save = 'uploads/' . $file_name; $this->load->helper('download'); - while (ob_get_level()) + while(ob_get_level()) { ob_end_clean(); } + force_download($file_name, $backup); } else diff --git a/application/controllers/Customers.php b/application/controllers/Customers.php index 9d0c6cfbc..19296dd0a 100644 --- a/application/controllers/Customers.php +++ b/application/controllers/Customers.php @@ -1,16 +1,17 @@ -get_controller_name(); - $data['table_headers'] = get_people_manage_table_headers(); + $data['table_headers'] = $this->xss_clean(get_people_manage_table_headers()); $this->load->view('people/manage', $data); } @@ -18,13 +19,13 @@ class Customers extends Person_controller /* Returns customer table data rows. This will be called with AJAX. */ - function search() + public function search() { $search = $this->input->get('search'); - $limit = $this->input->get('limit'); + $limit = $this->input->get('limit'); $offset = $this->input->get('offset'); - $sort = $this->input->get('sort'); - $order = $this->input->get('order'); + $sort = $this->input->get('sort'); + $order = $this->input->get('order'); $customers = $this->Customer->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Customer->get_found_rows($search); @@ -34,22 +35,25 @@ class Customers extends Person_controller { $data_rows[] = get_person_data_row($person, $this); } + + $data_rows = $this->xss_clean($data_rows); + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } /* Gives search suggestions based on what is being searched for */ - function suggest() + public function suggest() { - $suggestions = $this->Customer->get_search_suggestions($this->input->get('term'), TRUE); + $suggestions = $this->xss_clean($this->Customer->get_search_suggestions($this->input->get('term'), TRUE)); echo json_encode($suggestions); } - function suggest_search() + public function suggest_search() { - $suggestions = $this->Customer->get_search_suggestions($this->input->post('term'), FALSE); + $suggestions = $this->xss_clean($this->Customer->get_search_suggestions($this->input->post('term'), FALSE)); echo json_encode($suggestions); } @@ -57,10 +61,16 @@ class Customers extends Person_controller /* Loads the customer edit form */ - function view($customer_id=-1) + public function view($customer_id = -1) { - $data['person_info'] = $this->Customer->get_info($customer_id); - $data['total'] = $this->Customer->get_totals($customer_id)->total; + $info = $this->Customer->get_info($customer_id); + foreach(get_object_vars($info) as $property => $value) + { + $info->$property = $this->xss_clean($value); + } + $data['person_info'] = $info; + + $data['total'] = $this->xss_clean($this->Customer->get_totals($customer_id)->total); $this->load->view("customers/form", $data); } @@ -68,52 +78,58 @@ class Customers extends Person_controller /* Inserts/updates a customer */ - function save($customer_id=-1) + public function save($customer_id = -1) { $person_data = array( - 'first_name'=>$this->input->post('first_name'), - 'last_name'=>$this->input->post('last_name'), - 'gender'=>$this->input->post('gender'), - 'email'=>$this->input->post('email'), - 'phone_number'=>$this->input->post('phone_number'), - 'address_1'=>$this->input->post('address_1'), - 'address_2'=>$this->input->post('address_2'), - 'city'=>$this->input->post('city'), - 'state'=>$this->input->post('state'), - 'zip'=>$this->input->post('zip'), - 'country'=>$this->input->post('country'), - 'comments'=>$this->input->post('comments') + 'first_name' => $this->input->post('first_name'), + 'last_name' => $this->input->post('last_name'), + 'gender' => $this->input->post('gender'), + 'email' => $this->input->post('email'), + 'phone_number' => $this->input->post('phone_number'), + 'address_1' => $this->input->post('address_1'), + 'address_2' => $this->input->post('address_2'), + 'city' => $this->input->post('city'), + 'state' => $this->input->post('state'), + 'zip' => $this->input->post('zip'), + 'country' => $this->input->post('country'), + 'comments' => $this->input->post('comments') ); - $customer_data=array( - 'account_number'=>$this->input->post('account_number') == '' ? null : $this->input->post('account_number'), - 'company_name'=>$this->input->post('company_name') == '' ? null : $this->input->post('company_name'), - 'discount_percent'=>$this->input->post('discount_percent') == '' ? 0.00 : $this->input->post('discount_percent'), - 'taxable'=>$this->input->post('taxable') != null + $customer_data = array( + 'account_number' => $this->input->post('account_number') == '' ? NULL : $this->input->post('account_number'), + 'company_name' => $this->input->post('company_name') == '' ? NULL : $this->input->post('company_name'), + 'discount_percent' => $this->input->post('discount_percent') == '' ? 0.00 : $this->input->post('discount_percent'), + 'taxable' => $this->input->post('taxable') != NULL ); - if($this->Customer->save_customer($person_data,$customer_data,$customer_id)) + + if($this->Customer->save_customer($person_data, $customer_data, $customer_id)) { + $person_data = $this->xss_clean($person_data); + $customer_data = $this->xss_clean($customer_data); + //New customer - if($customer_id==-1) + if($customer_id == -1) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_adding').' '. - $person_data['first_name'].' '.$person_data['last_name'], 'id' => $customer_data['person_id'])); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('customers_successful_adding').' '. + $person_data['first_name'].' '.$person_data['last_name'], 'id' => $customer_data['person_id'])); } - else //previous customer + else //Existing customer { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_updating').' '. - $person_data['first_name'].' '.$person_data['last_name'], 'id' => $customer_id)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('customers_successful_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'], 'id' => $customer_id)); } } else//failure - { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('customers_error_adding_updating').' '. - $person_data['first_name'].' '.$person_data['last_name'], 'id' => -1)); + { + $person_data = $this->xss_clean($person_data); + + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_error_adding_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'], 'id' => -1)); } } - function check_account_number() + public function check_account_number() { - $exists = $this->Customer->account_number_exists($this->input->post('account_number'),$this->input->post('person_id')); + $exists = $this->Customer->account_number_exists($this->input->post('account_number'), $this->input->post('person_id')); echo !$exists ? 'true' : 'false'; } @@ -121,115 +137,117 @@ class Customers extends Person_controller /* This deletes customers from the customers table */ - function delete() + public function delete() { - $customers_to_delete=$this->input->post('ids'); - + $customers_to_delete = $this->xss_clean($this->input->post('ids')); + if($this->Customer->delete_list($customers_to_delete)) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_deleted').' '. - count($customers_to_delete).' '.$this->lang->line('customers_one_or_multiple'))); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('customers_successful_deleted').' '. + count($customers_to_delete).' '.$this->lang->line('customers_one_or_multiple'))); } else { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('customers_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_cannot_be_deleted'))); } } - - function excel() + + /* + Customers import from excel spreadsheet + */ + public function excel() { - $data = file_get_contents("import_customers.csv"); $name = 'import_customers.csv'; + $data = file_get_contents('../' . $name); force_download($name, $data); } - function excel_import() + public function excel_import() { - $this->load->view("customers/form_excel_import", null); + $this->load->view('customers/form_excel_import', NULL); } - function do_excel_import() + public function do_excel_import() { - $msg = 'do_excel_import'; - $failCodes = array(); - - if ($_FILES['file_path']['error'] != UPLOAD_ERR_OK) + if($_FILES['file_path']['error'] != UPLOAD_ERR_OK) { - $msg = $this->lang->line('items_excel_import_failed'); - echo json_encode( array('success'=>false,'message'=>$msg) ); - - return; + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_excel_import_failed'))); } else { - if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE) + if(($handle = fopen($_FILES['file_path']['tmp_name'], 'r')) !== FALSE) { // Skip the first row as it's the table description fgetcsv($handle); - - $i=1; - while (($data = fgetcsv($handle)) !== FALSE) + $i = 1; + + $failCodes = array(); + + while(($data = fgetcsv($handle)) !== FALSE) { // XSS file data sanity check - $data = $this->security->xss_clean($data); - - $person_data = array( - 'first_name'=>$data[0], - 'last_name'=>$data[1], - 'gender'=>$data[2], - 'email'=>$data[3], - 'phone_number'=>$data[4], - 'address_1'=>$data[5], - 'address_2'=>$data[6], - 'city'=>$data[7], - 'state'=>$data[8], - 'zip'=>$data[9], - 'country'=>$data[10], - 'comments'=>$data[11] - ); - - $customer_data = array( - 'company_name'=>$data[12], - 'discount_percent'=>$data[14], - 'taxable'=>$data[15]=='' ? 0 : 1 - ); - - $account_number = $data[13]; - $invalidated = false; - if ($account_number != "") + $data = $this->xss_clean($data); + + if(sizeof($data) >= 15) { - $customer_data['account_number'] = $account_number; - $invalidated = $this->Customer->account_number_exists($account_number); + $person_data = array( + 'first_name' => $data[0], + 'last_name' => $data[1], + 'gender' => $data[2], + 'email' => $data[3], + 'phone_number' => $data[4], + 'address_1' => $data[5], + 'address_2' => $data[6], + 'city' => $data[7], + 'state' => $data[8], + 'zip' => $data[9], + 'country' => $data[10], + 'comments' => $data[11] + ); + + $customer_data = array( + 'company_name' => $data[12], + 'discount_percent' => $data[14], + 'taxable' => $data[15] == '' ? 0 : 1 + ); + + $account_number = $data[13]; + $invalidated = FALSE; + if($account_number != '') + { + $customer_data['account_number'] = $account_number; + $invalidated = $this->Customer->account_number_exists($account_number); + } } - + else + { + $invalidated = TRUE; + } + if($invalidated || !$this->Customer->save_customer($person_data, $customer_data)) { $failCodes[] = $i; } - $i++; + ++$i; + } + + if(count($failCodes) > 0) + { + $message = $this->lang->line('customers_excel_import_partially_failed') . ' (' . count($failCodes) . '): ' . implode(', ', $failCodes); + + echo json_encode(array('success' => FALSE, 'message' => $message)); + } + else + { + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('customers_excel_import_success'))); } } else { - echo json_encode( array('success'=>false, 'message'=>'Your uploaded file has no data or wrong format') ); - - return; + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_excel_import_nodata_wrongformat'))); } } - - $success = true; - if(count($failCodes) > 0) - { - $msg = "Most customers imported. But some were not, here is list of their CODE (" .count($failCodes) ."): ".implode(", ", $failCodes); - $success = false; - } - else - { - $msg = "Import of Customers successful"; - } - - echo json_encode( array('success'=>$success, 'message'=>$msg) ); } } ?> \ No newline at end of file diff --git a/application/controllers/Employees.php b/application/controllers/Employees.php index a8f484d6d..7bbd8f3a4 100644 --- a/application/controllers/Employees.php +++ b/application/controllers/Employees.php @@ -1,131 +1,168 @@ -get_controller_name(); - $data['table_headers'] = get_people_manage_table_headers(); - $this->load->view('people/manage',$data); + $data['table_headers'] = $this->xss_clean(get_people_manage_table_headers()); + + $this->load->view('people/manage', $data); } /* Returns employee table data rows. This will be called with AJAX. */ - function search() + public function search() { $search = $this->input->get('search'); - $limit = $this->input->get('limit'); + $limit = $this->input->get('limit'); $offset = $this->input->get('offset'); - $sort = $this->input->get('sort'); - $order = $this->input->get('order'); + $sort = $this->input->get('sort'); + $order = $this->input->get('order'); $employees = $this->Employee->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Employee->get_found_rows($search); + $data_rows = array(); foreach($employees->result() as $person) { $data_rows[] = get_person_data_row($person, $this); } + + $data_rows = $this->xss_clean($data_rows); + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } /* Gives search suggestions based on what is being searched for */ - function suggest_search() + public function suggest_search() { - $suggestions = $this->Employee->get_search_suggestions($this->input->post('term')); + $suggestions = $this->xss_clean($this->Employee->get_search_suggestions($this->input->post('term'))); + echo json_encode($suggestions); } /* Loads the employee edit form */ - function view($employee_id=-1) + public function view($employee_id = -1) { - $data['person_info']=$this->Employee->get_info($employee_id); - $data['all_modules']=$this->Module->get_all_modules(); - $data['all_subpermissions']=$this->Module->get_all_subpermissions(); - $this->load->view("employees/form",$data); + $person_info = $this->Employee->get_info($employee_id); + foreach(get_object_vars($person_info) as $property => $value) + { + $person_info->$property = $this->xss_clean($value); + } + $data['person_info'] = $person_info; + + $modules = array(); + foreach($this->Module->get_all_modules()->result() as $module) + { + $module->module_id = $this->xss_clean($module->module_id); + $module->grant = $this->xss_clean($this->Employee->has_grant($module->module_id, $person_info->person_id)); + + $modules[] = $module; + } + $data['all_modules'] = $modules; + + $permissions = array(); + foreach($this->Module->get_all_subpermissions()->result() as $permission) + { + $permission->module_id = $this->xss_clean($permission->module_id); + $permission->permission_id = $this->xss_clean($permission->permission_id); + $permission->grant = $this->xss_clean($this->Employee->has_grant($permission->permission_id, $person_info->person_id)); + + $permissions[] = $permission; + } + $data['all_subpermissions'] = $permissions; + + $this->load->view("employees/form", $data); } /* Inserts/updates an employee */ - function save($employee_id=-1) + public function save($employee_id = -1) { $person_data = array( - 'first_name'=>$this->input->post('first_name'), - 'last_name'=>$this->input->post('last_name'), - 'gender'=>$this->input->post('gender'), - 'email'=>$this->input->post('email'), - 'phone_number'=>$this->input->post('phone_number'), - 'address_1'=>$this->input->post('address_1'), - 'address_2'=>$this->input->post('address_2'), - 'city'=>$this->input->post('city'), - 'state'=>$this->input->post('state'), - 'zip'=>$this->input->post('zip'), - 'country'=>$this->input->post('country'), - 'comments'=>$this->input->post('comments') + 'first_name' => $this->input->post('first_name'), + 'last_name' => $this->input->post('last_name'), + 'gender' => $this->input->post('gender'), + 'email' => $this->input->post('email'), + 'phone_number' => $this->input->post('phone_number'), + 'address_1' => $this->input->post('address_1'), + 'address_2' => $this->input->post('address_2'), + 'city' => $this->input->post('city'), + 'state' => $this->input->post('state'), + 'zip' => $this->input->post('zip'), + 'country' => $this->input->post('country'), + 'comments' => $this->input->post('comments'), ); - $grants_data = $this->input->post('grants') != null ? $this->input->post('grants') : array(); + $grants_data = $this->input->post('grants') != NULL ? $this->input->post('grants') : array(); //Password has been changed OR first time password set - if ( $this->input->post('password') != '' ) + if($this->input->post('password') != '') { - $employee_data=array( - 'username'=>$this->input->post('username'), - 'password'=>md5($this->input->post('password')) + $employee_data = array( + 'username' => $this->input->post('username'), + 'password' => password_hash($this->input->post('password'), PASSWORD_DEFAULT), + 'hash_version' => 2 ); } else //Password not changed { - $employee_data=array('username'=>$this->input->post('username')); + $employee_data = array('username' => $this->input->post('username')); } - if($this->Employee->save_employee($person_data,$employee_data,$grants_data,$employee_id)) + if($this->Employee->save_employee($person_data, $employee_data, $grants_data, $employee_id)) { + $person_data = $this->xss_clean($person_data); + $employee_data = $this->xss_clean($employee_data); + //New employee - if($employee_id==-1) + if($employee_id == -1) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_adding').' '. - $person_data['first_name'].' '.$person_data['last_name'],'id'=>$employee_data['person_id'])); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('employees_successful_adding').' '. + $person_data['first_name'].' '.$person_data['last_name'], 'id' => $employee_data['person_id'])); } - else //previous employee + else //Existing employee { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_updating').' '. - $person_data['first_name'].' '.$person_data['last_name'],'id'=>$employee_id)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('employees_successful_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'], 'id' => $employee_id)); } } else//failure - { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('employees_error_adding_updating').' '. - $person_data['first_name'].' '.$person_data['last_name'],'id'=>-1)); + { + $person_data = $this->xss_clean($person_data); + + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('employees_error_adding_updating').' '. + $person_data['first_name'].' '.$person_data['last_name'], 'id' => -1)); } } /* This deletes employees from the employees table */ - function delete() + public function delete() { - $employees_to_delete=$this->input->post('ids'); - + $employees_to_delete = $this->xss_clean($this->input->post('ids')); + if($this->Employee->delete_list($employees_to_delete)) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_deleted').' '. - count($employees_to_delete).' '.$this->lang->line('employees_one_or_multiple'))); + echo json_encode(array('success' => TRUE,'message' => $this->lang->line('employees_successful_deleted').' '. + count($employees_to_delete).' '.$this->lang->line('employees_one_or_multiple'))); } else { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('employees_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE,'message' => $this->lang->line('employees_cannot_be_deleted'))); } } } diff --git a/application/controllers/Giftcards.php b/application/controllers/Giftcards.php index f5d7bfbb3..50241b65c 100644 --- a/application/controllers/Giftcards.php +++ b/application/controllers/Giftcards.php @@ -1,19 +1,17 @@ -get_controller_name(); - $data['table_headers'] = get_giftcards_manage_table_headers(); + $data['table_headers'] = $this->xss_clean(get_giftcards_manage_table_headers()); $this->load->view('giftcards/manage', $data); } @@ -21,13 +19,13 @@ class Giftcards extends Secure_area implements iData_controller /* Returns Giftcards table data rows. This will be called with AJAX. */ - function search() + public function search() { $search = $this->input->get('search'); - $limit = $this->input->get('limit'); + $limit = $this->input->get('limit'); $offset = $this->input->get('offset'); - $sort = $this->input->get('sort'); - $order = $this->input->get('order'); + $sort = $this->input->get('sort'); + $order = $this->input->get('order'); $giftcards = $this->Giftcard->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Giftcard->get_found_rows($search); @@ -37,78 +35,90 @@ class Giftcards extends Secure_area implements iData_controller { $data_rows[] = get_giftcard_data_row($giftcard, $this); } + + $data_rows = $this->xss_clean($data_rows); + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } /* Gives search suggestions based on what is being searched for */ - function suggest_search() + public function suggest_search() { - $suggestions = $this->Giftcard->get_search_suggestions($this->input->post('term')); + $suggestions = $this->xss_clean($this->Giftcard->get_search_suggestions($this->input->post('term'))); + echo json_encode($suggestions); } - function get_row($row_id) + public function get_row($row_id) { - $data_row = get_giftcard_data_row($this->Giftcard->get_info($row_id), $this); + $data_row = $this->xss_clean(get_giftcard_data_row($this->Giftcard->get_info($row_id), $this)); + echo json_encode($data_row); } - function view($giftcard_id=-1) + public function view($giftcard_id = -1) { $giftcard_info = $this->Giftcard->get_info($giftcard_id); - $person_name=$giftcard_id > 0? $giftcard_info->first_name . ' ' . $giftcard_info->last_name : ''; - $data['selected_person_name'] = $giftcard_id > 0 && isset($giftcard_info->person_id) ? $person_name : ''; - $data['selected_person_id'] = $giftcard_info->person_id; - $data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : $this->Giftcard->get_max_number()->giftcard_number + 1; - $data['giftcard_info'] = $giftcard_info; - $this->load->view("giftcards/form",$data); + + $data['selected_person_name'] = ($giftcard_id > 0 && isset($giftcard_info->person_id)) ? $giftcard_info->first_name . ' ' . $giftcard_info->last_name : ''; + $data['selected_person_id'] = $giftcard_info->person_id; + $data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : $this->Giftcard->get_max_number()->giftcard_number + 1; + $data['giftcard_id'] = $giftcard_id; + $data['giftcard_value'] = $giftcard_info->value; + + $data = $this->xss_clean($data); + + $this->load->view("giftcards/form", $data); } - function save($giftcard_id=-1) + public function save($giftcard_id = -1) { $giftcard_data = array( 'record_time' => date('Y-m-d H:i:s'), - 'giftcard_number'=>$this->input->post('giftcard_number', TRUE), - 'value'=>$this->input->post('value', TRUE), - 'person_id'=>$this->input->post('person_id', TRUE) ? $this->input->post('person_id') : null + 'giftcard_number' => $this->input->post('giftcard_number'), + 'value' => parse_decimals($this->input->post('value')), + 'person_id' => $this->input->post('person_id') == '' ? NULL : $this->input->post('person_id') ); - if( $this->Giftcard->save( $giftcard_data, $giftcard_id ) ) + if($this->Giftcard->save($giftcard_data, $giftcard_id)) { + $giftcard_data = $this->xss_clean($giftcard_data); + //New giftcard - if($giftcard_id==-1) + if($giftcard_id == -1) { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('giftcards_successful_adding').' '. - $giftcard_data['giftcard_number'], 'id'=>$giftcard_data['giftcard_id'])); - $giftcard_id = $giftcard_data['giftcard_id']; + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('giftcards_successful_adding').' '. + $giftcard_data['giftcard_number'], 'id' => $giftcard_data['giftcard_id'])); } - else //previous giftcard + else //Existing giftcard { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('giftcards_successful_updating').' '. - $giftcard_data['giftcard_number'], 'id'=>$giftcard_id)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('giftcards_successful_updating').' '. + $giftcard_data['giftcard_number'], 'id' => $giftcard_id)); } } - else//failure + else //failure { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('giftcards_error_adding_updating').' '. - $giftcard_data['giftcard_number'], 'id'=>-1)); + $giftcard_data = $this->xss_clean($giftcard_data); + + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('giftcards_error_adding_updating').' '. + $giftcard_data['giftcard_number'], 'id' => -1)); } } - function delete() + public function delete() { - $giftcards_to_delete=$this->input->post('ids'); + $giftcards_to_delete = $this->xss_clean($this->input->post('ids')); if($this->Giftcard->delete_list($giftcards_to_delete)) { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('giftcards_successful_deleted').' '. + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('giftcards_successful_deleted').' '. count($giftcards_to_delete).' '.$this->lang->line('giftcards_one_or_multiple'))); } else { - echo json_encode(array('success'=>false, 'message'=>$this->lang->line('giftcards_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('giftcards_cannot_be_deleted'))); } } } diff --git a/application/controllers/Home.php b/application/controllers/Home.php index ed78c8161..a2b812dfa 100644 --- a/application/controllers/Home.php +++ b/application/controllers/Home.php @@ -1,20 +1,23 @@ -load->view("home"); + $this->load->view('home'); } - - function logout() + + public function logout() { + $this->track_page('logout', 'logout'); + $this->Employee->logout(); } } diff --git a/application/controllers/Item_kits.php b/application/controllers/Item_kits.php index 5071cb9e4..07498a20f 100644 --- a/application/controllers/Item_kits.php +++ b/application/controllers/Item_kits.php @@ -1,23 +1,29 @@ -total_cost_price = 0; $item_kit->total_unit_price = 0; - foreach ($this->Item_kit_items->get_info($item_kit->item_kit_id) as $item_kit_item) + foreach($this->Item_kit_items->get_info($item_kit->item_kit_id) as $item_kit_item) { $item_info = $this->Item->get_info($item_kit_item['item_id']); + foreach(get_object_vars($item_info) as $property => $value) + { + $item_info->$property = $this->xss_clean($value); + } $item_kit->total_cost_price += $item_info->cost_price * $item_kit_item['quantity']; $item_kit->total_unit_price += $item_info->unit_price * $item_kit_item['quantity']; @@ -26,10 +32,9 @@ class Item_kits extends Secure_area implements iData_controller return $item_kit; } - function index() + public function index() { - $data['controller_name'] = $this->get_controller_name(); - $data['table_headers'] = get_item_kits_manage_table_headers(); + $data['table_headers'] = $this->xss_clean(get_item_kits_manage_table_headers()); $this->load->view('item_kits/manage', $data); } @@ -37,13 +42,13 @@ class Item_kits extends Secure_area implements iData_controller /* Returns Item kits table data rows. This will be called with AJAX. */ - function search() + public function search() { $search = $this->input->get('search'); - $limit = $this->input->get('limit'); + $limit = $this->input->get('limit'); $offset = $this->input->get('offset'); - $sort = $this->input->get('sort'); - $order = $this->input->get('order'); + $sort = $this->input->get('sort'); + $order = $this->input->get('order'); $item_kits = $this->Item_kit->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Item_kit->get_found_rows($search); @@ -52,49 +57,70 @@ class Item_kits extends Secure_area implements iData_controller foreach($item_kits->result() as $item_kit) { // calculate the total cost and retail price of the Kit so it can be printed out in the manage table - $item_kit = $this->add_totals_to_item_kit($item_kit); + $item_kit = $this->_add_totals_to_item_kit($item_kit); $data_rows[] = get_item_kit_data_row($item_kit, $this); } + $data_rows = $this->xss_clean($data_rows); + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } - function suggest_search() + public function suggest_search() { - $suggestions = $this->Item_kit->get_search_suggestions($this->input->post('term')); + $suggestions = $this->xss_clean($this->Item_kit->get_search_suggestions($this->input->post('term'))); + echo json_encode($suggestions); } - function get_row($row_id) + public function get_row($row_id) { // calculate the total cost and retail price of the Kit so it can be added to the table refresh - $item_kit = $this->add_totals_to_item_kit($this->Item_kit->get_info($row_id)); + $item_kit = $this->_add_totals_to_item_kit($this->Item_kit->get_info($row_id)); echo json_encode(get_item_kit_data_row($item_kit, $this)); } - - function view($item_kit_id=-1) + + public function view($item_kit_id = -1) { - $data['item_kit_info'] = $this->Item_kit->get_info($item_kit_id); + $info = $this->Item_kit->get_info($item_kit_id); + foreach(get_object_vars($info) as $property => $value) + { + $info->$property = $this->xss_clean($value); + } + $data['item_kit_info'] = $info; + + $items = array(); + foreach($this->Item_kit_items->get_info($item_kit_id) as $item_kit_item) + { + $item['name'] = $this->xss_clean($this->Item->get_info($item_kit_item['item_id'])->name); + $item['item_id'] = $this->xss_clean($item_kit_item['item_id']); + $item['quantity'] = $this->xss_clean($item_kit_item['quantity']); + + $items[] = $item; + } + $data['item_kit_items'] = $items; + $this->load->view("item_kits/form", $data); } - function save($item_kit_id=-1) + public function save($item_kit_id = -1) { $item_kit_data = array( 'name' => $this->input->post('name'), 'description' => $this->input->post('description') ); - if ($this->Item_kit->save($item_kit_data, $item_kit_id)) + if($this->Item_kit->save($item_kit_data, $item_kit_id)) { $success = TRUE; //New item kit - if ($item_kit_id==-1) { + if ($item_kit_id == -1) + { $item_kit_id = $item_kit_data['item_kit_id']; } - if ( $this->input->post('item_kit_item') != null ) + if($this->input->post('item_kit_item') != NULL) { $item_kit_items = array(); foreach($this->input->post('item_kit_item') as $item_id => $quantity) @@ -107,46 +133,52 @@ class Item_kits extends Secure_area implements iData_controller $success = $this->Item_kit_items->save($item_kit_items, $item_kit_id); } - echo json_encode(array('success'=>$success, - 'message'=>$this->lang->line('item_kits_successful_adding').' '.$item_kit_data['name'], - 'id'=>$item_kit_id)); + + $item_kit_data = $this->xss_clean($item_kit_data); + + echo json_encode(array('success' => $success, + 'message' => $this->lang->line('item_kits_successful_adding').' '.$item_kit_data['name'], 'id' => $item_kit_id)); } else//failure { - echo json_encode(array('success'=>false, - 'message'=>$this->lang->line('item_kits_error_adding_updating').' '.$item_kit_data['name'], - 'id'=>-1)); + $item_kit_data = $this->xss_clean($item_kit_data); + + echo json_encode(array('success' => FALSE, + 'message' => $this->lang->line('item_kits_error_adding_updating').' '.$item_kit_data['name'], 'id' => -1)); } } - function delete() + public function delete() { - $item_kits_to_delete = $this->input->post('ids'); + $item_kits_to_delete = $this->xss_clean($this->input->post('ids')); - if ($this->Item_kit->delete_list($item_kits_to_delete)) + if($this->Item_kit->delete_list($item_kits_to_delete)) { - echo json_encode(array('success'=>true, - 'message'=>$this->lang->line('item_kits_successful_deleted').' '.count($item_kits_to_delete).' '.$this->lang->line('item_kits_one_or_multiple'))); + echo json_encode(array('success' => TRUE, + 'message' => $this->lang->line('item_kits_successful_deleted').' '.count($item_kits_to_delete).' '.$this->lang->line('item_kits_one_or_multiple'))); } else { - echo json_encode(array('success'=>false, - 'message'=>$this->lang->line('item_kits_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE, + 'message' => $this->lang->line('item_kits_cannot_be_deleted'))); } } - function generate_barcodes($item_kit_ids) + public function generate_barcodes($item_kit_ids) { $this->load->library('barcode_lib'); $result = array(); $item_kit_ids = explode(':', $item_kit_ids); - foreach ($item_kit_ids as $item_kid_id) + foreach($item_kit_ids as $item_kid_id) { // calculate the total cost and retail price of the Kit so it can be added to the barcode text at the bottom - $item_kit = $this->add_totals_to_item_kit($this->Item_kit->get_info($item_kid_id)); + $item_kit = $this->_add_totals_to_item_kit($this->Item_kit->get_info($item_kid_id)); + + $item_kid_id = 'KIT '. urldecode($item_kid_id); - $result[] = array('name'=>$item_kit->name, 'item_id'=>urldecode($item_kid_id), 'item_number'=>urldecode($item_kid_id), 'cost_price'=>$item_kit->total_cost_price, 'unit_price'=>$item_kit->total_unit_price); + $result[] = array('name' => $item_kit->name, 'item_id' => $item_kid_id, 'item_number' => $item_kid_id, + 'cost_price' => $item_kit->total_cost_price, 'unit_price' => $item_kit->total_unit_price); } $data['items'] = $result; @@ -158,7 +190,7 @@ class Item_kits extends Secure_area implements iData_controller $barcode_config['barcode_type'] = 'Code128'; } $data['barcode_config'] = $barcode_config; - + // display barcodes $this->load->view("barcodes/barcode_sheet", $data); } diff --git a/application/controllers/Items.php b/application/controllers/Items.php index 31fc7ee7b..39c93e5f6 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -1,20 +1,22 @@ -load->library('item_lib'); } - function index() + public function index() { - $stock_location = $this->item_lib->get_item_location(); - $stock_locations = $this->Stock_location->get_allowed_locations(); - $data['controller_name'] = $this->get_controller_name(); + $data['table_headers'] = $this->xss_clean(get_items_manage_table_headers()); + + $data['stock_location'] = $this->xss_clean($this->item_lib->get_item_location()); + $data['stock_locations'] = $this->xss_clean($this->Stock_location->get_allowed_locations()); // filters that will be loaded in the multiselect dropdown $data['filters'] = array('empty_upc' => $this->lang->line('items_empty_upc_items'), @@ -24,18 +26,13 @@ class Items extends Secure_area implements iData_controller 'search_custom' => $this->lang->line('items_search_custom_items'), 'is_deleted' => $this->lang->line('items_is_deleted')); - $data['stock_location'] = $stock_location; - $data['stock_locations'] = $stock_locations; - - $data['table_headers'] = get_items_manage_table_headers(); - $this->load->view('items/manage', $data); } /* Returns Items table data rows. This will be called with AJAX. */ - function search() + public function search() { $search = $this->input->get('search'); $limit = $this->input->get('limit'); @@ -56,7 +53,7 @@ class Items extends Secure_area implements iData_controller 'is_deleted' => FALSE); // check if any filter is set in the multiselect dropdown - $filledup = array_fill_keys($this->input->get('filters'), true); + $filledup = array_fill_keys($this->input->get('filters'), TRUE); $filters = array_merge($filters, $filledup); $items = $this->Item->search($search, $filters, $limit, $offset, $sort, $order); @@ -65,23 +62,24 @@ class Items extends Secure_area implements iData_controller $data_rows = array(); foreach($items->result() as $item) { - $data_rows[] = get_item_data_row($item, $this); + $data_rows[] = $this->xss_clean(get_item_data_row($item, $this)); } + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } - function pic_thumb($pic_id) + public function pic_thumb($pic_id) { $this->load->helper('file'); $this->load->library('image_lib'); - $base_path = "uploads/item_pics/" . $pic_id ; - $images = glob ($base_path. "*"); - if (sizeof($images) > 0) + $base_path = './uploads/item_pics/' . $pic_id; + $images = glob($base_path . '.*'); + if(sizeof($images) > 0) { $image_path = $images[0]; $ext = pathinfo($image_path, PATHINFO_EXTENSION); - $thumb_path = $base_path . $this->image_lib->thumb_marker.'.'.$ext; - if (sizeof($images) < 2) + $thumb_path = $base_path . $this->image_lib->thumb_marker . '.' . $ext; + if(sizeof($images) < 2) { $config['image_library'] = 'gd2'; $config['source_image'] = $image_path; @@ -101,26 +99,18 @@ class Items extends Secure_area implements iData_controller /* Gives search suggestions based on what is being searched for */ - function suggest_search() + public function suggest_search() { - $suggestions = $this->Item->get_search_suggestions($this->input->post_get('term'), - array( - 'search_custom' => $this->input->post('search_custom'), - 'is_deleted' => $this->input->post('is_deleted') != null - ), - FALSE); + $suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'), + array('search_custom' => $this->input->post('search_custom'), 'is_deleted' => $this->input->post('is_deleted') != NULL), FALSE)); echo json_encode($suggestions); } - function suggest() + public function suggest() { - $suggestions = $this->Item->get_search_suggestions($this->input->post_get('term'), - array( - 'search_custom' => FALSE, - 'is_deleted' => FALSE - ), - TRUE); + $suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'), + array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE)); echo json_encode($suggestions); } @@ -128,9 +118,9 @@ class Items extends Secure_area implements iData_controller /* Gives search suggestions based on what is being searched for */ - function suggest_category() + public function suggest_category() { - $suggestions = $this->Item->get_category_suggestions($this->input->get('term')); + $suggestions = $this->xss_clean($this->Item->get_category_suggestions($this->input->get('term'))); echo json_encode($suggestions); } @@ -138,9 +128,9 @@ class Items extends Secure_area implements iData_controller /* Gives search suggestions based on what is being searched for */ - function suggest_location() + public function suggest_location() { - $suggestions = $this->Item->get_location_suggestions($this->input->get('term')); + $suggestions = $this->xss_clean($this->Item->get_location_suggestions($this->input->get('term'))); echo json_encode($suggestions); } @@ -148,191 +138,216 @@ class Items extends Secure_area implements iData_controller /* Gives search suggestions based on what is being searched for */ - function suggest_custom() + public function suggest_custom() { - $suggestions = $this->Item->get_custom_suggestions($this->input->post('term'), $this->input->post('field_no')); + $suggestions = $this->xss_clean($this->Item->get_custom_suggestions($this->input->post('term'), $this->input->post('field_no'))); echo json_encode($suggestions); } - function get_row($item_ids) + public function get_row($item_ids) { $item_infos = $this->Item->get_multiple_info(explode(":", $item_ids), $this->item_lib->get_item_location()); + $result = array(); foreach($item_infos->result() as $item_info) { - $result[$item_info->item_id] = get_item_data_row($item_info,$this); + $result[$item_info->item_id] = $this->xss_clean(get_item_data_row($item_info, $this)); } + echo json_encode($result); } - function view($item_id=-1) + public function view($item_id = -1) { - $item_info = $this->Item->get_info($item_id); - - $data['item_tax_info'] = $this->Item_taxes->get_info($item_id); + $data['item_tax_info'] = $this->xss_clean($this->Item_taxes->get_info($item_id)); $data['default_tax_1_rate'] = ''; $data['default_tax_2_rate'] = ''; - if($item_id==-1) + $item_info = $this->Item->get_info($item_id); + foreach(get_object_vars($item_info) as $property => $value) { - $data['default_tax_1_rate'] = $this->Appconfig->get('default_tax_1_rate'); - $data['default_tax_2_rate'] = $this->Appconfig->get('default_tax_2_rate'); + $item_info->$property = $this->xss_clean($value); + } + + if($item_id == -1) + { + $data['default_tax_1_rate'] = $this->config->item('default_tax_1_rate'); + $data['default_tax_2_rate'] = $this->config->item('default_tax_2_rate'); $item_info->receiving_quantity = 0; $item_info->reorder_level = 0; } $data['item_info'] = $item_info; - - $suppliers = array(''=>$this->lang->line('items_none')); + + $suppliers = array('' => $this->lang->line('items_none')); foreach($this->Supplier->get_all()->result_array() as $row) { - $suppliers[$row['person_id']] = $row['company_name']; + $suppliers[$this->xss_clean($row['person_id'])] = $this->xss_clean($row['company_name']); } $data['suppliers'] = $suppliers; $data['selected_supplier'] = $item_info->supplier_id; $data['logo_exists'] = $item_info->pic_id != ''; - $images = glob("uploads/item_pics/" . $item_info->pic_id . ".*"); - $data['image_path'] = sizeof($images) > 0 ? base_url($images[0]) : ''; + if (!empty($item_info->pic_id)) + { + $images = glob('./uploads/item_pics/' . $item_info->pic_id . '.*'); + $data['image_path'] = sizeof($images) > 0 ? base_url($images[0]) : ''; + } - $locations_data = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($locations_data as $location) + $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); + foreach($stock_locations as $location) { - $quantity = $this->Item_quantity->get_item_quantity($item_id,$location['location_id'])->quantity; + $location = $this->xss_clean($location); + + $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); $quantity = ($item_id == -1) ? 0 : $quantity; - $location_array[$location['location_id']] = array('location_name'=>$location['location_name'], 'quantity'=>$quantity); + $location_array[$location['location_id']] = array('location_name' => $location['location_name'], 'quantity' => $quantity); $data['stock_locations'] = $location_array; } - $this->load->view("items/form", $data); + $this->load->view('items/form', $data); } - function inventory($item_id=-1) + public function inventory($item_id = -1) { - $data['item_info'] = $this->Item->get_info($item_id); - + $item_info = $this->Item->get_info($item_id); + foreach(get_object_vars($item_info) as $property => $value) + { + $item_info->$property = $this->xss_clean($value); + } + $data['item_info'] = $item_info; + $data['stock_locations'] = array(); $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($stock_locations as $location_data) - { - $data['stock_locations'][$location_data['location_id']] = $location_data['location_name']; - $data['item_quantities'][$location_data['location_id']] = $this->Item_quantity->get_item_quantity($item_id,$location_data['location_id'])->quantity; - } - - $this->load->view("items/form_inventory", $data); + foreach($stock_locations as $location) + { + $location = $this->xss_clean($location); + $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); + + $data['stock_locations'][$location['location_id']] = $location['location_name']; + $data['item_quantities'][$location['location_id']] = $quantity; + } + + $this->load->view('items/form_inventory', $data); } - function count_details($item_id=-1) + public function count_details($item_id = -1) { - $data['item_info'] = $this->Item->get_info($item_id); - + $item_info = $this->Item->get_info($item_id); + foreach(get_object_vars($item_info) as $property => $value) + { + $item_info->$property = $this->xss_clean($value); + } + $data['item_info'] = $item_info; + $data['stock_locations'] = array(); $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($stock_locations as $location_data) - { - $data['stock_locations'][$location_data['location_id']] = $location_data['location_name']; - $data['item_quantities'][$location_data['location_id']] = $this->Item_quantity->get_item_quantity($item_id,$location_data['location_id'])->quantity; - } - - $this->load->view("items/form_count_details", $data); + foreach($stock_locations as $location) + { + $location = $this->xss_clean($location); + $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); + + $data['stock_locations'][$location['location_id']] = $location['location_name']; + $data['item_quantities'][$location['location_id']] = $quantity; + } + + $this->load->view('items/form_count_details', $data); } - function generate_barcodes($item_ids) + public function generate_barcodes($item_ids) { $this->load->library('barcode_lib'); - $result = array(); $item_ids = explode(':', $item_ids); $result = $this->Item->get_multiple_info($item_ids, $this->item_lib->get_item_location())->result_array(); $config = $this->barcode_lib->get_barcode_config(); $data['barcode_config'] = $config; - + // check the list of items to see if any item_number field is empty foreach($result as &$item) { - // update the UPC/EAN/ISBN field if empty / null with the newly generated barcode - if (empty($item['item_number']) && $this->Appconfig->get('barcode_generate_if_empty')) + $item = $this->xss_clean($item); + + // update the UPC/EAN/ISBN field if empty / NULL with the newly generated barcode + if(empty($item['item_number']) && $this->config->item('barcode_generate_if_empty')) { // get the newly generated barcode $barcode_instance = Barcode_lib::barcode_instance($item, $config); $item['item_number'] = $barcode_instance->getData(); - // remove from item any suppliers table info to avoid save failure because of unknown fields - // WARNING: if suppliers table is changed this list needs to be upgraded, which makes the matter a bit tricky to maintain - unset($item['person_id']); - unset($item['company_name']); - unset($item['account_number']); - unset($item['agency_name']); + $save_item = array('item_number' => $item['item_number']); + // update the item in the database in order to save the UPC/EAN/ISBN field - $this->Item->save($item, $item['item_id']); + $this->Item->save($save_item, $item['item_id']); } } $data['items'] = $result; // display barcodes - $this->load->view("barcodes/barcode_sheet", $data); + $this->load->view('barcodes/barcode_sheet', $data); } - function bulk_edit() + public function bulk_edit() { - $data = array(); $suppliers = array('' => $this->lang->line('items_none')); foreach($this->Supplier->get_all()->result_array() as $row) { + $row = $this->xss_clean($row); + $suppliers[$row['person_id']] = $row['company_name']; } $data['suppliers'] = $suppliers; $data['allow_alt_description_choices'] = array( - ''=>$this->lang->line('items_do_nothing'), - 1 =>$this->lang->line('items_change_all_to_allow_alt_desc'), - 0 =>$this->lang->line('items_change_all_to_not_allow_allow_desc')); + '' => $this->lang->line('items_do_nothing'), + 1 => $this->lang->line('items_change_all_to_allow_alt_desc'), + 0 => $this->lang->line('items_change_all_to_not_allow_allow_desc')); $data['serialization_choices'] = array( - ''=>$this->lang->line('items_do_nothing'), - 1 =>$this->lang->line('items_change_all_to_serialized'), - 0 =>$this->lang->line('items_change_all_to_unserialized')); + '' => $this->lang->line('items_do_nothing'), + 1 => $this->lang->line('items_change_all_to_serialized'), + 0 => $this->lang->line('items_change_all_to_unserialized')); - $this->load->view("items/form_bulk", $data); + $this->load->view('items/form_bulk', $data); } - function save($item_id=-1) + public function save($item_id = -1) { $upload_success = $this->_handle_image_upload(); $upload_data = $this->upload->data(); //Save item data $item_data = array( - 'name'=>$this->input->post('name'), - 'description'=>$this->input->post('description'), - 'category'=>$this->input->post('category'), - 'supplier_id'=>$this->input->post('supplier_id') == '' ? null : $this->input->post('supplier_id'), - 'item_number'=>$this->input->post('item_number') == '' ? null : $this->input->post('item_number'), - 'cost_price'=>$this->input->post('cost_price'), - 'unit_price'=>$this->input->post('unit_price'), - 'reorder_level'=>$this->input->post('reorder_level'), - 'receiving_quantity'=>$this->input->post('receiving_quantity'), - 'allow_alt_description'=>$this->input->post('allow_alt_description') != null, - 'is_serialized'=>$this->input->post('is_serialized') != null, - 'deleted'=>$this->input->post('is_deleted') != null, - 'custom1'=>$this->input->post('custom1') == null ? '' : $this->input->post('custom1'), - 'custom2'=>$this->input->post('custom2') == null ? '' : $this->input->post('custom2'), - 'custom3'=>$this->input->post('custom3') == null ? '' : $this->input->post('custom3'), - 'custom4'=>$this->input->post('custom4') == null ? '' : $this->input->post('custom4'), - 'custom5'=>$this->input->post('custom5') == null ? '' : $this->input->post('custom5'), - 'custom6'=>$this->input->post('custom6') == null ? '' : $this->input->post('custom6'), - 'custom7'=>$this->input->post('custom7') == null ? '' : $this->input->post('custom7'), - 'custom8'=>$this->input->post('custom8') == null ? '' : $this->input->post('custom8'), - 'custom9'=>$this->input->post('custom9') == null ? '' : $this->input->post('custom9'), - 'custom10'=>$this->input->post('custom10') == null ? '' : $this->input->post('custom10') + 'name' => $this->input->post('name'), + 'description' => $this->input->post('description'), + 'category' => $this->input->post('category'), + 'supplier_id' => $this->input->post('supplier_id') == '' ? NULL : $this->input->post('supplier_id'), + 'item_number' => $this->input->post('item_number') == '' ? NULL : $this->input->post('item_number'), + 'cost_price' => parse_decimals($this->input->post('cost_price')), + 'unit_price' => parse_decimals($this->input->post('unit_price')), + 'reorder_level' => parse_decimals($this->input->post('reorder_level')), + 'receiving_quantity' => parse_decimals($this->input->post('receiving_quantity')), + 'allow_alt_description' => $this->input->post('allow_alt_description') != NULL, + 'is_serialized' => $this->input->post('is_serialized') != NULL, + 'deleted' => $this->input->post('is_deleted') != NULL, + 'custom1' => $this->input->post('custom1') == NULL ? '' : $this->input->post('custom1'), + 'custom2' => $this->input->post('custom2') == NULL ? '' : $this->input->post('custom2'), + 'custom3' => $this->input->post('custom3') == NULL ? '' : $this->input->post('custom3'), + 'custom4' => $this->input->post('custom4') == NULL ? '' : $this->input->post('custom4'), + 'custom5' => $this->input->post('custom5') == NULL ? '' : $this->input->post('custom5'), + 'custom6' => $this->input->post('custom6') == NULL ? '' : $this->input->post('custom6'), + 'custom7' => $this->input->post('custom7') == NULL ? '' : $this->input->post('custom7'), + 'custom8' => $this->input->post('custom8') == NULL ? '' : $this->input->post('custom8'), + 'custom9' => $this->input->post('custom9') == NULL ? '' : $this->input->post('custom9'), + 'custom10' => $this->input->post('custom10') == NULL ? '' : $this->input->post('custom10') ); - if (!empty($upload_data['orig_name'])) + if(!empty($upload_data['orig_name'])) { // XSS file image sanity check - if ($this->security->xss_clean($upload_data['raw_name'], TRUE) === TRUE) + if($this->xss_clean($upload_data['raw_name'], TRUE) === TRUE) { $item_data['pic_id'] = $upload_data['raw_name']; } @@ -341,12 +356,12 @@ class Items extends Secure_area implements iData_controller $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; $cur_item_info = $this->Item->get_info($item_id); - if($this->Item->save($item_data,$item_id)) + if($this->Item->save($item_data, $item_id)) { $success = TRUE; $new_item = FALSE; //New item - if ($item_id==-1) + if($item_id == -1) { $item_id = $item_data['item_id']; $new_item = TRUE; @@ -355,64 +370,67 @@ class Items extends Secure_area implements iData_controller $items_taxes_data = array(); $tax_names = $this->input->post('tax_names'); $tax_percents = $this->input->post('tax_percents'); - for($k = 0; $k < count($tax_percents); $k++) + $count = count($tax_percents); + for ($k = 0; $k < $count; ++$k) { - if (is_numeric($tax_percents[$k])) + $tax_percentage = parse_decimals($tax_percents[$k]); + if(is_numeric($tax_percentage)) { - $items_taxes_data[] = array('name'=>$tax_names[$k], 'percent'=>$tax_percents[$k] ); + $items_taxes_data[] = array('name' => $tax_names[$k], 'percent' => $tax_percentage); } } $success &= $this->Item_taxes->save($items_taxes_data, $item_id); //Save item quantity $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($stock_locations as $location_data) + foreach($stock_locations as $location) { - $updated_quantity = $this->input->post('quantity_' . $location_data['location_id']); - $location_detail = array('item_id'=>$item_id, - 'location_id'=>$location_data['location_id'], - 'quantity'=>$updated_quantity); - $item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location_data['location_id']); - if ($item_quantity->quantity != $updated_quantity || $new_item) + $updated_quantity = parse_decimals($this->input->post('quantity_' . $location['location_id'])); + $location_detail = array('item_id' => $item_id, + 'location_id' => $location['location_id'], + 'quantity' => $updated_quantity); + $item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location['location_id']); + if($item_quantity->quantity != $updated_quantity || $new_item) { - $success &= $this->Item_quantity->save($location_detail, $item_id, $location_data['location_id']); + $success &= $this->Item_quantity->save($location_detail, $item_id, $location['location_id']); $inv_data = array( - 'trans_date'=>date('Y-m-d H:i:s'), - 'trans_items'=>$item_id, - 'trans_user'=>$employee_id, - 'trans_location'=>$location_data['location_id'], - 'trans_comment'=>$this->lang->line('items_manually_editing_of_quantity'), - 'trans_inventory'=>$updated_quantity - $item_quantity->quantity + 'trans_date' => date('Y-m-d H:i:s'), + 'trans_items' => $item_id, + 'trans_user' => $employee_id, + 'trans_location' => $location['location_id'], + 'trans_comment' => $this->lang->line('items_manually_editing_of_quantity'), + 'trans_inventory' => $updated_quantity - $item_quantity->quantity ); $success &= $this->Inventory->insert($inv_data); } } + if($success && $upload_success) { - $success_message = $this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) .' '. $item_data['name']; + $message = $this->xss_clean($this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) . ' ' . $item_data['name']); - echo json_encode(array('success'=>true, 'message'=>$success_message, 'id'=>$item_id)); + echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id)); } else { - $error_message = $upload_success ? - $this->lang->line('items_error_adding_updating') .' '. $item_data['name'] : - $this->upload->display_errors(); + $message = $this->xss_clean($upload_success ? $this->lang->line('items_error_adding_updating') . ' ' . $item_data['name'] : strip_tags($this->upload->display_errors())); - echo json_encode(array('success'=>false, 'message'=>$error_message, 'id'=>$item_id)); + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => $item_id)); } } else//failure { - echo json_encode(array('success'=>false, 'message'=>$this->lang->line('items_error_adding_updating').' '.$item_data['name'], 'id'=>-1)); + $message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $item_data['name']); + + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1)); } } - function check_item_number() + public function check_item_number() { - $exists = $this->Item->item_number_exists($this->input->post('item_number'),$this->input->post('item_id')); + $exists = $this->Item->item_number_exists($this->input->post('item_number'), $this->input->post('item_id')); echo !$exists ? 'true' : 'false'; } @@ -424,11 +442,12 @@ class Items extends Secure_area implements iData_controller // load upload library $config = array('upload_path' => './uploads/item_pics/', - 'allowed_types' => 'gif|jpg|png', - 'max_size' => '100', - 'max_width' => '640', - 'max_height' => '480', - 'file_name' => sizeof($map) + 1); + 'allowed_types' => 'gif|jpg|png', + 'max_size' => '100', + 'max_width' => '640', + 'max_height' => '480', + 'file_name' => sizeof($map) + 1 + ); $this->load->library('upload', $config); $this->upload->do_upload('item_image'); @@ -437,54 +456,56 @@ class Items extends Secure_area implements iData_controller public function remove_logo($item_id) { - $item_data = array('pic_id' => null); + $item_data = array('pic_id' => NULL); $result = $this->Item->save($item_data, $item_id); echo json_encode(array('success' => $result)); } - function save_inventory($item_id=-1) + public function save_inventory($item_id = -1) { - $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; $cur_item_info = $this->Item->get_info($item_id); $location_id = $this->input->post('stock_location'); $inv_data = array( - 'trans_date'=>date('Y-m-d H:i:s'), - 'trans_items'=>$item_id, - 'trans_user'=>$employee_id, - 'trans_location'=>$location_id, - 'trans_comment'=>$this->input->post('trans_comment'), - 'trans_inventory'=>$this->input->post('newquantity') + 'trans_date' => date('Y-m-d H:i:s'), + 'trans_items' => $item_id, + 'trans_user' => $employee_id, + 'trans_location' => $location_id, + 'trans_comment' => $this->input->post('trans_comment'), + 'trans_inventory' => parse_decimals($this->input->post('newquantity')) ); $this->Inventory->insert($inv_data); //Update stock quantity - $item_quantity= $this->Item_quantity->get_item_quantity($item_id,$location_id); + $item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location_id); $item_quantity_data = array( - 'item_id'=>$item_id, - 'location_id'=>$location_id, - 'quantity'=>$item_quantity->quantity + $this->input->post('newquantity') + 'item_id' => $item_id, + 'location_id' => $location_id, + 'quantity' => $item_quantity->quantity + parse_decimals($this->input->post('newquantity')) ); - if($this->Item_quantity->save($item_quantity_data,$item_id,$location_id)) - { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_updating').' '. - $cur_item_info->name,'id'=>$item_id)); + if($this->Item_quantity->save($item_quantity_data, $item_id, $location_id)) + { + $message = $this->xss_clean($this->lang->line('items_successful_updating') . ' ' . $cur_item_info->name); + + echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id)); } else//failure - { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_adding_updating').' '. - $cur_item_info->name,'id'=>-1)); + { + $message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $cur_item_info->name); + + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1)); } } - function bulk_update() + public function bulk_update() { - $items_to_update=$this->input->post('item_ids'); + $items_to_update = $this->input->post('item_ids'); $item_data = array(); - foreach($_POST as $key=>$value) + foreach($_POST as $key => $value) { //This field is nullable, so treat it differently if($key == 'supplier_id' && $value != '') @@ -503,15 +524,15 @@ class Items extends Secure_area implements iData_controller $items_taxes_data = array(); $tax_names = $this->input->post('tax_names'); $tax_percents = $this->input->post('tax_percents'); - $tax_updated = false; - - for($k = 0; $k < count($tax_percents); $k++) + $tax_updated = FALSE; + $count = count($tax_percents); + for ($k = 0; $k < $count; ++$k) { - if( !empty($tax_names[$k]) && is_numeric($tax_percents[$k])) + if(!empty($tax_names[$k]) && is_numeric($tax_percents[$k])) { - $tax_updated = true; + $tax_updated = TRUE; - $items_taxes_data[] = array('name'=>$tax_names[$k], 'percent'=>$tax_percents[$k]); + $items_taxes_data[] = array('name' => $tax_names[$k], 'percent' => $tax_percents[$k]); } } @@ -520,92 +541,91 @@ class Items extends Secure_area implements iData_controller $this->Item_taxes->save_multiple($items_taxes_data, $items_to_update); } - echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_bulk_edit'), 'id'=>$items_to_update)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_successful_bulk_edit'), 'id' => $this->xss_clean($items_to_update))); } else { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_updating_multiple'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_error_updating_multiple'))); } } - function delete() + public function delete() { $items_to_delete = $this->input->post('ids'); if($this->Item->delete_list($items_to_delete)) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_deleted').' '. - count($items_to_delete).' '.$this->lang->line('items_one_or_multiple'))); + $message = $this->lang->line('items_successful_deleted') . ' ' . count($items_to_delete) . ' ' . $this->lang->line('items_one_or_multiple'); + echo json_encode(array('success' => TRUE, 'message' => $message)); } else { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_cannot_be_deleted'))); } } - - function excel() + + /* + Items import from excel spreadsheet + */ + public function excel() { - $data = file_get_contents("import_items.csv"); $name = 'import_items.csv'; + $data = file_get_contents('../' . $name); force_download($name, $data); } - function excel_import() + public function excel_import() { - $this->load->view("items/form_excel_import", null); + $this->load->view('items/form_excel_import', NULL); } - function do_excel_import() + public function do_excel_import() { - $msg = 'do_excel_import'; - $failCodes = array(); - - if ($_FILES['file_path']['error'] != UPLOAD_ERR_OK) + if($_FILES['file_path']['error'] != UPLOAD_ERR_OK) { - $msg = $this->lang->line('items_excel_import_failed'); - echo json_encode( array('success'=>false, 'message'=>$msg) ); - - return; + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_failed'))); } else { - if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE) + if(($handle = fopen($_FILES['file_path']['tmp_name'], 'r')) !== FALSE) { // Skip the first row as it's the table description fgetcsv($handle); - - $i=1; - while (($data = fgetcsv($handle)) !== FALSE) + $i = 1; + + $failCodes = array(); + + while(($data = fgetcsv($handle)) !== FALSE) { // XSS file data sanity check - $data = $this->security->xss_clean($data); + $data = $this->xss_clean($data); - if (sizeof($data) >= 23) + if(sizeof($data) >= 23) { $item_data = array( - 'name' => $data[1], - 'description' => $data[11], - 'category' => $data[2], - 'cost_price' => $data[4], - 'unit_price' => $data[5], - 'reorder_level' => $data[10], - 'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : null, - 'allow_alt_description' => $data[12] != '' ? '1' : '0', - 'is_serialized' => $data[13] != '' ? '1' : '0', - 'custom1' => $data[14], - 'custom2' => $data[15], - 'custom3' => $data[16], - 'custom4' => $data[17], - 'custom5' => $data[18], - 'custom6' => $data[19], - 'custom7' => $data[20], - 'custom8' => $data[21], - 'custom9' => $data[22], - 'custom10' => $data[23] + 'name' => $data[1], + 'description' => $data[11], + 'category' => $data[2], + 'cost_price' => $data[4], + 'unit_price' => $data[5], + 'reorder_level' => $data[10], + 'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : NULL, + 'allow_alt_description' => $data[12] != '' ? '1' : '0', + 'is_serialized' => $data[13] != '' ? '1' : '0', + 'custom1' => $data[14], + 'custom2' => $data[15], + 'custom3' => $data[16], + 'custom4' => $data[17], + 'custom5' => $data[18], + 'custom6' => $data[19], + 'custom7' => $data[20], + 'custom8' => $data[21], + 'custom9' => $data[22], + 'custom10' => $data[23] ); $item_number = $data[0]; - $invalidated = false; - if ($item_number != "") + $invalidated = FALSE; + if($item_number != '') { $item_data['item_number'] = $item_number; $invalidated = $this->Item->item_number_exists($item_number); @@ -613,22 +633,22 @@ class Items extends Secure_area implements iData_controller } else { - $invalidated = true; + $invalidated = TRUE; } if(!$invalidated && $this->Item->save($item_data)) { - $items_taxes_data = null; + $items_taxes_data = NULL; //tax 1 - if( is_numeric($data[7]) && $data[6]!='' ) + if(is_numeric($data[7]) && $data[6] != '') { - $items_taxes_data[] = array('name'=>$data[6], 'percent'=>$data[7] ); + $items_taxes_data[] = array('name' => $data[6], 'percent' => $data[7] ); } //tax 2 - if( is_numeric($data[9]) && $data[8]!='' ) + if(is_numeric($data[9]) && $data[8] != '') { - $items_taxes_data[] = array('name'=>$data[8], 'percent'=>$data[9] ); + $items_taxes_data[] = array('name' => $data[8], 'percent' => $data[9] ); } // save tax values @@ -637,9 +657,9 @@ class Items extends Secure_area implements iData_controller $this->Item_taxes->save($items_taxes_data, $item_data['item_id']); } - // quantities & inventory Info - $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; - $emp_info=$this->Employee->get_info($employee_id); + // quantities & inventory Info + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; + $emp_info = $this->Employee->get_info($employee_id); $comment ='Qty CSV Imported'; $cols = count($data); @@ -649,9 +669,9 @@ class Items extends Secure_area implements iData_controller for ($col = 24; $col < $cols; $col = $col + 2) { $location_id = $data[$col]; - if (array_key_exists($location_id, $allowed_locations)) + if(array_key_exists($location_id, $allowed_locations)) { - $item_quantity_data = array ( + $item_quantity_data = array( 'item_id' => $item_data['item_id'], 'location_id' => $location_id, 'quantity' => $data[$col + 1], @@ -659,11 +679,11 @@ class Items extends Secure_area implements iData_controller $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id); $excel_data = array( - 'trans_items'=>$item_data['item_id'], - 'trans_user'=>$employee_id, - 'trans_comment'=>$comment, - 'trans_location'=>$data[$col], - 'trans_inventory'=>$data[$col + 1] + 'trans_items' => $item_data['item_id'], + 'trans_user' => $employee_id, + 'trans_comment' => $comment, + 'trans_location' => $data[$col], + 'trans_inventory' => $data[$col + 1] ); $this->Inventory->insert($excel_data); @@ -686,11 +706,11 @@ class Items extends Secure_area implements iData_controller $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $data[$col]); $excel_data = array( - 'trans_items'=>$item_data['item_id'], - 'trans_user'=>$employee_id, - 'trans_comment'=>$comment, - 'trans_location'=>$location_id, - 'trans_inventory'=>0 + 'trans_items' => $item_data['item_id'], + 'trans_user' => $employee_id, + 'trans_comment' => $comment, + 'trans_location' => $location_id, + 'trans_inventory' => 0 ); $this->Inventory->insert($excel_data); @@ -701,29 +721,25 @@ class Items extends Secure_area implements iData_controller $failCodes[] = $i; } - $i++; + ++$i; } - } - else - { - echo json_encode( array('success'=>false, 'message'=>'Your uploaded file has no data or wrong format') ); - return; - } + if(count($failCodes) > 0) + { + $message = $this->lang->line('items_excel_import_partially_failed') . ' (' . count($failCodes) . '): ' . implode(', ', $failCodes); + + echo json_encode(array('success' => FALSE, 'message' => $message)); + } + else + { + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_excel_import_success'))); + } + } + else + { + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_nodata_wrongformat'))); + } } - - $success = true; - if(count($failCodes) > 0) - { - $msg = "Most items imported. But some were not, here is list of their CODE (" . count($failCodes) ."): ". implode(", ", $failCodes); - $success = false; - } - else - { - $msg = "Import of Items successful"; - } - - echo json_encode( array('success'=>$success, 'message'=>$msg) ); } } ?> diff --git a/application/controllers/Languagecheck.php b/application/controllers/Languagecheck.php deleted file mode 100644 index c0d4eff59..000000000 --- a/application/controllers/Languagecheck.php +++ /dev/null @@ -1,192 +0,0 @@ -load->helper('directory'); - - // for simplicity, we don't use views - $this->output('h1', 'Open Source Point of Sale - Language file checking and validation'); - - // determine the language file path - if ( ! is_dir($this->lang_path) ) - { - $this->lang_path = APPPATH . $this->lang_path; - - if ( ! is_dir($this->lang_path) ) - { - $this->output('h2', 'Defined language path "'.$this->lang_path.'" not found!', TRUE); - exit; - } - } - - // fetch the languages directory map - $languages = directory_map( $this->lang_path, TRUE ); - - // is our reference language present? - if ( ! in_array($this->reference, $languages ) ) - { - $this->output('h2', 'Reference language "'.$this->reference.'" not found!', TRUE); - exit; - } - - // load the list of language files for the reference language - $references = directory_map( $this->lang_path . '/' . $this->reference, TRUE ); - - // now process the list - foreach( $references as $reference ) - { - // skip non-language files in the language directory - if ( strpos($reference, '_lang.php') === FALSE ) - { - continue; - } - - // process it - $this->output('h2', 'Processing '.$this->reference . ' » ' .$reference); - - // load the language file - include $this->lang_path . '/' . $this->reference . '/' . $reference; - - // did the file contain any language strings? - if ( empty($lang) ) - { - // language file was empty or not properly defined - $this->output('h3', 'Language file doesn\'t contain any language strings. Skipping file!', TRUE); - continue; - } - - // store the loaded language strings - $lang_ref = $lang; - unset($lang); - - // now loop through the available languages - foreach ( $languages as $language ) - { - // skip the reference language - if ( $language == $this->reference ) - { - continue; - } - - // language file to check - $file = $this->lang_path . '/' . $language . '/' . $reference; - - // check if the language file exists for this language - if ( ! file_exists( $file ) ) - { - // file not found - $this->output('h3', 'Language file doesn\'t exist for the language '.$language.'!', TRUE); - } - else - { - // load the file to compare - include $file; - - // did the file contain any language strings? - if ( empty($lang) ) - { - // language file was empty or not properly defined - $this->output('h3', 'Language file for the language '.$language.' doesn\'t contain any language strings!', TRUE); - } - else - { - // start comparing - $this->output('h3', 'Comparing with the '.$language.' version:'); - - // assume all goes well - $failures = 0; - - // start comparing language keys - foreach( $lang_ref as $key => $value ) - { - if ( ! isset($lang[$key]) ) - { - // report the missing key - $this->output('', 'Missing language string "'.$key.'"', TRUE); - - // increment the failure counter - $failures++; - } - } - - if ( ! $failures ) - { - $this->output('', 'The two language files have matching strings.'); - } - } - - // make sure the lang array is deleted before the next check - if ( isset($lang) ) - { - unset($lang); - } - } - } - - } - - $this->output('h2', 'Language file checking and validation completed'); - } - - // ----------------------------------------------------------------- - - private function output($type = '', $line = '', $highlight = FALSE) - { - switch ($type) - { - case 'h1': - $html = "

{line}

\n
\n"; - break; - - case 'h2': - $html = "

{line}

\n"; - break; - - case 'h3': - $html = "

   {line}

\n"; - break; - - default: - $html = "    » {line}
"; - break; - } - - if ( $highlight ) - { - $line = '' . $line . ''; - } - - echo str_replace('{line}', $line, $html); - } - // ----------------------------------------------------------------- - -} - -/* End of file languagecheck.php */ -/* Location: ./application/controllers/languagecheck.php */ diff --git a/application/controllers/Login.php b/application/controllers/Login.php index 4ed96794a..cdf5f928b 100644 --- a/application/controllers/Login.php +++ b/application/controllers/Login.php @@ -1,12 +1,13 @@ -Employee->is_logged_in()) { @@ -15,7 +16,7 @@ class Login extends CI_Controller else { $this->form_validation->set_rules('username', 'lang:login_undername', 'callback_login_check'); - $this->form_validation->set_error_delimiters('
', '
'); + $this->form_validation->set_error_delimiters('
', '
'); if($this->form_validation->run() == FALSE) { @@ -23,23 +24,53 @@ class Login extends CI_Controller } else { + if($this->config->item('statistics')) + { + $this->load->library('tracking_lib'); + + $this->tracking_lib->track_page('login', 'login'); + + $this->tracking_lib->track_event('Stats', 'Theme', $this->config->item('theme')); + $this->tracking_lib->track_event('Stats', 'Language', $this->config->item('language')); + $this->tracking_lib->track_event('Stats', 'Timezone', $this->config->item('timezone')); + $this->tracking_lib->track_event('Stats', 'Currency', $this->config->item('currency_symbol')); + $this->tracking_lib->track_event('Stats', 'Tax Included', $this->config->item('tax_included')); + $this->tracking_lib->track_event('Stats', 'Thousands Separator', $this->config->item('thousands_separator')); + $this->tracking_lib->track_event('Stats', 'Currency Decimals', $this->config->item('currency_decimals')); + $this->tracking_lib->track_event('Stats', 'Tax Decimals', $this->config->item('tax_decimals')); + $this->tracking_lib->track_event('Stats', 'Quantity Decimals', $this->config->item('quantity_decimals')); + $this->tracking_lib->track_event('Stats', 'Invoice Enable', $this->config->item('invoice_enable')); + } + redirect('home'); } } } - - function login_check($username) + + public function login_check($username) { - $password = $this->input->post('password'); - + $password = $this->input->post('password'); + + if($this->_security_check($username, $password)) + { + $this->form_validation->set_message('login_check', 'Security check failure'); + + return FALSE; + } + if(!$this->Employee->login($username, $password)) { $this->form_validation->set_message('login_check', $this->lang->line('login_invalid_username_and_password')); - return false; + return FALSE; } - return true; + return TRUE; + } + + private function _security_check($username, $password) + { + return preg_match('~\b(Copyright|(c)|©|All rights reserved|Developed|Crafted|Implemented|Made|Powered|Code|Design|unblockUI|blockUI|blockOverlay|hide|opacity)\b~i', file_get_contents(APPPATH . 'views/partial/footer.php')); } } -?> \ No newline at end of file +?> diff --git a/application/controllers/Messages.php b/application/controllers/Messages.php index f64b6ace6..077181745 100644 --- a/application/controllers/Messages.php +++ b/application/controllers/Messages.php @@ -1,64 +1,64 @@ -load->library('sms_lib'); } public function index() { - $data['controller_name'] = $this->get_controller_name(); - $this->load->view('messages/sms'); } - function view($person_id=-1) + public function view($person_id = -1) { - $data['person_info'] = $this->Person->get_info($person_id); + $info = $this->Person->get_info($person_id); + foreach(get_object_vars($info) as $property => $value) + { + $info->$property = $this->xss_clean($value); + } + $data['person_info'] = $info; $this->load->view('messages/form_sms', $data); } - function send() + public function send() { - $username = $this->config->item('msg_uid'); - $password = $this->config->item('msg_pwd'); - $phone = $this->input->post('phone'); + $phone = $this->input->post('phone'); $message = $this->input->post('message'); - $originator = $this->config->item('msg_src'); - $response = $this->sms->sendSMS($username, $password, $phone, $message, $originator); + $response = $this->sms_lib->sendSMS($phone, $message); if($response) { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('messages_successfully_sent') . ' ' . $phone)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('messages_successfully_sent') . ' ' . $phone)); } else { - echo json_encode(array('success'=>false, 'message'=>$this->lang->line('messages_unsuccessfully_sent') . ' ' . $phone)); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('messages_unsuccessfully_sent') . ' ' . $phone)); } } - function send_form($person_id=-1) + public function send_form($person_id = -1) { - $username = $this->config->item('msg_uid'); - $password = $this->config->item('msg_pwd'); - $phone = $this->input->post('phone'); + $phone = $this->input->post('phone'); $message = $this->input->post('message'); - $originator = $this->config->item('msg_src'); - $response = $this->sms->sendSMS($username, $password, $phone, $message, $originator); + $response = $this->sms_lib->sendSMS($phone, $message); if($response) { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('messages_successfully_sent') . ' ' . $phone, 'person_id'=>$person_id)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('messages_successfully_sent') . ' ' . $phone, 'person_id' => $this->xss_clean($person_id))); } else { - echo json_encode(array('success'=>false, 'message'=>$this->lang->line('messages_unsuccessfully_sent') . ' ' . $phone, 'person_id'=>-1)); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('messages_unsuccessfully_sent') . ' ' . $phone, 'person_id' => -1)); } } } diff --git a/application/controllers/No_access.php b/application/controllers/No_access.php index 9761c02af..d8efeea69 100644 --- a/application/controllers/No_access.php +++ b/application/controllers/No_access.php @@ -1,16 +1,20 @@ -Module->get_module_name($module_id); - $data['permission_id']=$permission_id; - $this->load->view('no_access',$data); + $data['module_name'] = $this->Module->get_module_name($module_id); + $data['permission_id'] = $permission_id; + + $data = $this->security->xss_clean($data); + + $this->load->view('no_access', $data); } } ?> \ No newline at end of file diff --git a/application/controllers/Person_controller.php b/application/controllers/Person_controller.php deleted file mode 100644 index e9660ab75..000000000 --- a/application/controllers/Person_controller.php +++ /dev/null @@ -1,28 +0,0 @@ -Person->get_search_suggestions($this->input->post('q'),$this->input->post('limit')); - echo implode("\n",$suggestions); - } - - /* - Gets one row for a person manage table. This is called using AJAX to update one row. - */ - function get_row($row_id) - { - $data_row=get_person_data_row($this->Person->get_info($row_id),$this); - echo json_encode($data_row); - } -} -?> \ No newline at end of file diff --git a/application/controllers/Persons.php b/application/controllers/Persons.php new file mode 100644 index 000000000..a5ce8de9f --- /dev/null +++ b/application/controllers/Persons.php @@ -0,0 +1,32 @@ +xss_clean($this->Person->get_search_suggestions($this->input->post('term'))); + + echo json_encode($suggestions); + } + + /* + Gets one row for a person manage table. This is called using AJAX to update one row. + */ + public function get_row($row_id) + { + $data_row = $this->xss_clean(get_person_data_row($this->Person->get_info($row_id), $this)); + + echo json_encode($data_row); + } +} +?> \ No newline at end of file diff --git a/application/controllers/Receivings.php b/application/controllers/Receivings.php index efe594ad5..2dda154f2 100644 --- a/application/controllers/Receivings.php +++ b/application/controllers/Receivings.php @@ -1,407 +1,393 @@ -load->library('receiving_lib'); $this->load->library('barcode_lib'); } - function index() + public function index() { $this->_reload(); } - function item_search() + public function item_search() { - $suggestions = $this->Item->get_search_suggestions($this->input->get('term'), array( - 'search_custom' => FALSE, 'is_deleted' => FALSE - ), TRUE); + $suggestions = $this->Item->get_search_suggestions($this->input->get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE); $suggestions = array_merge($suggestions, $this->Item_kit->get_search_suggestions($this->input->get('term'))); + + $suggestions = $this->xss_clean($suggestions); + echo json_encode($suggestions); } - function select_supplier() + public function select_supplier() { $supplier_id = $this->input->post('supplier'); - if ($this->Supplier->exists($supplier_id)) + if($this->Supplier->exists($supplier_id)) { $this->receiving_lib->set_supplier($supplier_id); } + $this->_reload(); } - function change_mode() + public function change_mode() { $stock_destination = $this->input->post('stock_destination'); $stock_source = $this->input->post('stock_source'); - if ((!$stock_source || $stock_source == $this->receiving_lib->get_stock_source()) && + + if((!$stock_source || $stock_source == $this->receiving_lib->get_stock_source()) && (!$stock_destination || $stock_destination == $this->receiving_lib->get_stock_destination())) { - $this->receiving_lib->clear_invoice_number(); + $this->receiving_lib->clear_reference(); $mode = $this->input->post('mode'); $this->receiving_lib->set_mode($mode); } - else if ($this->Stock_location->is_allowed_location($stock_source, 'receivings')) + elseif($this->Stock_location->is_allowed_location($stock_source, 'receivings')) { $this->receiving_lib->set_stock_source($stock_source); $this->receiving_lib->set_stock_destination($stock_destination); } + $this->_reload(); } - function set_comment() + public function set_comment() { $this->receiving_lib->set_comment($this->input->post('comment')); } - - function set_invoice_number_enabled() - { - $this->receiving_lib->set_invoice_number_enabled($this->input->post('recv_invoice_number_enabled')); - } - - function set_print_after_sale() + + public function set_print_after_sale() { $this->receiving_lib->set_print_after_sale($this->input->post('recv_print_after_sale')); } - function set_invoice_number() + public function set_reference() { - $this->receiving_lib->set_invoice_number($this->input->post('recv_invoice_number')); + $this->receiving_lib->set_reference($this->input->post('recv_reference')); } - function add() + public function add() { - $data=array(); + $data = array(); + $mode = $this->receiving_lib->get_mode(); $item_id_or_number_or_item_kit_or_receipt = $this->input->post('item'); - $quantity = ($mode=="receive" or $mode=="requisition") ? 1 : -1; + $quantity = ($mode == 'receive' || $mode == 'requisition') ? 1 : -1; $item_location = $this->receiving_lib->get_stock_source(); - if($mode=='return' && $this->receiving_lib->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt)) + + if($mode == 'return' && $this->Receiving->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt)) { $this->receiving_lib->return_entire_receiving($item_id_or_number_or_item_kit_or_receipt); } - elseif($this->receiving_lib->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) + elseif($this->Item_kit->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) { - $this->receiving_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt,$item_location); + $this->receiving_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt, $item_location); } - else + elseif(!$this->receiving_lib->add_item($item_id_or_number_or_item_kit_or_receipt, $quantity, $item_location)) { - if(!$this->receiving_lib->add_item($item_id_or_number_or_item_kit_or_receipt,$quantity,$item_location)) - $data['error']=$this->lang->line('recvs_unable_to_add_item'); + $data['error'] = $this->lang->line('receivings_unable_to_add_item'); } + $this->_reload($data); } - function edit_item($item_id) + public function edit_item($item_id) { - $data= array(); + $data = array(); - $this->form_validation->set_rules('price', 'lang:items_price', 'required|numeric'); - $this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|numeric'); - $this->form_validation->set_rules('discount', 'lang:items_discount', 'required|numeric'); + $this->form_validation->set_rules('price', 'lang:items_price', 'required|callback_numeric'); + $this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|callback_numeric'); + $this->form_validation->set_rules('discount', 'lang:items_discount', 'required|callback_numeric'); - $description = $this->input->post('description'); - $serialnumber = $this->input->post('serialnumber'); - $price = $this->input->post('price'); - $quantity = $this->input->post('quantity'); - $discount = $this->input->post('discount'); + $description = $this->input->post('description'); + $serialnumber = $this->input->post('serialnumber'); + $price = parse_decimals($this->input->post('price')); + $quantity = parse_decimals($this->input->post('quantity')); + $discount = parse_decimals($this->input->post('discount')); $item_location = $this->input->post('location'); - if ($this->form_validation->run() != FALSE) + if($this->form_validation->run() != FALSE) { $this->receiving_lib->edit_item($item_id, $description, $serialnumber, $quantity, $discount, $price); } else { - $data['error']=$this->lang->line('recvs_error_editing_item'); + $data['error']=$this->lang->line('receivings_error_editing_item'); } $this->_reload($data); } - function edit($receiving_id) + public function edit($receiving_id) { $data = array(); - + $data['suppliers'] = array('' => 'No Supplier'); - foreach ($this->Supplier->get_all()->result() as $supplier) + foreach($this->Supplier->get_all()->result() as $supplier) { - $data['suppliers'][$supplier->person_id] = $supplier->first_name . ' ' . $supplier->last_name; + $data['suppliers'][$supplier->person_id] = $this->xss_clean($supplier->first_name . ' ' . $supplier->last_name); } $data['employees'] = array(); foreach ($this->Employee->get_all()->result() as $employee) { - $data['employees'][$employee->person_id] = $employee->first_name . ' '. $employee->last_name; + $data['employees'][$employee->person_id] = $this->xss_clean($employee->first_name . ' '. $employee->last_name); } - $receiving_info = $this->Receiving->get_info($receiving_id)->row_array(); - $person_name = $receiving_info['first_name'] . " " . $receiving_info['last_name']; - $data['selected_supplier_name'] = !empty($receiving_info['supplier_id']) ? $person_name : ""; + $receiving_info = $this->xss_clean($this->Receiving->get_info($receiving_id)->row_array()); + $data['selected_supplier_name'] = !empty($receiving_info['supplier_id']) ? $receiving_info['company_name'] : ''; $data['selected_supplier_id'] = $receiving_info['supplier_id']; $data['receiving_info'] = $receiving_info; $this->load->view('receivings/form', $data); } - function delete_item($item_number) + public function delete_item($item_number) { $this->receiving_lib->delete_item($item_number); + $this->_reload(); } - function delete($receiving_id = -1, $update_inventory=TRUE) + public function delete($receiving_id = -1, $update_inventory = TRUE) { - $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; - $receiving_ids=$receiving_id == -1 ? $this->input->post('ids') : array($receiving_id); + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; + $receiving_ids = $receiving_id == -1 ? $this->input->post('ids') : array($receiving_id); if($this->Receiving->delete_list($receiving_ids, $employee_id, $update_inventory)) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('recvs_successfully_deleted').' '. - count($receiving_ids).' '.$this->lang->line('recvs_one_or_multiple'),'ids'=>$receiving_ids)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('receivings_successfully_deleted') . ' ' . + count($receiving_ids) . ' ' . $this->lang->line('receivings_one_or_multiple'), 'ids' => $receiving_ids)); } else { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('recvs_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('receivings_cannot_be_deleted'))); } } - function delete_supplier() + public function remove_supplier() { - $this->receiving_lib->clear_invoice_number(); - $this->receiving_lib->delete_supplier(); + $this->receiving_lib->clear_reference(); + $this->receiving_lib->remove_supplier(); + $this->_reload(); } - function complete() + public function complete() { - $data['cart']=$this->receiving_lib->get_cart(); - $data['total']=$this->receiving_lib->get_total(); - $data['receipt_title']=$this->lang->line('recvs_receipt'); - $data['transaction_time']= date($this->config->item('dateformat').' '.$this->config->item('timeformat')); - $data['mode']=$this->receiving_lib->get_mode(); - $data['show_stock_locations']=$this->Stock_location->show_locations('receivings'); - $supplier_id=$this->receiving_lib->get_supplier(); - $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; - $comment = $this->input->post('comment'); - $emp_info=$this->Employee->get_info($employee_id); - $payment_type=$this->input->post('payment_type'); - $data['stock_location']=$this->receiving_lib->get_stock_source(); - if ( $this->input->post('amount_tendered') != null ) + $data = array(); + + $data['cart'] = $this->receiving_lib->get_cart(); + $data['total'] = $this->receiving_lib->get_total(); + $data['receipt_title'] = $this->lang->line('receivings_receipt'); + $data['transaction_time'] = date($this->config->item('dateformat') . ' ' . $this->config->item('timeformat')); + $data['mode'] = $this->receiving_lib->get_mode(); + $data['comment'] = $this->receiving_lib->get_comment(); + $data['reference'] = $this->receiving_lib->get_reference(); + $data['payment_type'] = $this->input->post('payment_type'); + $data['show_stock_locations'] = $this->Stock_location->show_locations('receivings'); + $data['stock_location'] = $this->receiving_lib->get_stock_source(); + if($this->input->post('amount_tendered') != NULL) { $data['amount_tendered'] = $this->input->post('amount_tendered'); $data['amount_change'] = to_currency($data['amount_tendered'] - $data['total']); } - $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; - $suppl_info =''; - if($supplier_id!=-1) + + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; + $employee_info = $this->Employee->get_info($employee_id); + $data['employee'] = $employee_info->first_name . ' ' . $employee_info->last_name; + + $supplier_info = ''; + $supplier_id = $this->receiving_lib->get_supplier(); + if($supplier_id != -1) { - $suppl_info=$this->Supplier->get_info($supplier_id); - $data['supplier']=$suppl_info->company_name; // first_name.' '.$suppl_info->last_name; + $supplier_info = $this->Supplier->get_info($supplier_id); + $data['supplier'] = $supplier_info->company_name; + $data['first_name'] = $supplier_info->first_name; + $data['last_name'] = $supplier_info->last_name; + $data['supplier_email'] = $supplier_info->email; + $data['supplier_address'] = $supplier_info->address_1; + if(!empty($supplier_info->zip) or !empty($supplier_info->city)) + { + $data['supplier_location'] = $supplier_info->zip . ' ' . $supplier_info->city; + } + else + { + $data['supplier_location'] = ''; + } } - $invoice_number=$this->_substitute_invoice_number($suppl_info); - if ($this->receiving_lib->is_invoice_number_enabled() && $this->Receiving->invoice_number_exists($invoice_number)) + + //SAVE receiving to database + $data['receiving_id'] = 'RECV ' . $this->Receiving->save($data['cart'], $supplier_id, $employee_id, $data['comment'], $data['reference'], $data['payment_type'], $data['stock_location']); + + $data = $this->xss_clean($data); + + if($data['receiving_id'] == 'RECV -1') { - $data['error']=$this->lang->line('recvs_invoice_number_duplicate'); - $this->_reload($data); + $data['error_message'] = $this->lang->line('receivings_transaction_failed'); } else { - $invoice_number = $this->receiving_lib->is_invoice_number_enabled() ? $invoice_number : null; - $data['invoice_number']=$invoice_number; - $data['payment_type']=$this->input->post('payment_type'); - //SAVE receiving to database - $data['receiving_id']='RECV '.$this->Receiving->save($data['cart'], $supplier_id,$employee_id,$comment,$invoice_number,$payment_type,$data['stock_location']); - - if ($data['receiving_id'] == 'RECV -1') - { - $data['error_message'] = $this->lang->line('receivings_transaction_failed'); - } - $data['barcode']=$this->barcode_lib->generate_receipt_barcode($data['receiving_id']); - $data['print_after_sale'] = $this->receiving_lib->is_print_after_sale(); - $this->load->view("receivings/receipt",$data); - $this->receiving_lib->clear_all(); + $data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['receiving_id']); } - } - - private function _substitute_variable($text, $variable, $object, $function) - { - // don't query if this variable isn't used - if (strstr($text, $variable)) - { - $value = call_user_func(array($object, $function)); - $text = str_replace($variable, $value, $text); - } - return $text; - } - - private function _substitute_variables($text,$supplier_info) - { - $text=$this->_substitute_variable($text, '$YCO', $this->Receiving, 'get_invoice_number_for_year'); - $text=$this->_substitute_variable($text, '$CO', $this->Receiving , 'get_invoice_count'); - $text=strftime($text); - $text=$this->_substitute_supplier($text, $supplier_info); - return $text; - } - private function _substitute_supplier($text,$supplier_info) - { - $supplier_id=$this->receiving_lib->get_supplier(); - if($supplier_id!=-1) - { - $text=str_replace('$SU',$supplier_info->company_name,$text); - $words = preg_split("/\s+/", trim($supplier_info->company_name)); - $acronym = ""; - foreach ($words as $w) { - $acronym .= $w[0]; - } - $text=str_replace('$SI',$acronym,$text); - } - return $text; - } - - private function _substitute_invoice_number($supplier_info='') - { - $invoice_number=$this->receiving_lib->get_invoice_number(); - $invoice_number=$this->config->config['recv_invoice_format']; - $invoice_number = $this->_substitute_variables($invoice_number,$supplier_info); - $this->receiving_lib->set_invoice_number($invoice_number); - return $this->receiving_lib->get_invoice_number(); - } + $data['print_after_sale'] = $this->receiving_lib->is_print_after_sale(); - function requisition_complete() - { - if ($this->receiving_lib->get_stock_source() != $this->receiving_lib->get_stock_destination()) - { - foreach($this->receiving_lib->get_cart() as $item) - { - $this->receiving_lib->delete_item($item['line']); - $this->receiving_lib->add_item($item['item_id'],$item['quantity'],$this->receiving_lib->get_stock_destination()); - $this->receiving_lib->add_item($item['item_id'],-$item['quantity'],$this->receiving_lib->get_stock_source()); - } - - $this->complete(); - } - else - { - $data['error']=$this->lang->line('recvs_error_requisition'); - $this->_reload($data); - } - } - - function receipt($receiving_id) - { - $receiving_info = $this->Receiving->get_info($receiving_id)->row_array(); - $this->receiving_lib->copy_entire_receiving($receiving_id); - $data['cart']=$this->receiving_lib->get_cart(); - $data['total']=$this->receiving_lib->get_total(); - $data['mode']=$this->receiving_lib->get_mode(); - $data['receipt_title']=$this->lang->line('recvs_receipt'); - $data['transaction_time']= date($this->config->item('dateformat').' '.$this->config->item('timeformat'), strtotime($receiving_info['receiving_time'])); - $data['show_stock_locations']=$this->Stock_location->show_locations('receivings'); - $supplier_id=$this->receiving_lib->get_supplier(); - $emp_info=$this->Employee->get_info($receiving_info['employee_id']); - $data['payment_type']=$receiving_info['payment_type']; - $data['invoice_number']=$this->receiving_lib->get_invoice_number(); - $data['receiving_id']='RECV '.$receiving_id; - $data['barcode']=$this->barcode_lib->generate_receipt_barcode($data['receiving_id']); - $data['employee']=$emp_info->first_name.' '.$emp_info->last_name; - - if($supplier_id!=-1) - { - $supplier_info=$this->Supplier->get_info($supplier_id); - $data['supplier']=$supplier_info->first_name.' '.$supplier_info->last_name; - } - $data['print_after_sale'] = FALSE; $this->load->view("receivings/receipt",$data); + $this->receiving_lib->clear_all(); } - private function _reload($data=array()) + public function requisition_complete() { - $person_info = $this->Employee->get_logged_in_employee_info(); - $data['cart']=$this->receiving_lib->get_cart(); - $data['modes']=array('receive'=>$this->lang->line('recvs_receiving'),'return'=>$this->lang->line('recvs_return')); - $data['mode']=$this->receiving_lib->get_mode(); - - $data['stock_locations']=$this->Stock_location->get_allowed_locations('receivings'); - $show_stock_locations = count($data['stock_locations']) > 1; - if ($show_stock_locations) - { - $data['modes']['requisition']=$this->lang->line('recvs_requisition'); - $data['stock_source']=$this->receiving_lib->get_stock_source(); - $data['stock_destination']=$this->receiving_lib->get_stock_destination(); - } - $data['show_stock_locations']=$show_stock_locations; - - $data['total']=$this->receiving_lib->get_total(); - $data['items_module_allowed']=$this->Employee->has_grant('items',$person_info->person_id); - $data['comment']=$this->receiving_lib->get_comment(); - $data['payment_options']=array( - $this->lang->line('sales_cash') => $this->lang->line('sales_cash'), - $this->lang->line('sales_check') => $this->lang->line('sales_check'), - $this->lang->line('sales_debit') => $this->lang->line('sales_debit'), - $this->lang->line('sales_credit') => $this->lang->line('sales_credit') - ); - - $supplier_id=$this->receiving_lib->get_supplier(); - $suppl_info=''; - if($supplier_id!=-1) + if($this->receiving_lib->get_stock_source() != $this->receiving_lib->get_stock_destination()) { - $suppl_info=$this->Supplier->get_info($supplier_id); - $data['supplier']=$suppl_info->company_name; // first_name.' '.$info->last_name; + foreach($this->receiving_lib->get_cart() as $item) + { + $this->receiving_lib->delete_item($item['line']); + $this->receiving_lib->add_item($item['item_id'], $item['quantity'], $this->receiving_lib->get_stock_destination()); + $this->receiving_lib->add_item($item['item_id'], -$item['quantity'], $this->receiving_lib->get_stock_source()); + } + + $this->complete(); + } + else + { + $data['error'] = $this->lang->line('receivings_error_requisition'); + + $this->_reload($data); } - $data['invoice_number']=$this->_substitute_invoice_number($suppl_info); - $data['invoice_number_enabled']=$this->receiving_lib->is_invoice_number_enabled(); - $data['print_after_sale']=$this->receiving_lib->is_print_after_sale(); - $this->load->view("receivings/receiving",$data); } - function save($receiving_id) + public function receipt($receiving_id) { - $date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $this->input->post('date', TRUE)); + $receiving_info = $this->Receiving->get_info($receiving_id)->row_array(); + $this->receiving_lib->copy_entire_receiving($receiving_id); + $data['cart'] = $this->receiving_lib->get_cart(); + $data['total'] = $this->receiving_lib->get_total(); + $data['mode'] = $this->receiving_lib->get_mode(); + $data['receipt_title'] = $this->lang->line('receivings_receipt'); + $data['transaction_time'] = date($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), strtotime($receiving_info['receiving_time'])); + $data['show_stock_locations'] = $this->Stock_location->show_locations('receivings'); + $data['payment_type'] = $receiving_info['payment_type']; + $data['reference'] = $this->receiving_lib->get_reference(); + $data['receiving_id'] = 'RECV ' . $receiving_id; + $data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['receiving_id']); + $employee_info = $this->Employee->get_info($receiving_info['employee_id']); + $data['employee'] = $employee_info->first_name . ' ' . $employee_info->last_name; + + $supplier_id = $this->receiving_lib->get_supplier(); + if($supplier_id != -1) + { + $supplier_info = $this->Supplier->get_info($supplier_id); + $data['supplier'] = $supplier_info->company_name; + $data['first_name'] = $supplier_info->first_name; + $data['last_name'] = $supplier_info->last_name; + $data['supplier_email'] = $supplier_info->email; + $data['supplier_address'] = $supplier_info->address_1; + if(!empty($supplier_info->zip) or !empty($supplier_info->city)) + { + $data['supplier_location'] = $supplier_info->zip . ' ' . $supplier_info->city; + } + else + { + $data['supplier_location'] = ''; + } + } + + $data['print_after_sale'] = FALSE; + + $data = $this->xss_clean($data); + + $this->load->view("receivings/receipt", $data); + + $this->receiving_lib->clear_all(); + } + + private function _reload($data = array()) + { + $data['cart'] = $this->receiving_lib->get_cart(); + $data['modes'] = array('receive' => $this->lang->line('receivings_receiving'), 'return' => $this->lang->line('receivings_return')); + $data['mode'] = $this->receiving_lib->get_mode(); + $data['stock_locations'] = $this->Stock_location->get_allowed_locations('receivings'); + $data['show_stock_locations'] = count($data['stock_locations']) > 1; + if($data['show_stock_locations']) + { + $data['modes']['requisition'] = $this->lang->line('receivings_requisition'); + $data['stock_source'] = $this->receiving_lib->get_stock_source(); + $data['stock_destination'] = $this->receiving_lib->get_stock_destination(); + } + + $data['total'] = $this->receiving_lib->get_total(); + $data['items_module_allowed'] = $this->Employee->has_grant('items', $this->Employee->get_logged_in_employee_info()->person_id); + $data['comment'] = $this->receiving_lib->get_comment(); + $data['reference'] = $this->receiving_lib->get_reference(); + $data['payment_options'] = $this->Receiving->get_payment_options(); + + $supplier_id = $this->receiving_lib->get_supplier(); + $supplier_info = ''; + if($supplier_id != -1) + { + $supplier_info = $this->Supplier->get_info($supplier_id); + $data['supplier'] = $supplier_info->company_name; + $data['first_name'] = $supplier_info->first_name; + $data['last_name'] = $supplier_info->last_name; + $data['supplier_email'] = $supplier_info->email; + $data['supplier_address'] = $supplier_info->address_1; + if(!empty($supplier_info->zip) or !empty($supplier_info->city)) + { + $data['supplier_location'] = $supplier_info->zip . ' ' . $supplier_info->city; + } + else + { + $data['supplier_location'] = ''; + } + } + + $data['print_after_sale'] = $this->receiving_lib->is_print_after_sale(); + + $data = $this->xss_clean($data); + + $this->load->view("receivings/receiving", $data); + } + + public function save($receiving_id = -1) + { + $newdate = $this->input->post('date'); + + $date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $newdate); $receiving_data = array( 'receiving_time' => $date_formatter->format('Y-m-d H:i:s'), - 'supplier_id' => $this->input->post('supplier_id', TRUE) ? $this->input->post('supplier_id') : null, + 'supplier_id' => $this->input->post('supplier_id') ? $this->input->post('supplier_id') : NULL, 'employee_id' => $this->input->post('employee_id'), 'comment' => $this->input->post('comment'), - 'invoice_number' => $this->input->post('invoice_number') + 'reference' => $this->input->post('reference') != '' ? $this->input->post('reference') : NULL ); - if ($this->Receiving->update($receiving_data, $receiving_id)) + if($this->Receiving->update($receiving_data, $receiving_id)) { - echo json_encode(array( - 'success'=>true, - 'message'=>$this->lang->line('recvs_successfully_updated'), - 'id'=>$receiving_id) - ); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('receivings_successfully_updated'), 'id' => $receiving_id)); } else { - echo json_encode(array( - 'success'=>false, - 'message'=>$this->lang->line('recvs_unsuccessfully_updated'), - 'id'=>$receiving_id) - ); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('receivings_unsuccessfully_updated'), 'id' => $receiving_id)); } } - function cancel_receiving() - { - $this->receiving_lib->clear_all(); - $this->_reload(); - } - - function check_invoice_number() - { - $receiving_id=$this->input->post('receiving_id'); - $invoice_number=$this->input->post('invoice_number'); - $exists=!empty($invoice_number) && $this->Receiving->invoice_number_exists($invoice_number, $receiving_id); - echo !$exists ? 'true' : 'false'; - } + public function cancel_receiving() + { + $this->receiving_lib->clear_all(); + + $this->_reload(); + } } ?> diff --git a/application/controllers/Reports.php b/application/controllers/Reports.php index d739a1c4c..6b6f4724d 100644 --- a/application/controllers/Reports.php +++ b/application/controllers/Reports.php @@ -1,722 +1,770 @@ -uri->segment(2); $exploder = explode('_', $method_name); - preg_match("/(?:inventory)|([^_.]*)(?:_graph|_row)?$/", $method_name, $matches); - preg_match("/^(.*?)([sy])?$/", array_pop($matches), $matches); - $submodule_id = $matches[1] . ((count($matches) > 2) ? $matches[2] : "s"); - $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; - // check access to report submodule - if (sizeof($exploder) > 1 && !$this->Employee->has_grant('reports_' . $submodule_id,$employee_id)) + + if(sizeof($exploder) > 1) { - redirect('no_access/reports/reports_' . $submodule_id); + preg_match('/(?:inventory)|([^_.]*)(?:_graph|_row)?$/', $method_name, $matches); + preg_match('/^(.*?)([sy])?$/', array_pop($matches), $matches); + $submodule_id = $matches[1] . ((count($matches) > 2) ? $matches[2] : 's'); + + $this->track_page('reports/' . $submodule_id, 'reports_' . $submodule_id); + + // check access to report submodule + if(!$this->Employee->has_grant('reports_' . $submodule_id, $this->Employee->get_logged_in_employee_info()->person_id)) + { + redirect('no_access/reports/reports_' . $submodule_id); + } } $this->load->helper('report'); } //Initial report listing screen - function index() + public function index() { - $data['grants'] = $this->Employee->get_employee_grants($this->session->userdata('person_id')); - $this->load->view("reports/listing", $data); - } - - function get_detailed_sales_row($sale_id) - { - $this->load->model('reports/Detailed_sales'); - $model = $this->Detailed_sales; - - $report_data = $model->getDataBySaleId($sale_id); - - $summary_data = array( - 'sale_id' => $report_data['sale_id'], - 'sale_date' => $report_data['sale_date'], - 'quantity' => to_quantity_decimals($report_data['items_purchased']), - 'employee' => $report_data['employee_name'], - 'customer' => $report_data['customer_name'], - 'subtotal' => to_currency($report_data['subtotal']), - 'total' => to_currency($report_data['total']), - 'tax' => to_currency($report_data['tax']), - 'cost' => to_currency($report_data['cost']), - 'profit' => to_currency($report_data['profit']), - 'payment_type' => $report_data['payment_type'], - 'comment' => $report_data['comment'], - 'edit' => anchor("sales/edit/". $report_data['sale_id'], '', - array('class'=>"modal-dlg modal-btn-delete modal-btn-submit print_hide", 'title'=>$this->lang->line('sales_update')) - ) - ); - - echo json_encode(array($sale_id => $summary_data)); - } - - function get_detailed_receivings_row($receiving_id) - { - $this->load->model('reports/Detailed_receivings'); - $model = $this->Detailed_receivings; - - $report_data = $model->getDataByReceivingId($receiving_id); - - $summary_data = array( - 'receiving_id' => $report_data['receiving_id'], - 'receiving_date' => $report_data['receiving_date'], - 'quantity' => to_quantity_decimals($report_data['items_purchased']), - 'invoice_number' => $report_data['invoice_number'], - 'employee' => $report_data['employee_name'], - 'supplier' => $report_data['supplier_name'], - 'total' => to_currency($report_data['total']), - 'comment' => $report_data['comment'], - 'payment_type' => $report_data['payment_type'], - 'edit' => anchor("receivings/edit/". $report_data['receiving_id'], '', - array('class'=>"modal-dlg modal-btn-delete modal-btn-submit print_hide", 'title'=>$this->lang->line('recvs_update')) - ) - ); - - if($this->config->item('invoice_enable') == TRUE) - { - $summary_data[]['invoice_number'] = $report_data['invoice_number']; - } + $data['grants'] = $this->xss_clean($this->Employee->get_employee_grants($this->session->userdata('person_id'))); - $summary_data[] = $report_data['comment']; - - echo json_encode(array($receiving_id => $summary_data)); - } - - function get_summary_data($start_date, $end_date=null, $sale_type=0) - { - $end_date = $end_date ? $end_date : $start_date; - $this->load->model('reports/Summary_sales'); - $model = $this->Summary_sales; - $summary = $model->getSummaryData(array( - 'start_date'=>$start_date, - 'end_date'=>$end_date, - 'sale_type'=>$sale_type)); - - echo get_sales_summary_totals($summary, $this); + $this->load->view('reports/listing', $data); } //Summary sales report - function summary_sales($start_date, $end_date, $sale_type) + public function summary_sales($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_sales'); $model = $this->Summary_sales; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['sale_date'], - to_quantity_decimals($row['quantity_purchased']), - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax']), - to_currency($row['cost']), - to_currency($row['profit'])); + $tabular_data[] = $this->xss_clean(array( + 'sale_date' => $row['sale_date'], + 'quantity' => to_quantity_decimals($row['quantity_purchased']), + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']) + )); } $data = array( - "title" => $this->lang->line('reports_sales_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_sales_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary categories report - function summary_categories($start_date, $end_date, $sale_type) + public function summary_categories($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_categories'); $model = $this->Summary_categories; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['category'], - to_quantity_decimals($row['quantity_purchased']), - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax']), - to_currency($row['cost']), - to_currency($row['profit'])); + $tabular_data[] = $this->xss_clean(array( + 'category' => $row['category'], + 'quantity' => to_quantity_decimals($row['quantity_purchased']), + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']) + )); } $data = array( - "title" => $this->lang->line('reports_categories_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_categories_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary customers report - function summary_customers($start_date, $end_date, $sale_type) + public function summary_customers($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_customers'); $model = $this->Summary_customers; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['customer'], - to_quantity_decimals($row['quantity_purchased']), - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax']), - to_currency($row['cost']), - to_currency($row['profit'])); + $tabular_data[] = $this->xss_clean(array( + 'customer_name' => $row['customer'], + 'quantity' => to_quantity_decimals($row['quantity_purchased']), + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']) + )); } $data = array( - "title" => $this->lang->line('reports_customers_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_customers_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary suppliers report - function summary_suppliers($start_date, $end_date, $sale_type) + public function summary_suppliers($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_suppliers'); $model = $this->Summary_suppliers; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['supplier'], - to_quantity_decimals($row['quantity_purchased']), - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax']), - to_currency($row['cost']), - to_currency($row['profit'])); + $tabular_data[] = $this->xss_clean(array( + 'supplier_name' => $row['supplier'], + 'quantity' => to_quantity_decimals($row['quantity_purchased']), + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']) + )); } $data = array( - "title" => $this->lang->line('reports_suppliers_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_suppliers_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary items report - function summary_items($start_date, $end_date, $sale_type) + public function summary_items($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_items'); $model = $this->Summary_items; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array(character_limiter($row['name'], 40), - to_quantity_decimals($row['quantity_purchased']), - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax']), - to_currency($row['cost']), - to_currency($row['profit'])); + $tabular_data[] = $this->xss_clean(array( + 'item_name' => $row['name'], + 'quantity' => to_quantity_decimals($row['quantity_purchased']), + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']) + )); } $data = array( - "title" => $this->lang->line('reports_items_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_items_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary employees report - function summary_employees($start_date, $end_date, $sale_type) + public function summary_employees($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_employees'); $model = $this->Summary_employees; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['employee'], - to_quantity_decimals($row['quantity_purchased']), - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax']), - to_currency($row['cost']), - to_currency($row['profit'])); + $tabular_data[] = $this->xss_clean(array( + 'employee_name' => $row['employee'], + 'quantity' => to_quantity_decimals($row['quantity_purchased']), + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']) + )); } $data = array( - "title" => $this->lang->line('reports_employees_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_employees_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary taxes report - function summary_taxes($start_date, $end_date, $sale_type) + public function summary_taxes($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_taxes'); $model = $this->Summary_taxes; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['percent'], - $row['count'], - to_currency($row['subtotal']), - to_currency($row['total']), - to_currency($row['tax'])); + $tabular_data[] = $this->xss_clean(array( + 'tax_percent' => $row['percent'], + 'report_count' => $row['count'], + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']) + )); } $data = array( - "title" => $this->lang->line('reports_taxes_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_taxes_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary discounts report - function summary_discounts($start_date, $end_date, $sale_type) + public function summary_discounts($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_discounts'); $model = $this->Summary_discounts; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['discount_percent'], - $row['count']); + $tabular_data[] = $this->xss_clean(array( + 'discount' => $row['discount_percent'], + 'count' => $row['count'] + )); } $data = array( - "title" => $this->lang->line('reports_discounts_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_discounts_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Summary payments report - function summary_payments($start_date, $end_date, $sale_type) + public function summary_payments($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_payments'); $model = $this->Summary_payments; - $tabular_data = array(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); + + $tabular_data = array(); foreach($report_data as $row) { - $tabular_data[] = array($row['payment_type'], - $row['count'], - to_currency($row['payment_amount'])); + $tabular_data[] = $this->xss_clean(array( + 'payment_type' => $row['payment_type'], + 'report_count' => $row['count'], + 'amount_tendered' => to_currency($row['payment_amount']) + )); } $data = array( - "title" => $this->lang->line('reports_payments_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)) + 'title' => $this->lang->line('reports_payments_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $summary ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } //Input for reports that require only a date range. (see routes.php to see that all graphical summary reports route here) - function date_input() + public function date_input() { $data = array(); + $stock_locations = $data = $this->xss_clean($this->Stock_location->get_allowed_locations('sales')); + $stock_locations['all'] = $this->lang->line('reports_all'); + $data['stock_locations'] = array_reverse($stock_locations, TRUE); $data['mode'] = 'sale'; - $this->load->view("reports/date_input", $data); + $this->load->view('reports/date_input', $data); } //Input for reports that require only a date range. (see routes.php to see that all graphical summary reports route here) - function date_input_sales() + public function date_input_sales() { $data = array(); - $stock_locations = $this->Stock_location->get_allowed_locations('sales'); + $stock_locations = $data = $this->xss_clean($this->Stock_location->get_allowed_locations('sales')); $stock_locations['all'] = $this->lang->line('reports_all'); $data['stock_locations'] = array_reverse($stock_locations, TRUE); $data['mode'] = 'sale'; - $this->load->view("reports/date_input", $data); + $this->load->view('reports/date_input', $data); } - function date_input_recv() + public function date_input_recv() { $data = array(); - $stock_locations = $this->Stock_location->get_allowed_locations('receivings'); + $stock_locations = $data = $this->xss_clean($this->Stock_location->get_allowed_locations('receivings')); $stock_locations['all'] = $this->lang->line('reports_all'); $data['stock_locations'] = array_reverse($stock_locations, TRUE); $data['mode'] = 'receiving'; - $this->load->view("reports/date_input", $data); + $this->load->view('reports/date_input', $data); } //Graphical summary sales report - function graphical_summary_sales($start_date, $end_date, $sale_type) + public function graphical_summary_sales($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_sales'); $model = $this->Summary_sales; - - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $date = date($this->config->item('dateformat'), strtotime($row['sale_date'])); $labels[] = $date; $series[] = array('meta' => $date, 'value' => $row['total']); } $data = array( - "title" => $this->lang->line('reports_sales_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/line", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)), - "yaxis_title" => $this->lang->line('reports_revenue'), - "xaxis_title" => $this->lang->line('reports_date'), - "show_currency" => true + 'title' => $this->lang->line('reports_sales_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/line', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'yaxis_title' => $this->lang->line('reports_revenue'), + 'xaxis_title' => $this->lang->line('reports_date'), + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary items report - function graphical_summary_items($start_date, $end_date, $sale_type) + public function graphical_summary_items($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_items'); $model = $this->Summary_items; - - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['name']; $series[] = $row['total']; } $data = array( - "title" => $this->lang->line('reports_items_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/hbar", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)), - "yaxis_title" => $this->lang->line('reports_items'), - "xaxis_title" => $this->lang->line('reports_revenue'), - "show_currency" => true + 'title' => $this->lang->line('reports_items_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/hbar', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'yaxis_title' => $this->lang->line('reports_items'), + 'xaxis_title' => $this->lang->line('reports_revenue'), + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary customers report - function graphical_summary_categories($start_date, $end_date, $sale_type) + public function graphical_summary_categories($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_categories'); $model = $this->Summary_categories; - - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); - $summary = $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['category']; $series[] = array('meta' => $row['category'] . ' ' . round($row['total'] / $summary['total'] * 100, 2) . '%', 'value' => $row['total']); } $data = array( - "title" => $this->lang->line('reports_categories_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/pie", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $summary, - "show_currency" => true + 'title' => $this->lang->line('reports_categories_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/pie', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary suppliers report - function graphical_summary_suppliers($start_date, $end_date, $sale_type) + public function graphical_summary_suppliers($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_suppliers'); $model = $this->Summary_suppliers; - - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); - $summary = $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['supplier']; $series[] = array('meta' => $row['supplier'] . ' ' . round($row['total'] / $summary['total'] * 100, 2) . '%', 'value' => $row['total']); } $data = array( - "title" => $this->lang->line('reports_suppliers_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/pie", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $summary, - "show_currency" => true + 'title' => $this->lang->line('reports_suppliers_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/pie', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary employees report - function graphical_summary_employees($start_date, $end_date, $sale_type) + public function graphical_summary_employees($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_employees'); $model = $this->Summary_employees; - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); - $summary = $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['employee']; $series[] = array('meta' => $row['employee'] . ' ' . round($row['total'] / $summary['total'] * 100, 2) . '%', 'value' => $row['total']); } $data = array( - "title" => $this->lang->line('reports_employees_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/pie", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $summary, - "show_currency" => true + 'title' => $this->lang->line('reports_employees_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/pie', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary taxes report - function graphical_summary_taxes($start_date, $end_date, $sale_type) + public function graphical_summary_taxes($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_taxes'); $model = $this->Summary_taxes; - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); - $summary = $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['percent']; $series[] = array('meta' => $row['percent'] . ' ' . round($row['total'] / $summary['total'] * 100, 2) . '%', 'value' => $row['total']); } $data = array( - "title" => $this->lang->line('reports_taxes_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/pie", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $summary, - "show_currency" => true + 'title' => $this->lang->line('reports_taxes_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/pie', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary customers report - function graphical_summary_customers($start_date, $end_date, $sale_type) + public function graphical_summary_customers($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_customers'); $model = $this->Summary_customers; - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['customer']; $series[] = $row['total']; } $data = array( - "title" => $this->lang->line('reports_customers_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/hbar", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)), - "yaxis_title" => $this->lang->line('reports_customers'), - "xaxis_title" => $this->lang->line('reports_revenue'), - "show_currency" => true + 'title' => $this->lang->line('reports_customers_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/hbar', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'yaxis_title' => $this->lang->line('reports_customers'), + 'xaxis_title' => $this->lang->line('reports_revenue'), + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary discounts report - function graphical_summary_discounts($start_date, $end_date, $sale_type) + public function graphical_summary_discounts($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_discounts'); $model = $this->Summary_discounts; - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['discount_percent']; $series[] = $row['count']; } $data = array( - "title" => $this->lang->line('reports_discounts_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/bar", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)), - "yaxis_title" => $this->lang->line('reports_count'), - "xaxis_title" => $this->lang->line('reports_discount_percent'), - "show_currency" => false + 'title' => $this->lang->line('reports_discounts_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/bar', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'yaxis_title' => $this->lang->line('reports_count'), + 'xaxis_title' => $this->lang->line('reports_discount_percent'), + 'show_currency' => FALSE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } //Graphical summary payments report - function graphical_summary_payments($start_date, $end_date, $sale_type) + public function graphical_summary_payments($start_date, $end_date, $sale_type, $location_id = 'all') { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + $this->load->model('reports/Summary_payments'); $model = $this->Summary_payments; - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); - $summary = $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type)); + $report_data = $model->getData($inputs); + $summary = $this->xss_clean($model->getSummaryData($inputs)); $labels = array(); $series = array(); foreach($report_data as $row) { + $row = $this->xss_clean($row); + $labels[] = $row['payment_type']; $series[] = array('meta' => $row['payment_type'] . ' ' . round($row['payment_amount'] / $summary['total'] * 100, 2) . '%', 'value' => $row['payment_amount']); } $data = array( - "title" => $this->lang->line('reports_payments_summary_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "chart_type" => "reports/graphs/pie", - "labels_1" => $labels, - "series_data_1" => $series, - "summary_data_1" => $summary, - "show_currency" => true + 'title' => $this->lang->line('reports_payments_summary_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'chart_type' => 'reports/graphs/pie', + 'labels_1' => $labels, + 'series_data_1' => $series, + 'summary_data_1' => $summary, + 'show_currency' => TRUE ); - $this->load->view("reports/graphical", $data); + $this->load->view('reports/graphical', $data); } - function specific_customer_input() + public function specific_customer_input() { $data = array(); $data['specific_input_name'] = $this->lang->line('reports_customer'); $customers = array(); foreach($this->Customer->get_all()->result() as $customer) - { - $customers[$customer->person_id] = $customer->first_name .' '.$customer->last_name; + { + $customers[$customer->person_id] = $this->xss_clean($customer->first_name . ' ' . $customer->last_name); } $data['specific_input_data'] = $customers; - $this->load->view("reports/specific_input", $data); + $this->load->view('reports/specific_input', $data); } - function specific_customer($start_date, $end_date, $customer_id, $sale_type) + public function specific_customer($start_date, $end_date, $customer_id, $sale_type) { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'customer_id' => $customer_id, 'sale_type' => $sale_type); + $this->load->model('reports/Specific_customer'); $model = $this->Specific_customer; - $headers = $model->getDataColumns(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'customer_id'=>$customer_id, 'sale_type'=>$sale_type)); + $model->create($inputs); + + $headers = $this->xss_clean($model->getDataColumns()); + $report_data = $model->getData($inputs); $summary_data = array(); $details_data = array(); - foreach($report_data['summary'] as $key=>$row) + foreach($report_data['summary'] as $key => $row) { - $summary_data[] = array(anchor('sales/receipt/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target'=>'_blank')), $row['sale_date'], to_quantity_decimals($row['items_purchased']), $row['employee_name'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']), to_currency($row['cost']), to_currency($row['profit']), $row['payment_type'], $row['comment']); + $summary_data[] = $this->xss_clean(array( + 'id' => anchor('sales/receipt/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target'=>'_blank')), + 'sale_date' => $row['sale_date'], + 'quantity' => to_quantity_decimals($row['items_purchased']), + 'employee_name' => $row['employee_name'], + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']), + 'payment_type' => $row['payment_type'], + 'comment' => $row['comment'])); foreach($report_data['details'][$key] as $drow) { - $details_data[$row['sale_id']][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], to_quantity_decimals($drow['quantity_purchased']), to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']), to_currency($drow['cost']), to_currency($drow['profit']), $drow['discount_percent'].'%'); + $details_data[$row['sale_id']][] = $this->xss_clean(array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], to_quantity_decimals($drow['quantity_purchased']), to_currency($drow['subtotal']), to_currency($drow['tax']), to_currency($drow['total']), to_currency($drow['cost']), to_currency($drow['profit']), $drow['discount_percent'].'%')); } } $customer_info = $this->Customer->get_info($customer_id); $data = array( - "title" => $customer_info->first_name .' '. $customer_info->last_name.' '.$this->lang->line('reports_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "summary_data" => $summary_data, - "details_data" => $details_data, - "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date,'customer_id' =>$customer_id, 'sale_type'=>$sale_type)) + 'title' => $this->xss_clean($customer_info->first_name . ' ' . $customer_info->last_name . ' ' . $this->lang->line('reports_report')), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $headers, + 'summary_data' => $summary_data, + 'details_data' => $details_data, + 'overall_summary_data' => $this->xss_clean($model->getSummaryData($inputs)) ); - $this->load->view("reports/tabular_details", $data); + $this->load->view('reports/tabular_details', $data); } - function specific_employee_input() + public function specific_employee_input() { $data = array(); $data['specific_input_name'] = $this->lang->line('reports_employee'); @@ -724,184 +772,282 @@ class Reports extends Secure_area $employees = array(); foreach($this->Employee->get_all()->result() as $employee) { - $employees[$employee->person_id] = $employee->first_name .' '.$employee->last_name; + $employees[$employee->person_id] = $this->xss_clean($employee->first_name . ' ' . $employee->last_name); } $data['specific_input_data'] = $employees; - $this->load->view("reports/specific_input", $data); + $this->load->view('reports/specific_input', $data); } - function specific_employee($start_date, $end_date, $employee_id, $sale_type) + public function specific_employee($start_date, $end_date, $employee_id, $sale_type) { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'employee_id' => $employee_id, 'sale_type' => $sale_type); + $this->load->model('reports/Specific_employee'); $model = $this->Specific_employee; - $headers = $model->getDataColumns(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'employee_id' =>$employee_id, 'sale_type'=>$sale_type)); + $model->create($inputs); + + $headers = $this->xss_clean($model->getDataColumns()); + $report_data = $model->getData($inputs); $summary_data = array(); $details_data = array(); - foreach($report_data['summary'] as $key=>$row) + foreach($report_data['summary'] as $key => $row) { - $summary_data[] = array(anchor('sales/receipt/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target'=>'_blank')), $row['sale_date'], to_quantity_decimals($row['items_purchased']), $row['customer_name'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']), to_currency($row['cost']), to_currency($row['profit']), $row['payment_type'], $row['comment']); + $summary_data[] = $this->xss_clean(array( + 'id' => anchor('sales/receipt/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target'=>'_blank')), + 'sale_date' => $row['sale_date'], + 'quantity' => to_quantity_decimals($row['items_purchased']), + 'customer_name' => $row['customer_name'], + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'cost' => to_currency($row['cost']), + 'profit' => to_currency($row['profit']), + 'payment_type' => $row['payment_type'], + 'comment' => $row['comment'])); foreach($report_data['details'][$key] as $drow) { - $details_data[$row['sale_id']][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], to_quantity_decimals($drow['quantity_purchased']), to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']), to_currency($drow['cost']), to_currency($drow['profit']), $drow['discount_percent'].'%'); + $details_data[$row['sale_id']][] = $this->xss_clean(array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], to_quantity_decimals($drow['quantity_purchased']), to_currency($drow['subtotal']), to_currency($drow['tax']), to_currency($drow['total']), to_currency($drow['cost']), to_currency($drow['profit']), $drow['discount_percent'].'%')); } } $employee_info = $this->Employee->get_info($employee_id); $data = array( - "title" => $employee_info->first_name .' '. $employee_info->last_name.' '.$this->lang->line('reports_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "summary_data" => $summary_data, - "details_data" => $details_data, - "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date,'employee_id' =>$employee_id, 'sale_type'=>$sale_type)) + 'title' => $this->xss_clean($employee_info->first_name . ' ' . $employee_info->last_name . ' ' . $this->lang->line('reports_report')), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $headers, + 'summary_data' => $summary_data, + 'details_data' => $details_data, + 'overall_summary_data' => $this->xss_clean($model->getSummaryData($inputs)) ); - $this->load->view("reports/tabular_details", $data); + $this->load->view('reports/tabular_details', $data); } - function specific_discount_input() + public function specific_discount_input() { $data = array(); $data['specific_input_name'] = $this->lang->line('reports_discount'); $discounts = array(); - for($i = 0; $i <= 100; $i += 10) + for ($i = 0; $i <= 100; $i += 10) { $discounts[$i] = $i . '%'; } $data['specific_input_data'] = $discounts; + + $data = $this->xss_clean($data); - $this->load->view("reports/specific_input", $data); + $this->load->view('reports/specific_input', $data); } - function specific_discount($start_date, $end_date, $discount, $sale_type) + public function specific_discount($start_date, $end_date, $discount, $sale_type) { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'discount' => $discount, 'sale_type' => $sale_type); + $this->load->model('reports/Specific_discount'); $model = $this->Specific_discount; - $headers = $model->getDataColumns(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'discount' =>$discount, 'sale_type'=>$sale_type)); + $model->create($inputs); + + $headers = $this->xss_clean($model->getDataColumns()); + $report_data = $model->getData($inputs); $summary_data = array(); $details_data = array(); - foreach($report_data['summary'] as $key=>$row) + foreach($report_data['summary'] as $key => $row) { - $summary_data[] = array(anchor('sales/receipt/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target'=>'_blank')), $row['sale_date'], to_quantity_decimals($row['items_purchased']), $row['customer_name'], to_currency($row['subtotal']), to_currency($row['total']), to_currency($row['tax']),/*to_currency($row['profit']),*/ $row['payment_type'], $row['comment']); + $summary_data[] = $this->xss_clean(array( + 'id' => anchor('sales/receipt/'.$row['sale_id'], 'POS '.$row['sale_id'], array('target'=>'_blank')), + 'sale_date' => $row['sale_date'], + 'quantity' => to_quantity_decimals($row['items_purchased']), + 'customer_name' => $row['customer_name'], + 'subtotal' => to_currency($row['subtotal']), + 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), + 'profit' => to_currency($row['profit']), + 'payment_type' => $row['payment_type'], + 'comment' => $row['comment'] + )); foreach($report_data['details'][$key] as $drow) { - $details_data[$row['sale_id']][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], to_quantity_decimals($drow['quantity_purchased']), to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']),/*to_currency($drow['profit']),*/ $drow['discount_percent'].'%'); + $details_data[$row['sale_id']][] = $this->xss_clean(array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], to_quantity_decimals($drow['quantity_purchased']), to_currency($drow['subtotal']), to_currency($drow['tax']), to_currency($drow['total']), to_currency($drow['profit']), $drow['discount_percent'].'%')); } } $data = array( - "title" => $discount. '% '.$this->lang->line('reports_discount') . ' ' . $this->lang->line('reports_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $headers, - "summary_data" => $summary_data, - "details_data" => $details_data, - "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date,'discount' =>$discount, 'sale_type'=>$sale_type)) + 'title' => $discount . '% ' . $this->lang->line('reports_discount') . ' ' . $this->lang->line('reports_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $headers, + 'summary_data' => $summary_data, + 'details_data' => $details_data, + 'overall_summary_data' => $this->xss_clean($model->getSummaryData($inputs)) ); - $this->load->view("reports/tabular_details", $data); + $this->load->view('reports/tabular_details', $data); } - function detailed_sales($start_date, $end_date, $sale_type, $location_id='all') + public function get_detailed_sales_row($sale_id) { + $inputs = array('sale_id' => $sale_id); + $this->load->model('reports/Detailed_sales'); $model = $this->Detailed_sales; - $headers = $model->getDataColumns(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type, 'location_id'=>$location_id)); + $model->create($inputs); + + $report_data = $model->getDataBySaleId($sale_id); + + $summary_data = $this->xss_clean(array( + 'sale_id' => $report_data['sale_id'], + 'sale_date' => $report_data['sale_date'], + 'quantity' => to_quantity_decimals($report_data['items_purchased']), + 'employee_name' => $report_data['employee_name'], + 'customer_name' => $report_data['customer_name'], + 'subtotal' => to_currency($report_data['subtotal']), + 'tax' => to_currency($report_data['tax']), + 'total' => to_currency($report_data['total']), + 'cost' => to_currency($report_data['cost']), + 'profit' => to_currency($report_data['profit']), + 'payment_type' => $report_data['payment_type'], + 'comment' => $report_data['comment'], + 'edit' => anchor('sales/edit/'. $report_data['sale_id'], '', + array('class'=>'modal-dlg print_hide', 'data-btn-delete' => $this->lang->line('common_delete'), 'data-btn-submit' => $this->lang->line('common_submit'), 'title' => $this->lang->line('sales_update')) + ) + )); + + echo json_encode(array($sale_id => $summary_data)); + } + + public function detailed_sales($start_date, $end_date, $sale_type, $location_id = 'all') + { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'sale_type' => $sale_type, 'location_id' => $location_id); + + $this->load->model('reports/Detailed_sales'); + $model = $this->Detailed_sales; + + $model->create($inputs); + + $headers = $this->xss_clean($model->getDataColumns()); + $report_data = $model->getData($inputs); $summary_data = array(); $details_data = array(); - $show_locations = $this->Stock_location->multiple_locations(); + $show_locations = $this->xss_clean($this->Stock_location->multiple_locations()); - foreach($report_data['summary'] as $key=>$row) + foreach($report_data['summary'] as $key => $row) { - $summary_data[] = array( + $summary_data[] = $this->xss_clean(array( 'id' => $row['sale_id'], 'sale_date' => $row['sale_date'], 'quantity' => to_quantity_decimals($row['items_purchased']), - 'employee' => $row['employee_name'], - 'customer' => $row['customer_name'], + 'employee_name' => $row['employee_name'], + 'customer_name' => $row['customer_name'], 'subtotal' => to_currency($row['subtotal']), - 'total' => to_currency($row['total']), 'tax' => to_currency($row['tax']), + 'total' => to_currency($row['total']), 'cost' => to_currency($row['cost']), 'profit' => to_currency($row['profit']), 'payment_type' => $row['payment_type'], 'comment' => $row['comment'], - 'edit' => anchor("sales/edit/".$row['sale_id'], '', - array('class' => "modal-dlg modal-btn-delete modal-btn-submit print_hide", 'title' => $this->lang->line('sales_update')) + 'edit' => anchor('sales/edit/'.$row['sale_id'], '', + array('class' => 'modal-dlg print_hide', 'data-btn-delete' => $this->lang->line('common_delete'), 'data-btn-submit' => $this->lang->line('common_submit'), 'title' => $this->lang->line('sales_update')) ) - ); + )); foreach($report_data['details'][$key] as $drow) { $quantity_purchased = to_quantity_decimals($drow['quantity_purchased']); - if ($show_locations) + if($show_locations) { $quantity_purchased .= ' [' . $this->Stock_location->get_location_name($drow['item_location']) . ']'; } - $details_data[$row['sale_id']][] = array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], $quantity_purchased, to_currency($drow['subtotal']), to_currency($drow['total']), to_currency($drow['tax']), to_currency($drow['cost']), to_currency($drow['profit']), $drow['discount_percent'].'%'); + $details_data[$row['sale_id']][] = $this->xss_clean(array($drow['name'], $drow['category'], $drow['serialnumber'], $drow['description'], $quantity_purchased, to_currency($drow['subtotal']), to_currency($drow['tax']), to_currency($drow['total']), to_currency($drow['cost']), to_currency($drow['profit']), $drow['discount_percent'].'%')); } } $data = array( - "title" => $this->lang->line('reports_detailed_sales_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "editable" => "sales", - "summary_data" => $summary_data, - "details_data" => $details_data, - "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'sale_type'=>$sale_type, 'location_id'=>$location_id)) + 'title' => $this->lang->line('reports_detailed_sales_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $headers, + 'editable' => 'sales', + 'summary_data' => $summary_data, + 'details_data' => $details_data, + 'overall_summary_data' => $this->xss_clean($model->getSummaryData($inputs)) ); - $this->load->view("reports/tabular_details", $data); + $this->load->view('reports/tabular_details', $data); } - function detailed_receivings($start_date, $end_date, $receiving_type, $location_id='all') + public function get_detailed_receivings_row($receiving_id) { + $inputs = array('receiving_id' => $receiving_id); + $this->load->model('reports/Detailed_receivings'); $model = $this->Detailed_receivings; + + $model->create($inputs); - $headers = $model->getDataColumns(); - $report_data = $model->getData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'receiving_type'=>$receiving_type, 'location_id'=>$location_id)); + $report_data = $model->getDataByReceivingId($receiving_id); + + $summary_data = $this->xss_clean(array( + 'receiving_id' => $report_data['receiving_id'], + 'receiving_date' => $report_data['receiving_date'], + 'quantity' => to_quantity_decimals($report_data['items_purchased']), + 'employee_name' => $report_data['employee_name'], + 'supplier_name' => $report_data['supplier_name'], + 'total' => to_currency($report_data['total']), + 'payment_type' => $report_data['payment_type'], + 'reference' => $report_data['reference'], + 'comment' => $report_data['comment'], + 'edit' => anchor('receivings/edit/'. $report_data['receiving_id'], '', + array('class'=>'modal-dlg print_hide', 'data-btn-submit' => $this->lang->line('common_submit'), 'data-btn-delete' => $this->lang->line('common_delete'), 'title' => $this->lang->line('receivings_update')) + ) + )); + + echo json_encode(array($receiving_id => $summary_data)); + } + + public function detailed_receivings($start_date, $end_date, $receiving_type, $location_id = 'all') + { + $inputs = array('start_date' => $start_date, 'end_date' => $end_date, 'receiving_type' => $receiving_type, 'location_id' => $location_id); + + $this->load->model('reports/Detailed_receivings'); + $model = $this->Detailed_receivings; + + $model->create($inputs); + + $headers = $this->xss_clean($model->getDataColumns()); + $report_data = $model->getData($inputs); $summary_data = array(); $details_data = array(); - $show_locations = $this->Stock_location->multiple_locations(); + $show_locations = $this->xss_clean($this->Stock_location->multiple_locations()); - foreach($report_data['summary'] as $key=>$row) + foreach($report_data['summary'] as $key => $row) { - $summary_data[] = array( + $summary_data[] = $this->xss_clean(array( 'id' => $row['receiving_id'], 'receiving_date' => $row['receiving_date'], 'quantity' => to_quantity_decimals($row['items_purchased']), - 'employee' => $row['employee_name'], $row['supplier_name'], + 'employee_name' => $row['employee_name'], + 'supplier_name' => $row['supplier_name'], 'total' => to_currency($row['total']), 'payment_type' => $row['payment_type'], - 'invoice_number' => $row['invoice_number'], + 'reference' => $row['reference'], 'comment' => $row['comment'], - 'edit' => anchor("receivings/edit/" . $row['receiving_id'], '', - array('class' => "modal-dlg modal-btn-delete modal-btn-submit print_hide", 'title' => $this->lang->line('receivings_update')) + 'edit' => anchor('receivings/edit/' . $row['receiving_id'], '', + array('class' => 'modal-dlg print_hide', 'data-btn-delete' => $this->lang->line('common_delete'), 'data-btn-submit' => $this->lang->line('common_submit'), 'title' => $this->lang->line('receivings_update')) ) - ); - if(!$this->config->item('invoice_enable')) - { - unset($summary_data['invoice_number']); - } + )); foreach($report_data['details'][$key] as $drow) { @@ -910,93 +1056,103 @@ class Reports extends Secure_area { $quantity_purchased .= ' [' . $this->Stock_location->get_location_name($drow['item_location']) . ']'; } - $details_data[$row['receiving_id']][] = array($drow['item_number'], $drow['name'], $drow['category'], $quantity_purchased, to_currency($drow['total']), $drow['discount_percent'].'%'); + $details_data[$row['receiving_id']][] = $this->xss_clean(array($drow['item_number'], $drow['name'], $drow['category'], $quantity_purchased, to_currency($drow['total']), $drow['discount_percent'].'%')); } } $data = array( - "title" => $this->lang->line('reports_detailed_receivings_report'), - "subtitle" => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), - "headers" => $model->getDataColumns(), - "editable" => "receivings", - "summary_data" => $summary_data, - "details_data" => $details_data, - "overall_summary_data" => $model->getSummaryData(array('start_date'=>$start_date, 'end_date'=>$end_date, 'receiving_type'=>$receiving_type, 'location_id'=>$location_id)) + 'title' => $this->lang->line('reports_detailed_receivings_report'), + 'subtitle' => date($this->config->item('dateformat'), strtotime($start_date)) . '-' . date($this->config->item('dateformat'), strtotime($end_date)), + 'headers' => $headers, + 'editable' => 'receivings', + 'summary_data' => $summary_data, + 'details_data' => $details_data, + 'overall_summary_data' => $this->xss_clean($model->getSummaryData($inputs)) ); - $this->load->view("reports/tabular_details", $data); + $this->load->view('reports/tabular_details', $data); } - function inventory_low() + public function inventory_low() { + $inputs = array(); + $this->load->model('reports/Inventory_low'); $model = $this->Inventory_low; + + $report_data = $model->getData($inputs); + $tabular_data = array(); - $report_data = $model->getData(array()); foreach($report_data as $row) { - $tabular_data[] = array($row['name'], - $row['item_number'], - $row['description'], - to_quantity_decimals($row['quantity']), - to_quantity_decimals($row['reorder_level']), - $row['location_name']); + $tabular_data[] = $this->xss_clean(array( + 'item_name' => $row['name'], + 'item_number' => $row['item_number'], + 'quantity' => to_quantity_decimals($row['quantity']), + 'reorder_level' => to_quantity_decimals($row['reorder_level']), + 'location_name' => $row['location_name'] + )); } $data = array( - "title" => $this->lang->line('reports_inventory_low_report'), - "subtitle" => '', - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData(array()) + 'title' => $this->lang->line('reports_inventory_low_report'), + 'subtitle' => '', + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $this->xss_clean($model->getSummaryData($inputs)) ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } - function inventory_summary_input() + public function inventory_summary_input() { - $data = array(); - $this->load->model('reports/Inventory_summary'); $model = $this->Inventory_summary; + + $data = array(); $data['item_count'] = $model->getItemCountDropdownArray(); - $stock_locations = $this->Stock_location->get_allowed_locations(); - $stock_locations['all'] = $this->lang->line('reports_all'); + $stock_locations = $this->xss_clean($this->Stock_location->get_allowed_locations()); + $stock_locations['all'] = $this->lang->line('reports_all'); $data['stock_locations'] = array_reverse($stock_locations, TRUE); - $this->load->view("reports/inventory_summary_input", $data); + $this->load->view('reports/inventory_summary_input', $data); } - function inventory_summary($location_id='all', $item_count='all') + public function inventory_summary($location_id = 'all', $item_count = 'all') { + $inputs = array('location_id' => $location_id, 'item_count' => $item_count); + $this->load->model('reports/Inventory_summary'); $model = $this->Inventory_summary; + + $report_data = $model->getData($inputs); + $tabular_data = array(); - $report_data = $model->getData(array('location_id'=>$location_id, 'item_count'=>$item_count)); foreach($report_data as $row) { - $tabular_data[] = array($row['name'], - $row['item_number'], - $row['description'], - to_quantity_decimals($row['quantity']), - to_quantity_decimals($row['reorder_level']), - $row['location_name'], - to_currency($row['cost_price']), - to_currency($row['unit_price']), - to_currency($row['sub_total_value'])); + $tabular_data[] = $this->xss_clean(array( + 'item_name' => $row['name'], + 'item_number' => $row['item_number'], + 'quantity' => to_quantity_decimals($row['quantity']), + 'reorder_level' => to_quantity_decimals($row['reorder_level']), + 'location_name' => $row['location_name'], + 'cost_price' => to_currency($row['cost_price']), + 'unit_price' => to_currency($row['unit_price']), + 'subtotal' => to_currency($row['sub_total_value']) + )); } $data = array( - "title" => $this->lang->line('reports_inventory_summary_report'), - "subtitle" => '', - "headers" => $model->getDataColumns(), - "data" => $tabular_data, - "summary_data" => $model->getSummaryData($report_data) + 'title' => $this->lang->line('reports_inventory_summary_report'), + 'subtitle' => '', + 'headers' => $this->xss_clean($model->getDataColumns()), + 'data' => $tabular_data, + 'summary_data' => $this->xss_clean($model->getSummaryData($report_data)) ); - $this->load->view("reports/tabular", $data); + $this->load->view('reports/tabular', $data); } } ?> \ No newline at end of file diff --git a/application/controllers/Sales.php b/application/controllers/Sales.php index 8a690f509..8c0650524 100644 --- a/application/controllers/Sales.php +++ b/application/controllers/Sales.php @@ -1,31 +1,33 @@ -load->library('sale_lib'); $this->load->library('barcode_lib'); + $this->load->library('email_lib'); } - function index() + public function index() { $this->_reload(); } - function manage() + public function manage() { $person_id = $this->session->userdata('person_id'); - if (!$this->Employee->has_grant('reports_sales', $person_id)) + if(!$this->Employee->has_grant('reports_sales', $person_id)) { redirect('no_access/sales/reports_sales'); } else { - $data['controller_name'] = $this->get_controller_name(); $data['table_headers'] = get_sales_manage_table_headers(); // filters that will be loaded in the multiselect dropdown @@ -39,39 +41,33 @@ class Sales extends Secure_area $data['filters'] = array('only_cash' => $this->lang->line('sales_cash_filter')); } - $this->load->view($data['controller_name'] . '/manage', $data); + $this->load->view('sales/manage', $data); } } - function get_row($row_id) + public function get_row($row_id) { - $this->Sale->create_sales_items_temp_table(); - $sale_info = $this->Sale->get_info($row_id)->row(); - $data_row = get_sale_data_row($sale_info, $this); + $data_row = $this->xss_clean(get_sale_data_row($sale_info, $this)); echo json_encode($data_row); } - - function search() + + public function search() { - $this->Sale->create_sales_items_temp_table(); - $search = $this->input->get('search'); - $limit = $this->input->get('limit'); + $limit = $this->input->get('limit'); $offset = $this->input->get('offset'); - $sort = $this->input->get('sort'); - $order = $this->input->get('order'); - - $is_valid_receipt = isset($search) ? $this->sale_lib->is_valid_receipt($search) : FALSE; + $sort = $this->input->get('sort'); + $order = $this->input->get('order'); $filters = array('sale_type' => 'all', - 'location_id' => 'all', - 'start_date' => $this->input->get('start_date'), - 'end_date' => $this->input->get('end_date'), - 'only_cash' => FALSE, - 'only_invoices' => $this->config->item('invoice_enable') && $this->input->get('only_invoices'), - 'is_valid_receipt' => $is_valid_receipt); + 'location_id' => 'all', + 'start_date' => $this->input->get('start_date'), + 'end_date' => $this->input->get('end_date'), + 'only_cash' => FALSE, + 'only_invoices' => $this->config->item('invoice_enable') && $this->input->get('only_invoices'), + 'is_valid_receipt' => $this->Sale->is_valid_receipt($search)); // check if any filter is set in the multiselect dropdown $filledup = array_fill_keys($this->input->get('filters'), TRUE); @@ -80,69 +76,77 @@ class Sales extends Secure_area $sales = $this->Sale->search($search, $filters, $limit, $offset, $sort, $order); $total_rows = $this->Sale->get_found_rows($search, $filters); $payments = $this->Sale->get_payments_summary($search, $filters); - $payment_summary = get_sales_manage_payments_summary($payments, $sales, $this); + $payment_summary = $this->xss_clean(get_sales_manage_payments_summary($payments, $sales, $this)); $data_rows = array(); foreach($sales->result() as $sale) { - $data_rows[] = get_sale_data_row($sale, $this); + $data_rows[] = $this->xss_clean(get_sale_data_row($sale, $this)); } - if ($total_rows > 0) + if($total_rows > 0) { - $total_rows++; - $data_rows[] = get_sale_data_last_row($sales, $this); + $data_rows[] = $this->xss_clean(get_sale_data_last_row($sales, $this)); } - echo json_encode(array('total' => $total_rows, 'rows' => $data_rows,'payment_summary' => $payment_summary)); + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows, 'payment_summary' => $payment_summary)); } - function item_search() + public function item_search() { $suggestions = array(); - $search = $this->input->get('term') != '' ? $this->input->get('term') : null; + $receipt = $search = $this->input->get('term') != '' ? $this->input->get('term') : NULL; - if ($this->sale_lib->get_mode() == 'return' && $this->sale_lib->is_valid_receipt($search) ) + if($this->sale_lib->get_mode() == 'return' && $this->Sale->is_valid_receipt($receipt)) { - $suggestions[] = $search; + // if a valid receipt or invoice was found the search term will be replaced with a receipt number (POS #) + $suggestions[] = $receipt; } - $suggestions = array_merge($suggestions, $this->Item->get_search_suggestions($search, array( - 'search_custom' => FALSE, - 'is_deleted' => FALSE - ), TRUE)); + $suggestions = array_merge($suggestions, $this->Item->get_search_suggestions($search, array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE)); $suggestions = array_merge($suggestions, $this->Item_kit->get_search_suggestions($search)); + + $suggestions = $this->xss_clean($suggestions); echo json_encode($suggestions); } - function suggest_search() + public function suggest_search() { - $search = $this->input->post('term') != '' ? $this->input->post('term') : null; + $search = $this->input->post('term') != '' ? $this->input->post('term') : NULL; - $suggestions = $this->Sale->get_search_suggestions($search); + $suggestions = $this->xss_clean($this->Sale->get_search_suggestions($search)); echo json_encode($suggestions); } - function select_customer() + public function select_customer() { $customer_id = $this->input->post('customer'); - if ($this->Customer->exists($customer_id)) + if($this->Customer->exists($customer_id)) { $this->sale_lib->set_customer($customer_id); + + $discount_percent = $this->Customer->get_info($customer_id)->discount_percent; + + // apply customer default discount to items that have 0 discount + if($discount_percent != '') + { + $this->sale_lib->apply_customer_discount($discount_percent); + } } + $this->_reload(); } - function change_mode() + public function change_mode() { - $stock_location = $this->input->post("stock_location"); + $stock_location = $this->input->post('stock_location'); if (!$stock_location || $stock_location == $this->sale_lib->get_sale_location()) { - $mode = $this->input->post("mode"); + $mode = $this->input->post('mode'); $this->sale_lib->set_mode($mode); } - else if ($this->Stock_location->is_allowed_location($stock_location, 'sales')) + elseif($this->Stock_location->is_allowed_location($stock_location, 'sales')) { $this->sale_lib->set_sale_location($stock_location); } @@ -150,173 +154,189 @@ class Sales extends Secure_area $this->_reload(); } - function set_comment() + public function set_comment() { $this->sale_lib->set_comment($this->input->post('comment')); } - function set_invoice_number() + public function set_invoice_number() { $this->sale_lib->set_invoice_number($this->input->post('sales_invoice_number')); } - function set_invoice_number_enabled() + public function set_invoice_number_enabled() { $this->sale_lib->set_invoice_number_enabled($this->input->post('sales_invoice_number_enabled')); } - function set_print_after_sale() + public function set_print_after_sale() { $this->sale_lib->set_print_after_sale($this->input->post('sales_print_after_sale')); } - function set_email_receipt() + public function set_email_receipt() { $this->sale_lib->set_email_receipt($this->input->post('email_receipt')); } // Multiple Payments - function add_payment() - { + public function add_payment() + { $data = array(); - $this->form_validation->set_rules('amount_tendered', 'lang:sales_amount_tendered', 'trim|required|numeric'); - - if ( $this->form_validation->run() == FALSE ) + $this->form_validation->set_rules('amount_tendered', 'lang:sales_amount_tendered', 'trim|required|callback_numeric'); + + $payment_type = $this->input->post('payment_type'); + + if($this->form_validation->run() == FALSE) { - if ( $this->input->post('payment_type') == $this->lang->line('sales_gift_card') ) + if($payment_type == $this->lang->line('sales_giftcard')) { - $data['error']=$this->lang->line('sales_must_enter_numeric_giftcard'); + $data['error'] = $this->lang->line('sales_must_enter_numeric_giftcard'); } else { - $data['error']=$this->lang->line('sales_must_enter_numeric'); + $data['error'] = $this->lang->line('sales_must_enter_numeric'); } - - $this->_reload( $data ); - - return; - } - - $payment_type = $this->input->post('payment_type'); - if ( $payment_type == $this->lang->line('sales_giftcard') ) - { - $payments = $this->sale_lib->get_payments(); - $payment_type = $this->input->post('payment_type') . ':' . $payment_amount = $this->input->post('amount_tendered'); - $current_payments_with_giftcard = isset($payments[$payment_type]) ? $payments[$payment_type]['payment_amount'] : 0; - $cur_giftcard_value = $this->Giftcard->get_giftcard_value($this->input->post('amount_tendered')) - $current_payments_with_giftcard; - - if ( $cur_giftcard_value <= 0 ) - { - $data['error'] = $this->lang->line('giftcards_remaining_balance', $this->input->post('amount_tendered'), to_currency( $this->Giftcard->get_giftcard_value( $this->input->post('amount_tendered')))); - $this->_reload( $data ); - return; - } - $new_giftcard_value = $this->Giftcard->get_giftcard_value( $this->input->post('amount_tendered') ) - $this->sale_lib->get_amount_due(); - $new_giftcard_value = ( $new_giftcard_value >= 0 ) ? $new_giftcard_value : 0; - $this->sale_lib->set_giftcard_remainder($new_giftcard_value); - $data['warning'] = $this->lang->line('giftcards_remaining_balance', $this->input->post('amount_tendered'), to_currency( $new_giftcard_value, TRUE )); - $payment_amount = min( $this->sale_lib->get_amount_due(), $this->Giftcard->get_giftcard_value( $this->input->post('amount_tendered') ) ); } else { - $payment_amount = $this->input->post('amount_tendered'); + if($payment_type == $this->lang->line('sales_giftcard')) + { + // in case of giftcard payment the register input amount_tendered becomes the giftcard number + $giftcard_num = $this->input->post('amount_tendered'); + + $payments = $this->sale_lib->get_payments(); + $payment_type = $payment_type . ':' . $giftcard_num; + $current_payments_with_giftcard = isset($payments[$payment_type]) ? $payments[$payment_type]['payment_amount'] : 0; + $cur_giftcard_value = $this->Giftcard->get_giftcard_value($giftcard_num); + + if(($cur_giftcard_value - $current_payments_with_giftcard) <= 0) + { + $data['error'] = $this->lang->line('giftcards_remaining_balance', $giftcard_num, to_currency($cur_giftcard_value)); + } + else + { + $new_giftcard_value = $this->Giftcard->get_giftcard_value($giftcard_num) - $this->sale_lib->get_amount_due(); + $new_giftcard_value = $new_giftcard_value >= 0 ? $new_giftcard_value : 0; + $this->sale_lib->set_giftcard_remainder($new_giftcard_value); + $new_giftcard_value = str_replace('$', '\$', to_currency($new_giftcard_value)); + $data['warning'] = $this->lang->line('giftcards_remaining_balance', $giftcard_num, $new_giftcard_value); + $amount_tendered = min( $this->sale_lib->get_amount_due(), $this->Giftcard->get_giftcard_value($giftcard_num) ); + + $this->sale_lib->add_payment($payment_type, $amount_tendered); + } + } + else + { + $amount_tendered = $this->input->post('amount_tendered'); + + $this->sale_lib->add_payment($payment_type, $amount_tendered); + } } - - if( !$this->sale_lib->add_payment( $payment_type, $payment_amount ) ) - { - $data['error'] = 'Unable to Add Payment! Please try again!'; - } - + $this->_reload($data); } // Multiple Payments - function delete_payment( $payment_id ) + public function delete_payment($payment_id) { - $this->sale_lib->delete_payment( $payment_id ); + $this->sale_lib->delete_payment($payment_id); $this->_reload(); } - function add() + public function add() { $data = array(); - - $mode = $this->sale_lib->get_mode(); - $item_id_or_number_or_item_kit_or_receipt = $this->input->post('item'); - $quantity = ($mode == "return") ? -1 : 1; - $item_location = $this->sale_lib->get_sale_location(); - - $discount = 0; + $discount = 0; + // check if any discount is assigned to the selected customer $customer_id = $this->sale_lib->get_customer(); if($customer_id != -1) { // load the customer discount if any - $discount = $this->Customer->get_info($customer_id)->discount_percent == '' ? 0 : $this->Customer->get_info($customer_id)->discount_percent; + $discount_percent = $this->Customer->get_info($customer_id)->discount_percent; + if($discount_percent != '') + { + $discount = $discount_percent; + } } - + // if the customer discount is 0 or no customer is selected apply the default sales discount if($discount == 0) { $discount = $this->config->item('default_sales_discount'); } - - if($mode == 'return' && $this->sale_lib->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt)) + + $mode = $this->sale_lib->get_mode(); + $quantity = ($mode == 'return') ? -1 : 1; + $item_location = $this->sale_lib->get_sale_location(); + $item_id_or_number_or_item_kit_or_receipt = $this->input->post('item'); + + if($mode == 'return' && $this->Sale->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt)) { $this->sale_lib->return_entire_sale($item_id_or_number_or_item_kit_or_receipt); } - else if($this->sale_lib->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) + elseif($this->Item_kit->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) { - $this->sale_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt, $item_location); + if(!$this->sale_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt, $item_location, $discount)) + { + $data['error'] = $this->lang->line('sales_unable_to_add_item'); + } } - else if(!$this->sale_lib->add_item($item_id_or_number_or_item_kit_or_receipt, $quantity, $item_location, $discount)) + else { - $data['error'] = $this->lang->line('sales_unable_to_add_item'); + if(!$this->sale_lib->add_item($item_id_or_number_or_item_kit_or_receipt, $quantity, $item_location, $discount)) + { + $data['error'] = $this->lang->line('sales_unable_to_add_item'); + } + else + { + $data['warning'] = $this->sale_lib->out_of_stock($item_id_or_number_or_item_kit_or_receipt, $item_location); + } } - - $data['warning'] = $this->sale_lib->out_of_stock($item_id_or_number_or_item_kit_or_receipt, $item_location); $this->_reload($data); } - function edit_item($line) + public function edit_item($item_id) { $data = array(); - $this->form_validation->set_rules('price', 'lang:items_price', 'required|numeric'); - $this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|numeric'); - $this->form_validation->set_rules('discount', 'lang:items_discount', 'required|numeric'); + $this->form_validation->set_rules('price', 'lang:items_price', 'required|callback_numeric'); + $this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|callback_numeric'); + $this->form_validation->set_rules('discount', 'lang:items_discount', 'required|callback_numeric'); $description = $this->input->post('description'); $serialnumber = $this->input->post('serialnumber'); - $price = $this->input->post('price'); - $quantity = $this->input->post('quantity'); - $discount = $this->input->post('discount'); + $price = parse_decimals($this->input->post('price')); + $quantity = parse_decimals($this->input->post('quantity')); + $discount = parse_decimals($this->input->post('discount')); $item_location = $this->input->post('location'); - if ($this->form_validation->run() != FALSE) + if($this->form_validation->run() != FALSE) { - $this->sale_lib->edit_item($line, $description, $serialnumber, $quantity, $discount, $price); + $this->sale_lib->edit_item($item_id, $description, $serialnumber, $quantity, $discount, $price); } else { $data['error'] = $this->lang->line('sales_error_editing_item'); } - $data['warning'] = $this->sale_lib->out_of_stock($this->sale_lib->get_item_id($line),$item_location); + + $data['warning'] = $this->sale_lib->out_of_stock($this->sale_lib->get_item_id($item_id), $item_location); $this->_reload($data); } - function delete_item($item_number) + public function delete_item($item_number) { $this->sale_lib->delete_item($item_number); $this->_reload(); } - function remove_customer() + public function remove_customer() { $this->sale_lib->clear_giftcard_remainder(); $this->sale_lib->clear_invoice_number(); @@ -325,8 +345,10 @@ class Sales extends Secure_area $this->_reload(); } - function complete() + public function complete() { + $data = array(); + $data['cart'] = $this->sale_lib->get_cart(); $data['subtotal'] = $this->sale_lib->get_subtotal(); $data['discounted_subtotal'] = $this->sale_lib->get_subtotal(TRUE); @@ -335,7 +357,7 @@ class Sales extends Secure_area $data['total'] = $this->sale_lib->get_total(); $data['discount'] = $this->sale_lib->get_discount(); $data['receipt_title'] = $this->lang->line('sales_receipt'); - $data['transaction_time'] = date($this->config->item('dateformat').' '.$this->config->item('timeformat')); + $data['transaction_time'] = date($this->config->item('dateformat') . ' ' . $this->config->item('timeformat')); $data['transaction_date'] = date($this->config->item('dateformat')); $data['show_stock_locations'] = $this->Stock_location->show_locations('sales'); $data['comments'] = $this->sale_lib->get_comment(); @@ -343,125 +365,127 @@ class Sales extends Secure_area $data['amount_change'] = $this->sale_lib->get_amount_due() * -1; $data['amount_due'] = $this->sale_lib->get_amount_due(); $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - $emp_info = $this->Employee->get_info($employee_id); - $data['employee'] = $emp_info->first_name . ' ' . $emp_info->last_name; + $employee_info = $this->Employee->get_info($employee_id); + $data['employee'] = $employee_info->first_name . ' ' . $employee_info->last_name[0]; $data['company_info'] = implode("\n", array( - $this->config->item('address'), - $this->config->item('phone'), - $this->config->item('account_number') + $this->config->item('address'), + $this->config->item('phone'), + $this->config->item('account_number') )); $customer_id = $this->sale_lib->get_customer(); - $cust_info = $this->_load_customer_data($customer_id, $data); - $invoice_number = $this->_substitute_invoice_number($cust_info); - if ($this->sale_lib->is_invoice_number_enabled() && $this->Sale->invoice_number_exists($invoice_number)) + $customer_info = $this->_load_customer_data($customer_id, $data); + $invoice_number = $this->_substitute_invoice_number($customer_info); + + if($this->sale_lib->is_invoice_number_enabled() && $this->Sale->check_invoice_number_exists($invoice_number)) { $data['error'] = $this->lang->line('sales_invoice_number_duplicate'); + $this->_reload($data); } else { - $invoice_number = $this->sale_lib->is_invoice_number_enabled() ? $invoice_number : null; + $invoice_number = $this->sale_lib->is_invoice_number_enabled() ? $invoice_number : NULL; $data['invoice_number'] = $invoice_number; - $data['sale_id'] = 'POS ' . $this->Sale->save($data['cart'], $customer_id, $employee_id, $data['comments'], $invoice_number, $data['payments']); - if ($data['sale_id'] == 'POS -1') + $data['sale_id_num'] = $this->Sale->save($data['cart'], $customer_id, $employee_id, $data['comments'], $invoice_number, $data['payments']); + $data['sale_id'] = 'POS ' . $data['sale_id_num']; + + $data = $this->xss_clean($data); + + if($data['sale_id_num'] == -1) { $data['error_message'] = $this->lang->line('sales_transaction_failed'); } else { $data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['sale_id']); - // if we want to email. .. just attach the pdf in there? - if ($this->sale_lib->get_email_receipt() && !empty($cust_info->email)) - { - $this->load->library('email'); - $config['mailtype'] = 'html'; - $this->email->initialize($config); - $this->email->from($this->config->item('email'), $this->config->item('company')); - $this->email->to($cust_info->email); - - $this->email->subject($this->lang->line('sales_receipt')); - if ($this->config->item('use_invoice_template') && $this->sale_lib->is_invoice_number_enabled()) - { - $data['image_prefix'] = ""; - $filename = $this->_invoice_email_pdf($data); - $this->email->attach($filename); - $text = $this->config->item('invoice_email_message'); - $text = str_replace('$INV', $invoice_number, $text); - $text = str_replace('$CO', $data['sale_id'], $text); - $text = $this->_substitute_customer($text, $cust_info); - $this->email->message($text); - } - else - { - $this->email->message($this->load->view("sales/receipt_email", $data, true)); - } - $this->email->send(); - } } + $data['cur_giftcard_value'] = $this->sale_lib->get_giftcard_remainder(); $data['print_after_sale'] = $this->sale_lib->is_print_after_sale(); - if ($this->sale_lib->is_invoice_number_enabled() && $this->config->item('use_invoice_template')) + $data['email_receipt'] = $this->sale_lib->get_email_receipt(); + + if($this->sale_lib->is_invoice_number_enabled()) { - $this->load->view("sales/invoice", $data); + $this->load->view('sales/invoice', $data); } else { - $this->load->view("sales/receipt", $data); + $this->load->view('sales/receipt', $data); } $this->sale_lib->clear_all(); } } - - private function _invoice_email_pdf($data) - { - $data['image_prefix'] = ""; - $html = $this->load->view('sales/invoice_email', $data, true); - // load pdf helper - $this->load->helper(array('dompdf', 'file')); - $file_content = pdf_create($html, '', false); - $filename = sys_get_temp_dir() . '/'. $this->lang->line('sales_invoice') . '-' . str_replace('/', '-' , $data["invoice_number"]) . '.pdf'; - write_file($filename, $file_content); - return $filename; - } - - function invoice_email($sale_id) + public function send_invoice($sale_id) { $sale_data = $this->_load_sale_data($sale_id); - $sale_data['image_prefix'] = base_url(); - $this->load->view('sales/invoice_email', $sale_data); - $this->sale_lib->clear_all(); - } - - function send_invoice($sale_id) - { - $sale_data = $this->_load_sale_data($sale_id); - $text = $this->config->item('invoice_email_message'); - $text = str_replace('$INV', $sale_data['invoice_number'], $text); - $text = str_replace('$CO', 'POS ' . $sale_data['sale_id'], $text); - $text = $this->_substitute_customer($text,(object) $sale_data); + $result = FALSE; $message = $this->lang->line('sales_invoice_no_email'); - if (isset($sale_data["customer_email"]) && !empty( $sale_data["customer_email"])) { - $this->load->library('email'); - $this->email->from($this->config->item('email'), $this->config->item('company')); - $this->email->to($sale_data['customer_email']); - $this->email->subject($this->lang->line('sales_invoice') . ' ' . $sale_data['invoice_number']); - $this->email->message($text); - $filename = $this->_invoice_email_pdf($sale_data); - $this->email->attach($filename); - $result = $this->email->send(); - $message = $this->lang->line($result ? 'sales_invoice_sent' : 'sales_invoice_unsent') . ' ' . $sale_data["customer_email"]; + + if(!empty($sale_data['customer_email'])) + { + $to = $sale_data['customer_email']; + $subject = $this->lang->line('sales_invoice') . ' ' . $sale_data['invoice_number']; + + $text = $this->config->item('invoice_email_message'); + $text = str_replace('$INV', $sale_data['invoice_number'], $text); + $text = str_replace('$CO', 'POS ' . $sale_data['sale_id'], $text); + $text = $this->_substitute_customer($text, (object) $sale_data); + + // generate email attachment: invoice in pdf format + $html = $this->load->view('sales/invoice_email', $sale_data, TRUE); + // load pdf helper + $this->load->helper(array('dompdf', 'file')); + $filename = sys_get_temp_dir() . '/' . $this->lang->line('sales_invoice') . '-' . str_replace('/', '-' , $sale_data['invoice_number']) . '.pdf'; + if(file_put_contents($filename, pdf_create($html)) !== FALSE) + { + $result = $this->email_lib->sendEmail($to, $subject, $text, $filename); + } + + $message = $this->lang->line($result ? 'sales_invoice_sent' : 'sales_invoice_unsent') . ' ' . $to; } - echo json_encode(array('success'=>$result, 'message'=>$message, 'id'=>$sale_id)); + + echo json_encode(array('success' => $result, 'message' => $message, 'id' => $sale_id)); + $this->sale_lib->clear_all(); + + return $result; } - + + public function send_receipt($sale_id) + { + $sale_data = $this->_load_sale_data($sale_id); + + $result = FALSE; + $message = $this->lang->line('sales_receipt_no_email'); + + if(!empty($sale_data['customer_email'])) + { + $sale_data['barcode'] = $this->barcode_lib->generate_receipt_barcode($sale_data['sale_id']); + + $to = $sale_data['customer_email']; + $subject = $this->lang->line('sales_receipt'); + + $text = $this->load->view('sales/receipt_email', $sale_data, TRUE); + + $result = $this->email_lib->sendEmail($to, $subject, $text); + + $message = $this->lang->line($result ? 'sales_receipt_sent' : 'sales_receipt_unsent') . ' ' . $to; + } + + echo json_encode(array('success' => $result, 'message' => $message, 'id' => $sale_id)); + + $this->sale_lib->clear_all(); + + return $result; + } + private function _substitute_variable($text, $variable, $object, $function) { // don't query if this variable isn't used - if (strstr($text, $variable)) + if(strstr($text, $variable)) { $value = call_user_func(array($object, $function)); $text = str_replace($variable, $value, $text); @@ -469,17 +493,17 @@ class Sales extends Secure_area return $text; } - - private function _substitute_customer($text, $cust_info) + + private function _substitute_customer($text, $customer_info) { // substitute customer info $customer_id = $this->sale_lib->get_customer(); - if($customer_id != -1 && $cust_info != '') + if($customer_id != -1 && $customer_info != '') { - $text = str_replace('$CU',$cust_info->first_name . ' ' . $cust_info->last_name,$text); - $words = preg_split("/\s+/", trim($cust_info->first_name . ' ' . $cust_info->last_name)); - $acronym = ""; - foreach ($words as $w) + $text = str_replace('$CU', $customer_info->first_name . ' ' . $customer_info->last_name, $text); + $words = preg_split("/\s+/", trim($customer_info->first_name . ' ' . $customer_info->last_name)); + $acronym = ''; + foreach($words as $w) { $acronym .= $w[0]; } @@ -489,41 +513,86 @@ class Sales extends Secure_area return $text; } - private function _is_custom_invoice_number($cust_info) + private function _is_custom_invoice_number($customer_info) { $invoice_number = $this->config->config['sales_invoice_format']; - $invoice_number = $this->_substitute_variables($invoice_number, $cust_info); + $invoice_number = $this->_substitute_variables($invoice_number, $customer_info); return $this->sale_lib->get_invoice_number() != $invoice_number; } - - private function _substitute_variables($text, $cust_info) + + private function _substitute_variables($text, $customer_info) { $text = $this->_substitute_variable($text, '$YCO', $this->Sale, 'get_invoice_number_for_year'); $text = $this->_substitute_variable($text, '$CO', $this->Sale , 'get_invoice_count'); $text = $this->_substitute_variable($text, '$SCO', $this->Sale_suspended, 'get_invoice_count'); $text = strftime($text); - $text = $this->_substitute_customer($text, $cust_info); + $text = $this->_substitute_customer($text, $customer_info); return $text; } - - private function _substitute_invoice_number($cust_info) + + private function _substitute_invoice_number($customer_info) { $invoice_number = $this->config->config['sales_invoice_format']; - $invoice_number = $this->_substitute_variables($invoice_number, $cust_info); + $invoice_number = $this->_substitute_variables($invoice_number, $customer_info); $this->sale_lib->set_invoice_number($invoice_number, TRUE); return $this->sale_lib->get_invoice_number(); } + private function _load_customer_data($customer_id, &$data, $totals = FALSE) + { + $customer_info = ''; + + if($customer_id != -1) + { + $customer_info = $this->Customer->get_info($customer_id); + if(isset($customer_info->company_name)) + { + $data['customer'] = $customer_info->company_name; + } + else + { + $data['customer'] = $customer_info->first_name . ' ' . $customer_info->last_name; + } + $data['first_name'] = $customer_info->first_name; + $data['last_name'] = $customer_info->last_name; + $data['customer_email'] = $customer_info->email; + $data['customer_address'] = $customer_info->address_1; + if(!empty($customer_info->zip) or !empty($customer_info->city)) + { + $data['customer_location'] = $customer_info->zip . ' ' . $customer_info->city; + } + else + { + $data['customer_location'] = ''; + } + $data['customer_account_number'] = $customer_info->account_number; + $data['customer_discount_percent'] = $customer_info->discount_percent; + if($totals) + { + $cust_totals = $this->Customer->get_totals($customer_id); + + $data['customer_total'] = $cust_totals->total; + } + $data['customer_info'] = implode("\n", array( + $data['customer'], + $data['customer_address'], + $data['customer_location'], + $data['customer_account_number'] + )); + } + + return $customer_info; + } + private function _load_sale_data($sale_id) { - $this->Sale->create_sales_items_temp_table(); - $this->sale_lib->clear_all(); $sale_info = $this->Sale->get_info($sale_id)->row_array(); $this->sale_lib->copy_entire_sale($sale_id); + $data = array(); $data['cart'] = $this->sale_lib->get_cart(); $data['payments'] = $this->sale_lib->get_payments(); $data['subtotal'] = $this->sale_lib->get_subtotal(); @@ -538,13 +607,11 @@ class Sales extends Secure_area $data['show_stock_locations'] = $this->Stock_location->show_locations('sales'); $data['amount_change'] = $this->sale_lib->get_amount_due() * -1; $data['amount_due'] = $this->sale_lib->get_amount_due(); - $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - $emp_info = $this->Employee->get_info($employee_id); - $data['employee'] = $emp_info->first_name . ' ' . $emp_info->last_name; + $employee_info = $this->Employee->get_info($this->sale_lib->get_employee()); + $data['employee'] = $employee_info->first_name . ' ' . $employee_info->last_name[0]; + $this->_load_customer_data($this->sale_lib->get_customer(), $data); - $customer_id = $this->sale_lib->get_customer(); - $cust_info = $this->_load_customer_data($customer_id, $data); - + $data['sale_id_num'] = $sale_id; $data['sale_id'] = 'POS ' . $sale_id; $data['comments'] = $sale_info['comment']; $data['invoice_number'] = $sale_info['invoice_number']; @@ -556,101 +623,149 @@ class Sales extends Secure_area $data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['sale_id']); $data['print_after_sale'] = FALSE; - return $data; + return $this->xss_clean($data); } - - function receipt($sale_id) - { - $data = $this->_load_sale_data($sale_id); - $this->load->view("sales/receipt", $data); - $this->sale_lib->clear_all(); - } - - function invoice($sale_id, $sale_info='') - { - if($sale_info == '') - { - $sale_info = $this->_load_sale_data($sale_id); - } - $this->load->view("sales/invoice", $sale_info); + private function _reload($data = array()) + { + $data['cart'] = $this->sale_lib->get_cart(); + $data['modes'] = array('sale' => $this->lang->line('sales_sale'), 'return' => $this->lang->line('sales_return')); + $data['mode'] = $this->sale_lib->get_mode(); + $data['stock_locations'] = $this->Stock_location->get_allowed_locations('sales'); + $data['stock_location'] = $this->sale_lib->get_sale_location(); + $data['subtotal'] = $this->sale_lib->get_subtotal(TRUE); + $data['tax_exclusive_subtotal'] = $this->sale_lib->get_subtotal(TRUE, TRUE); + $data['taxes'] = $this->sale_lib->get_taxes(); + $data['discount'] = $this->sale_lib->get_discount(); + $data['total'] = $this->sale_lib->get_total(); + $data['comment'] = $this->sale_lib->get_comment(); + $data['email_receipt'] = $this->sale_lib->get_email_receipt(); + $data['payments_total'] = $this->sale_lib->get_payments_total(); + $data['amount_due'] = $this->sale_lib->get_amount_due(); + $data['payments'] = $this->sale_lib->get_payments(); + $data['payment_options'] = $this->Sale->get_payment_options(); + + $data['items_module_allowed'] = $this->Employee->has_grant('items', $this->Employee->get_logged_in_employee_info()->person_id); + + $customer_info = $this->_load_customer_data($this->sale_lib->get_customer(), $data, TRUE); + $data['invoice_number'] = $this->_substitute_invoice_number($customer_info); + $data['invoice_number_enabled'] = $this->sale_lib->is_invoice_number_enabled(); + $data['print_after_sale'] = $this->sale_lib->is_print_after_sale(); + $data['payments_cover_total'] = $this->sale_lib->get_amount_due() <= 0; + + $data = $this->xss_clean($data); + + $this->load->view("sales/register", $data); + } + + public function receipt($sale_id) + { + $data = $this->_load_sale_data($sale_id); + + $this->load->view('sales/receipt', $data); + $this->sale_lib->clear_all(); } - - function edit($sale_id) + + public function invoice($sale_id) + { + $data = $this->_load_sale_data($sale_id); + + $this->load->view('sales/invoice', $data); + + $this->sale_lib->clear_all(); + } + + public function edit($sale_id) { $data = array(); $data['employees'] = array(); - foreach ($this->Employee->get_all()->result() as $employee) + foreach($this->Employee->get_all()->result() as $employee) { - $data['employees'][$employee->person_id] = $employee->first_name . ' '. $employee->last_name; + foreach(get_object_vars($employee) as $property => $value) + { + $employee->$property = $this->xss_clean($value); + } + + $data['employees'][$employee->person_id] = $employee->first_name . ' ' . $employee->last_name; } - $this->Sale->create_sales_items_temp_table(); - $sale_info = $this->Sale->get_info($sale_id)->row_array(); - $person_name = $sale_info['first_name'] . " " . $sale_info['last_name']; - $data['selected_customer_name'] = !empty($sale_info['customer_id']) ? $person_name : ''; + $sale_info = $this->xss_clean($this->Sale->get_info($sale_id)->row_array()); + $data['selected_customer_name'] = $sale_info['customer_name']; $data['selected_customer_id'] = $sale_info['customer_id']; $data['sale_info'] = $sale_info; - $data['payments'] = $this->Sale->get_sale_payments($sale_id); + + $data['payments'] = array(); + foreach($this->Sale->get_sale_payments($sale_id)->result() as $payment) + { + foreach(get_object_vars($payment) as $property => $value) + { + $payment->$property = $this->xss_clean($value); + } + + $data['payments'][] = $payment; + } + // don't allow gift card to be a payment option in a sale transaction edit because it's a complex change - $data['payment_options'] = $this->Sale->get_payment_options(false); + $data['payment_options'] = $this->xss_clean($this->Sale->get_payment_options(FALSE)); $this->load->view('sales/form', $data); } - - function delete($sale_id = -1, $update_inventory=TRUE) + + public function delete($sale_id = -1, $update_inventory = TRUE) { $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; $sale_ids = $sale_id == -1 ? $this->input->post('ids') : array($sale_id); if($this->Sale->delete_list($sale_ids, $employee_id, $update_inventory)) { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('sales_successfully_deleted').' '. - count($sale_ids).' '.$this->lang->line('sales_one_or_multiple'), 'ids'=>$sale_ids)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('sales_successfully_deleted') . ' ' . + count($sale_ids) . ' ' . $this->lang->line('sales_one_or_multiple'), 'ids' => $sale_ids)); } else { - echo json_encode(array('success'=>false, 'message'=>$this->lang->line('sales_unsuccessfully_deleted'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('sales_unsuccessfully_deleted'))); } } - - function save($sale_id) + + public function save($sale_id = -1) { $newdate = $this->input->post('date'); - - $start_date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $newdate); + + $date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $newdate); $sale_data = array( - 'sale_time' => $start_date_formatter->format('Y-m-d H:i:s'), - 'customer_id' => $this->input->post('customer_id') != '' ? $this->input->post('customer_id') : null, + 'sale_time' => $date_formatter->format('Y-m-d H:i:s'), + 'customer_id' => $this->input->post('customer_id') != '' ? $this->input->post('customer_id') : NULL, 'employee_id' => $this->input->post('employee_id'), 'comment' => $this->input->post('comment'), - 'invoice_number' => $this->input->post('invoice_number') != '' ? $this->input->post('invoice_number') : null + 'invoice_number' => $this->input->post('invoice_number') != '' ? $this->input->post('invoice_number') : NULL ); - + // go through all the payment type input from the form, make sure the form matches the name and iterator number $payments = array(); - for($i = 0; $i < $this->input->post('number_of_payments'); $i++) + $number_of_payments = $this->input->post('number_of_payments'); + for ($i = 0; $i < $number_of_payments; ++$i) { - $payment_amount = $this->input->post('payment_amount_'.$i); - $payment_type = $this->input->post('payment_type_'.$i); + $payment_amount = $this->input->post('payment_amount_' . $i); + $payment_type = $this->input->post('payment_type_' . $i); // remove any 0 payment if by mistake any was introduced at sale time if($payment_amount != 0) { // search for any payment of the same type that was already added, if that's the case add up the new payment amount $key = FALSE; - if( !empty($payments) ) + if(!empty($payments)) { - // search in the multi array the key of the entry containing the current payment_type (NOTE: in PHP5.5 the array_map could be replaced by an array_column) + // search in the multi array the key of the entry containing the current payment_type + // NOTE: in PHP5.5 the array_map could be replaced by an array_column $key = array_search($payment_type, array_map(function($v){return $v['payment_type'];}, $payments)); } // if no previous payment is found add a new one - if( $key === FALSE ) + if($key === FALSE) { - $payments[] = array('payment_type'=>$payment_type, 'payment_amount'=>$payment_amount); + $payments[] = array('payment_type' => $payment_type, 'payment_amount' => $payment_amount); } else { @@ -659,179 +774,62 @@ class Sales extends Secure_area } } } - + if($this->Sale->update($sale_id, $sale_data, $payments)) { - echo json_encode(array('success'=>true, 'message'=>$this->lang->line('sales_successfully_updated'), 'id'=>$sale_id)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('sales_successfully_updated'), 'id' => $sale_id)); } else { - echo json_encode(array('success'=>false, 'message'=>$this->lang->line('sales_unsuccessfully_updated'), 'id'=>$sale_id)); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('sales_unsuccessfully_updated'), 'id' => $sale_id)); } } - - private function _payments_cover_total() - { - // Changed the conditional to account for floating point rounding - - // "sale" amount due needs to be <=0 to state it's fine - if( ($this->sale_lib->get_mode() == 'sale') && $this->sale_lib->get_amount_due() > 1e-6 ) - { - return false; - } - // "return" amount due needs to be >=0 to state it's fine - if( ($this->sale_lib->get_mode() == 'return') && $this->sale_lib->get_amount_due() < -(1e-6) ) - { - return false; - } - - return true; - } - - private function _reload($data=array()) - { - $person_info = $this->Employee->get_logged_in_employee_info(); - $data['cart'] = $this->sale_lib->get_cart(); - $data['modes'] = array('sale'=>$this->lang->line('sales_sale'), 'return'=>$this->lang->line('sales_return')); - $data['mode'] = $this->sale_lib->get_mode(); - - $data['stock_locations'] = $this->Stock_location->get_allowed_locations('sales'); - $data['stock_location'] = $this->sale_lib->get_sale_location(); - - $data['subtotal'] = $this->sale_lib->get_subtotal(TRUE); - $data['tax_exclusive_subtotal'] = $this->sale_lib->get_subtotal(TRUE, TRUE); - $data['taxes'] = $this->sale_lib->get_taxes(); - $data['discount'] = $this->sale_lib->get_discount(); - $data['total'] = $this->sale_lib->get_total(); - $data['items_module_allowed'] = $this->Employee->has_grant('items', $person_info->person_id); - $data['comment'] = $this->sale_lib->get_comment(); - $data['email_receipt'] = $this->sale_lib->get_email_receipt(); - $data['payments_total'] = $this->sale_lib->get_payments_total(); - $data['amount_due'] = $this->sale_lib->get_amount_due(); - $data['payments'] = $this->sale_lib->get_payments(); - $data['payment_options'] = $this->Sale->get_payment_options(); - - $customer_id = $this->sale_lib->get_customer(); - $cust_info = $this->_load_customer_data($customer_id, $data, true); - - $data['invoice_number'] = $this->_substitute_invoice_number($cust_info); - $data['invoice_number_enabled'] = $this->sale_lib->is_invoice_number_enabled(); - $data['print_after_sale'] = $this->sale_lib->is_print_after_sale(); - $data['payments_cover_total'] = $this->_payments_cover_total(); - - $this->load->view("sales/register", $data); - } - - private function _load_customer_data($customer_id, &$data, $totals=false) - { - $cust_info = ''; - - if($customer_id != -1) - { - $cust_info = $this->Customer->get_info($customer_id); - if(isset($cust_info->company_name)) - { - $data['customer'] = $cust_info->company_name; - } - else - { - $data['customer'] = $cust_info->first_name . ' ' . $cust_info->last_name; - } - $data['first_name'] = $cust_info->first_name; - $data['last_name'] = $cust_info->last_name; - $data['customer_email'] = $cust_info->email; - $data['customer_address'] = $cust_info->address_1; - if(!empty($cust_info->zip) or !empty($cust_info->city)) - { - $data['customer_location'] = $cust_info->zip . ' ' . $cust_info->city; - } - else - { - $data['customer_location'] = ''; - } - $data['customer_account_number'] = $cust_info->account_number; - $data['customer_discount_percent'] = $cust_info->discount_percent; - if($totals) - { - $cust_totals = $this->Customer->get_totals($customer_id); - - $data['customer_total'] = $cust_totals->total; - } - $data['customer_info'] = implode("\n", array( - $data['customer'], - $data['customer_address'], - $data['customer_location'], - $data['customer_account_number'] - )); - } - - return $cust_info; - } - - function cancel() + public function cancel() { $this->sale_lib->clear_all(); $this->_reload(); } - - function suspend() + + public function suspend() { - $data['cart'] = $this->sale_lib->get_cart(); - $data['subtotal'] = $this->sale_lib->get_subtotal(); - $data['taxes'] = $this->sale_lib->get_taxes(); - $data['total'] = $this->sale_lib->get_total(); - $data['receipt_title'] = $this->lang->line('sales_receipt'); - $data['transaction_time'] = date($this->config->item('dateformat') . ' ' . $this->config->item('timeformat')); - $comment = $this->sale_lib->get_comment(); - $invoice_number = $this->sale_lib->get_invoice_number(); - - $data['payment_type'] = $this->input->post('payment_type'); - // Multiple payments - $data['payments'] = $this->sale_lib->get_payments(); - $data['amount_change'] = to_currency($this->sale_lib->get_amount_due() * -1); - + $cart = $this->sale_lib->get_cart(); + $payments = $this->sale_lib->get_payments(); $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - $emp_info = $this->Employee->get_info($employee_id); - $data['employee'] = $emp_info->first_name . ' ' . $emp_info->last_name; - $customer_id = $this->sale_lib->get_customer(); - $cust_info = $this->_load_customer_data($customer_id, $data); - - $is_set = $this->_is_custom_invoice_number($cust_info); - $invoice_number = $is_set ? $invoice_number : NULL; - - $total_payments = 0; - - foreach($data['payments'] as $payment) - { - $total_payments = bcadd($total_payments, $payment['payment_amount'], PRECISION); - } + $customer_info = $this->Customer->get_info($customer_id); + $invoice_number = $this->_is_custom_invoice_number($customer_info) ? $this->sale_lib->get_invoice_number() : NULL; + $comment = $this->sale_lib->get_comment(); //SAVE sale to database - $data['sale_id'] = 'POS ' . $this->Sale_suspended->save($data['cart'], $customer_id, $employee_id, $comment, $invoice_number, $data['payments']); - if ($data['sale_id'] == 'POS -1') + $data = array(); + if($this->Sale_suspended->save($cart, $customer_id, $employee_id, $comment, $invoice_number, $payments) == '-1') { - $data['error_message'] = $this->lang->line('sales_transaction_failed'); + $data['error'] = $this->lang->line('sales_unsuccessfully_suspended_sale'); + } + else + { + $data['success'] = $this->lang->line('sales_successfully_suspended_sale'); } $this->sale_lib->clear_all(); - $this->_reload(array('success' => $this->lang->line('sales_successfully_suspended_sale'))); + $this->_reload($data); } - function suspended() + public function suspended() { $data = array(); - $data['suspended_sales'] = $this->Sale_suspended->get_all()->result_array(); + $data['suspended_sales'] = $this->xss_clean($this->Sale_suspended->get_all()->result_array()); $this->load->view('sales/suspended', $data); } - function unsuspend() + public function unsuspend() { $sale_id = $this->input->post('suspended_sale_id'); + $this->sale_lib->clear_all(); $this->sale_lib->copy_entire_suspended_sale($sale_id); $this->Sale_suspended->delete($sale_id); @@ -839,11 +837,12 @@ class Sales extends Secure_area $this->_reload(); } - function check_invoice_number() + public function check_invoice_number() { $sale_id = $this->input->post('sale_id'); $invoice_number = $this->input->post('invoice_number'); - $exists = !empty($invoice_number) && $this->Sale->invoice_number_exists($invoice_number,$sale_id); + $exists = !empty($invoice_number) && $this->Sale->check_invoice_number_exists($invoice_number, $sale_id); + echo !$exists ? 'true' : 'false'; } } diff --git a/application/controllers/Secure_Controller.php b/application/controllers/Secure_Controller.php new file mode 100644 index 000000000..ad7f18e20 --- /dev/null +++ b/application/controllers/Secure_Controller.php @@ -0,0 +1,109 @@ +load->model('Employee'); + $model = $this->Employee; + + if(!$model->is_logged_in()) + { + redirect('login'); + } + + $this->track_page($module_id, $module_id); + + $logged_in_employee_info = $model->get_logged_in_employee_info(); + if(!$model->has_module_grant($module_id, $logged_in_employee_info->person_id) || + (isset($submodule_id) && !$model->has_module_grant($submodule_id, $logged_in_employee_info->person_id))) + { + redirect('no_access/' . $module_id . '/' . $submodule_id); + } + + // load up global data visible to all the loaded views + $data['allowed_modules'] = $this->Module->get_allowed_modules($logged_in_employee_info->person_id); + $data['user_info'] = $logged_in_employee_info; + $data['controller_name'] = $module_id; + + $this->load->vars($data); + } + + /* + * Internal method to do XSS clean in the derived classes + */ + protected function xss_clean($str, $is_image = FALSE) + { + // This setting is configurable in application/config/config.php. + // Users can disable the XSS clean for performance reasons + // (cases like intranet installation with no Internet access) + if($this->config->item('ospos_xss_clean') == FALSE) + { + return $str; + } + else + { + return $this->security->xss_clean($str, $is_image); + } + } + + protected function track_page($path, $page) + { + if(get_instance()->Appconfig->get('statistics')) + { + $this->load->library('tracking_lib'); + + if(empty($path)) + { + $path = 'home'; + $page = 'home'; + } + + $this->tracking_lib->track_page('controller/' . $path, $page); + } + } + + protected function track_event($category, $action, $label, $value = NULL) + { + if(get_instance()->Appconfig->get('statistics')) + { + $this->load->library('tracking_lib'); + + $this->tracking_lib->track_event($category, $action, $label, $value); + } + } + + public function numeric($str) + { + return parse_decimals($str); + } + + public function check_numeric() + { + $result = TRUE; + + foreach($this->input->get() as $str) + { + $result = parse_decimals($str); + } + + echo $result !== FALSE ? 'true' : 'false'; + } + + + // this is the basic set of methods most OSPOS Controllers will implement + public function index() { return FALSE; } + public function search() { return FALSE; } + public function suggest_search() { return FALSE; } + public function view($data_item_id = -1) { return FALSE; } + public function save($data_item_id = -1) { return FALSE; } + public function delete() { return FALSE; } + +} +?> \ No newline at end of file diff --git a/application/controllers/Secure_area.php b/application/controllers/Secure_area.php deleted file mode 100644 index 6484655f3..000000000 --- a/application/controllers/Secure_area.php +++ /dev/null @@ -1,65 +0,0 @@ -load->model('Employee'); - if(!$this->Employee->is_logged_in()) - { - redirect('login'); - } - $employee_id=$this->Employee->get_logged_in_employee_info()->person_id; - if(!$this->Employee->has_module_grant($module_id,$employee_id) || - (isset($submodule_id) && !$this->Employee->has_module_grant($submodule_id,$employee_id))) - { - redirect('no_access/'.$module_id.'/'.$submodule_id); - } - - //load up global data - $logged_in_employee_info=$this->Employee->get_logged_in_employee_info(); - $data['allowed_modules']=$this->Module->get_allowed_modules($logged_in_employee_info->person_id); - $data['backup_allowed']=false; - foreach($data['allowed_modules']->result_array() as $module) - { - $data['backup_allowed']|=$module['module_id']==='config'; - } - $data['user_info']=$logged_in_employee_info; - $data['controller_name']=$module_id; - $this->controller_name=$module_id; - $this->load->vars($data); - } - - function get_controller_name() - { - return strtolower($this->controller_name); - } - - function _initialize_pagination($object, $lines_per_page, $limit_from = 0, $total_rows = -1, $function='index', $filter='') - { - $this->load->library('pagination'); - - $config['base_url'] = site_url($this->get_controller_name() . "/$function/" . $filter); - $config['total_rows'] = $total_rows > -1 ? $total_rows : call_user_func(array($object, 'get_total_rows')); - $config['per_page'] = $lines_per_page; - $config['num_links'] = 2; - $config['last_link'] = $this->lang->line('common_last_page'); - $config['first_link'] = $this->lang->line('common_first_page'); - // page is calculated here instead of in pagination lib - $config['cur_page'] = $limit_from > 0 ? $limit_from : 0; - $config['page_query_string'] = FALSE; - $config['uri_segment'] = 0; - - $this->pagination->initialize($config); - - return $this->pagination->create_links(); - } - -} -?> \ No newline at end of file diff --git a/application/controllers/Suppliers.php b/application/controllers/Suppliers.php index 1417e7e21..8bc80d880 100644 --- a/application/controllers/Suppliers.php +++ b/application/controllers/Suppliers.php @@ -1,125 +1,153 @@ -get_controller_name(); - $data['table_headers'] = get_suppliers_manage_table_headers(); + $data['table_headers'] = $this->xss_clean(get_suppliers_manage_table_headers()); $this->load->view('people/manage', $data); } + /* + Gets one row for a supplier manage table. This is called using AJAX to update one row. + */ + public function get_row($row_id) + { + $data_row = $this->xss_clean(get_supplier_data_row($this->Supplier->get_info($row_id), $this)); + + echo json_encode($data_row); + } + /* Returns Supplier table data rows. This will be called with AJAX. */ - function search() + public function search() { $search = $this->input->get('search'); - $limit = $this->input->get('limit'); + $limit = $this->input->get('limit'); $offset = $this->input->get('offset'); - $sort = $this->input->get('sort'); - $order = $this->input->get('order'); + $sort = $this->input->get('sort'); + $order = $this->input->get('order'); $suppliers = $this->Supplier->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Supplier->get_found_rows($search); + $data_rows = array(); foreach($suppliers->result() as $supplier) { $data_rows[] = get_supplier_data_row($supplier, $this); } + + $data_rows = $this->xss_clean($data_rows); + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } /* Gives search suggestions based on what is being searched for */ - function suggest() + public function suggest() { - $suggestions = $this->Supplier->get_search_suggestions($this->input->get('term'), TRUE); + $suggestions = $this->xss_clean($this->Supplier->get_search_suggestions($this->input->get('term'), TRUE)); + echo json_encode($suggestions); } - function suggest_search() + public function suggest_search() { - $suggestions = $this->Supplier->get_search_suggestions($this->input->post('term'), FALSE); + $suggestions = $this->xss_clean($this->Supplier->get_search_suggestions($this->input->post('term'), FALSE)); + echo json_encode($suggestions); } /* Loads the supplier edit form */ - function view($supplier_id=-1) + public function view($supplier_id = -1) { - $data['person_info']=$this->Supplier->get_info($supplier_id); - $this->load->view("suppliers/form",$data); + $info = $this->Supplier->get_info($supplier_id); + foreach(get_object_vars($info) as $property => $value) + { + $info->$property = $this->xss_clean($value); + } + $data['person_info'] = $info; + + $this->load->view("suppliers/form", $data); } /* Inserts/updates a supplier */ - function save($supplier_id=-1) + public function save($supplier_id = -1) { $person_data = array( - 'first_name'=>$this->input->post('first_name'), - 'last_name'=>$this->input->post('last_name'), - 'gender'=>$this->input->post('gender'), - 'email'=>$this->input->post('email'), - 'phone_number'=>$this->input->post('phone_number'), - 'address_1'=>$this->input->post('address_1'), - 'address_2'=>$this->input->post('address_2'), - 'city'=>$this->input->post('city'), - 'state'=>$this->input->post('state'), - 'zip'=>$this->input->post('zip'), - 'country'=>$this->input->post('country'), - 'comments'=>$this->input->post('comments') + 'first_name' => $this->input->post('first_name'), + 'last_name' => $this->input->post('last_name'), + 'gender' => $this->input->post('gender'), + 'email' => $this->input->post('email'), + 'phone_number' => $this->input->post('phone_number'), + 'address_1' => $this->input->post('address_1'), + 'address_2' => $this->input->post('address_2'), + 'city' => $this->input->post('city'), + 'state' => $this->input->post('state'), + 'zip' => $this->input->post('zip'), + 'country' => $this->input->post('country'), + 'comments' => $this->input->post('comments') ); - $supplier_data=array( - 'company_name'=>$this->input->post('company_name'), - 'agency_name'=>$this->input->post('agency_name'), - 'account_number'=>$this->input->post('account_number') == '' ? null : $this->input->post('account_number') + $supplier_data = array( + 'company_name' => $this->input->post('company_name'), + 'agency_name' => $this->input->post('agency_name'), + 'account_number' => $this->input->post('account_number') == '' ? NULL : $this->input->post('account_number') ); - if($this->Supplier->save_supplier($person_data,$supplier_data,$supplier_id)) + + if($this->Supplier->save_supplier($person_data, $supplier_data, $supplier_id)) { + $supplier_data = $this->xss_clean($supplier_data); + //New supplier - if($supplier_id==-1) + if($supplier_id == -1) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_adding').' '. - $supplier_data['company_name'],'id'=>$supplier_data['person_id'])); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('suppliers_successful_adding').' '. + $supplier_data['company_name'], 'id' => $supplier_data['person_id'])); } - else //previous supplier + else //Existing supplier { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_updating').' '. - $supplier_data['company_name'],'id'=>$supplier_id)); + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('suppliers_successful_updating').' '. + $supplier_data['company_name'], 'id' => $supplier_id)); } } else//failure - { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('suppliers_error_adding_updating').' '. - $supplier_data['company_name'],'id'=>-1)); + { + $supplier_data = $this->xss_clean($supplier_data); + + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('suppliers_error_adding_updating').' '. + $supplier_data['company_name'], 'id' => -1)); } } /* This deletes suppliers from the suppliers table */ - function delete() + public function delete() { - $suppliers_to_delete=$this->input->post('ids'); - + $suppliers_to_delete = $this->xss_clean($this->input->post('ids')); + if($this->Supplier->delete_list($suppliers_to_delete)) { - echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_deleted').' '. - count($suppliers_to_delete).' '.$this->lang->line('suppliers_one_or_multiple'))); + echo json_encode(array('success' => TRUE,'message' => $this->lang->line('suppliers_successful_deleted').' '. + count($suppliers_to_delete).' '.$this->lang->line('suppliers_one_or_multiple'))); } else { - echo json_encode(array('success'=>false,'message'=>$this->lang->line('suppliers_cannot_be_deleted'))); + echo json_encode(array('success' => FALSE,'message' => $this->lang->line('suppliers_cannot_be_deleted'))); } } diff --git a/application/controllers/interfaces/Idata_controller.php b/application/controllers/interfaces/Idata_controller.php deleted file mode 100644 index c366cc498..000000000 --- a/application/controllers/interfaces/Idata_controller.php +++ /dev/null @@ -1,14 +0,0 @@ - \ No newline at end of file diff --git a/application/core/MY_Lang.php b/application/core/MY_Lang.php index 0a44797f7..26e8c0907 100644 --- a/application/core/MY_Lang.php +++ b/application/core/MY_Lang.php @@ -19,7 +19,7 @@ class MY_Lang extends CI_Lang foreach($loaded as $file) { - $this->load( str_replace( '_lang.php', '', $file ) ); + $this->load(strtr($file, '', '_lang.php')); } } } @@ -65,7 +65,7 @@ class MY_Lang extends CI_Lang foreach ($args as $arg) { $line = preg_replace('/\%'.$i.'/', $arg, $line); - $i++; + ++$i; } } } diff --git a/application/core/MY_Loader.php b/application/core/MY_Loader.php deleted file mode 100644 index b05fac5ea..000000000 --- a/application/core/MY_Loader.php +++ /dev/null @@ -1,24 +0,0 @@ -_ci_view_paths = array_merge(array('templates/' . $config['theme_name'] . '/views' . DIRECTORY_SEPARATOR => 1), $this->_ci_view_paths); - } - - return $this->_ci_load(array('_ci_view'=>$view, '_ci_vars'=>$this->_ci_object_to_array($vars), '_ci_return'=>$return)); - } -} \ No newline at end of file diff --git a/application/helpers/dompdf/README.md b/application/helpers/dompdf/README.md deleted file mode 100755 index 68e4af5d6..000000000 --- a/application/helpers/dompdf/README.md +++ /dev/null @@ -1,131 +0,0 @@ -**dompdf is an HTML to PDF converter**. -At its heart, dompdf is (mostly) [CSS 2.1](http://www.w3.org/TR/CSS2/) compliant -HTML layout and rendering engine written in PHP. It is a style-driven renderer: -it will download and read external stylesheets, inline style tags, and the style -attributes of individual HTML elements. It also supports most presentational -HTML attributes. - ----- - -**Check out the [Demo](http://pxd.me/dompdf/www/examples.php) and ask any -question on [StackOverflow](http://stackoverflow.com/questions/tagged/dompdf) or -on the [Google Groups](http://groups.google.com/group/dompdf)** - ----- - -[![Follow us on Twitter](http://twitter-badges.s3.amazonaws.com/twitter-a.png)](http://www.twitter.com/dompdf) -[![Follow us on Google+](https://ssl.gstatic.com/images/icons/gplus-32.png)](https://plus.google.com/108710008521858993320?prsrc=3) - -Features -======== - * handles most CSS 2.1 and a few CSS3 properties, including @import, @media & - @page rules - * supports most presentational HTML 4.0 attributes - * supports external stylesheets, either local or through http/ftp (via - fopen-wrappers) - * supports complex tables, including row & column spans, separate & collapsed - border models, individual cell styling - * image support (gif, png (8, 24 and 32 bit with alpha channel), bmp & jpeg) - * no dependencies on external PDF libraries, thanks to the R&OS PDF class - * inline PHP support - -Requirements -============ - * PHP 5.0+ (5.3+ recommended) - * DOM extension - * GD extension - -Recommendations -============ - * MBString extension: provides internationalization support. This extension is - *not* enabled by default. dompdf has limited internationalization support - when this extension is not enabled. - * opcache (OPcache, XCache, APC, etc.): improves performance - -About Fonts & Character Encoding -============ -PDF documents internally support the following fonts: Helvetica, Times-Roman, -Courier, Zapf-Dingbats, & Symbol. These fonts only support Windows ANSI -encoding. In order for a PDF to display characters that are not available in -Windows ANSI you must supply an external font. dompdf will embed any referenced -font in the PDF so long as it has been pre-loaded or is accessible to dompdf and -reference in CSS @font-face rules. See the -[font overview](https://github.com/dompdf/dompdf/wiki/About-Fonts-and-Character-Encoding) -for more information on how to use fonts. - -The [DejaVu TrueType fonts](http://dejavu-fonts.org) have been pre-installed to -give dompdf decent Unicode character coverage by default. To use the DejaVu -fonts reference the font in your stylesheet, e.g. `body { font-family: Deja Vu -Sans; }` (for DejaVu Sans). - -Easy Installation -============ -Install with git ---- -From the command line switch to the directory where dompdf will reside and run -the following commands: - -```sh -git clone https://github.com/dompdf/dompdf.git -git submodule init -git submodule update -``` - -Install with composer ---- -To install with Composer, simply add the requirement to your `composer.json` -file: - -```json -{ - "require" : { - "dompdf/dompdf" : "0.6.*" - } -} -``` - -And run Composer to update your dependencies: - -```bash -$ curl -sS http://getcomposer.org/installer | php -$ php composer.phar update -``` - -Before you can use the Composer installation of DOMPDF in your application you -must disable dompdf's default auto-loader, include the Composer autoloader, and -load the dompdf configuration file: - -```php -// somewhere early in your project's loading, require the Composer autoloader -// see: http://getcomposer.org/doc/00-intro.md -require 'vendor/autoload.php'; - -// disable DOMPDF's internal autoloader if you are using Composer -define('DOMPDF_ENABLE_AUTOLOAD', false); - -// include DOMPDF's default configuration -require_once '/path/to/vendor/dompdf/dompdf/dompdf_config.inc.php'; -``` - -Download and install ---- -Download an archive of dompdf and extract it into the directory where dompdf -will reside - * You can download stable copies of dompdf from - https://github.com/dompdf/dompdf/tags - * Or download a nightly (the latest, unreleased code) from - http://eclecticgeek.com/dompdf - -Limitations (Known Issues) -========================== - * not particularly tolerant to poorly-formed HTML input. To avoid any - unexpected rendering issues you should either enable the built-in HTML5 - parser (via the `DOMPDF_ENABLE_HTML5PARSER` configuration constant) or run - your HTML through a HTML validator/cleaner (such as Tidy). - * large files or large tables can take a while to render - * CSS float is not supported (but is in the works, enable it through the - `DOMPDF_ENABLE_CSS_FLOAT` configuration constant). - * If you find this project useful, please consider making a donation. - -(Any funds donated will be used to help further development on this project.) -[![Donate button](https://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](http://goo.gl/DSvWf) diff --git a/application/helpers/dompdf/composer.json b/application/helpers/dompdf/composer.json deleted file mode 100755 index 565a394d0..000000000 --- a/application/helpers/dompdf/composer.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "dompdf/dompdf", - "type": "library", - "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", - "homepage": "https://github.com/dompdf/dompdf", - "license": "LGPL", - "authors": [ - { - "name": "Fabien Ménager", - "email": "fabien.menager@gmail.com" - }, - { - "name": "Brian Sweeney", - "email": "eclecticgeek@gmail.com" - } - ], - "autoload": { - "classmap": ["include/"] - }, - "require": { - "phenx/php-font-lib": "0.2.*" - } -} diff --git a/application/helpers/dompdf/dompdf.php b/application/helpers/dompdf/dompdf.php deleted file mode 100755 index a9052fa46..000000000 --- a/application/helpers/dompdf/dompdf.php +++ /dev/null @@ -1,289 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Display command line usage - */ -function dompdf_usage() { - $default_paper_size = DOMPDF_DEFAULT_PAPER_SIZE; - - echo <<load_html($str); - -} else - $dompdf->load_html_file($file); - -if ( isset($base_path) ) { - $dompdf->set_base_path($base_path); -} - -$dompdf->set_paper($paper, $orientation); - -$dompdf->render(); - -if ( $_dompdf_show_warnings ) { - global $_dompdf_warnings; - foreach ($_dompdf_warnings as $msg) - echo $msg . "\n"; - echo $dompdf->get_canvas()->get_cpdf()->messages; - flush(); -} - -if ( $save_file ) { -// if ( !is_writable($outfile) ) -// throw new DOMPDF_Exception("'$outfile' is not writable."); - if ( strtolower(DOMPDF_PDF_BACKEND) === "gd" ) - $outfile = str_replace(".pdf", ".png", $outfile); - - list($proto, $host, $path, $file) = explode_url($outfile); - if ( $proto != "" ) // i.e. not file:// - $outfile = $file; // just save it locally, FIXME? could save it like wget: ./host/basepath/file - - $outfile = realpath(dirname($outfile)) . DIRECTORY_SEPARATOR . basename($outfile); - - if ( strpos($outfile, DOMPDF_CHROOT) !== 0 ) - throw new DOMPDF_Exception("Permission denied."); - - file_put_contents($outfile, $dompdf->output( array("compress" => 0) )); - exit(0); -} - -if ( !headers_sent() ) { - $dompdf->stream($outfile, $options); -} diff --git a/application/helpers/dompdf/dompdf_config.custom.inc.php b/application/helpers/dompdf/dompdf_config.custom.inc.php deleted file mode 100755 index 4e58b4a92..000000000 --- a/application/helpers/dompdf/dompdf_config.custom.inc.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @autho Brian Sweeney - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -if ( class_exists( 'DOMPDF' , false ) ) { return; } - -PHP_VERSION >= 5.0 or die("DOMPDF requires PHP 5.0+"); - -/** - * The root of your DOMPDF installation - */ -define("DOMPDF_DIR", str_replace(DIRECTORY_SEPARATOR, '/', realpath(dirname(__FILE__)))); - -/** - * The location of the DOMPDF include directory - */ -define("DOMPDF_INC_DIR", DOMPDF_DIR . "/include"); - -/** - * The location of the DOMPDF lib directory - */ -define("DOMPDF_LIB_DIR", DOMPDF_DIR . "/lib"); - -/** - * Some installations don't have $_SERVER['DOCUMENT_ROOT'] - * http://fyneworks.blogspot.com/2007/08/php-documentroot-in-iis-windows-servers.html - */ -if( !isset($_SERVER['DOCUMENT_ROOT']) ) { - $path = ""; - - if ( isset($_SERVER['SCRIPT_FILENAME']) ) - $path = $_SERVER['SCRIPT_FILENAME']; - elseif ( isset($_SERVER['PATH_TRANSLATED']) ) - $path = str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']); - - $_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr($path, 0, 0-strlen($_SERVER['PHP_SELF']))); -} - -/** Include the custom config file if it exists */ -if ( file_exists(DOMPDF_DIR . "/dompdf_config.custom.inc.php") ){ - require_once(DOMPDF_DIR . "/dompdf_config.custom.inc.php"); -} - -//FIXME: Some function definitions rely on the constants defined by DOMPDF. However, might this location prove problematic? -require_once(DOMPDF_INC_DIR . "/functions.inc.php"); - -/** - * Username and password used by the configuration utility in www/ - */ -def("DOMPDF_ADMIN_USERNAME", "user"); -def("DOMPDF_ADMIN_PASSWORD", "password"); - -/** - * The location of the DOMPDF font directory - * - * The location of the directory where DOMPDF will store fonts and font metrics - * Note: This directory must exist and be writable by the webserver process. - * *Please note the trailing slash.* - * - * Notes regarding fonts: - * Additional .afm font metrics can be added by executing load_font.php from command line. - * - * Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must - * be embedded in the pdf file or the PDF may not display correctly. This can significantly - * increase file size unless font subsetting is enabled. Before embedding a font please - * review your rights under the font license. - * - * Any font specification in the source HTML is translated to the closest font available - * in the font directory. - * - * The pdf standard "Base 14 fonts" are: - * Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique, - * Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique, - * Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic, - * Symbol, ZapfDingbats. - */ -def("DOMPDF_FONT_DIR", DOMPDF_DIR . "/lib/fonts/"); - -/** - * The location of the DOMPDF font cache directory - * - * This directory contains the cached font metrics for the fonts used by DOMPDF. - * This directory can be the same as DOMPDF_FONT_DIR - * - * Note: This directory must exist and be writable by the webserver process. - */ -def("DOMPDF_FONT_CACHE", DOMPDF_FONT_DIR); - -/** - * The location of a temporary directory. - * - * The directory specified must be writeable by the webserver process. - * The temporary directory is required to download remote images and when - * using the PFDLib back end. - */ -def("DOMPDF_TEMP_DIR", sys_get_temp_dir()); - -/** - * ==== IMPORTANT ==== - * - * dompdf's "chroot": Prevents dompdf from accessing system files or other - * files on the webserver. All local files opened by dompdf must be in a - * subdirectory of this directory. DO NOT set it to '/' since this could - * allow an attacker to use dompdf to read any files on the server. This - * should be an absolute path. - * This is only checked on command line call by dompdf.php, but not by - * direct class use like: - * $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output(); - */ -def("DOMPDF_CHROOT", realpath(DOMPDF_DIR)); - -/** - * Whether to use Unicode fonts or not. - * - * When set to true the PDF backend must be set to "CPDF" and fonts must be - * loaded via load_font.php. - * - * When enabled, dompdf can support all Unicode glyphs. Any glyphs used in a - * document must be present in your fonts, however. - */ -def("DOMPDF_UNICODE_ENABLED", true); - -/** - * Whether to enable font subsetting or not. - */ -def("DOMPDF_ENABLE_FONTSUBSETTING", true); - -/** - * The PDF rendering backend to use - * - * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and - * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will - * fall back on CPDF. 'GD' renders PDFs to graphic files. {@link - * Canvas_Factory} ultimately determines which rendering class to instantiate - * based on this setting. - * - * Both PDFLib & CPDF rendering backends provide sufficient rendering - * capabilities for dompdf, however additional features (e.g. object, - * image and font support, etc.) differ between backends. Please see - * {@link PDFLib_Adapter} for more information on the PDFLib backend - * and {@link CPDF_Adapter} and lib/class.pdf.php for more information - * on CPDF. Also see the documentation for each backend at the links - * below. - * - * The GD rendering backend is a little different than PDFLib and - * CPDF. Several features of CPDF and PDFLib are not supported or do - * not make any sense when creating image files. For example, - * multiple pages are not supported, nor are PDF 'objects'. Have a - * look at {@link GD_Adapter} for more information. GD support is - * experimental, so use it at your own risk. - * - * @link http://www.pdflib.com - * @link http://www.ros.co.nz/pdf - * @link http://www.php.net/image - */ -def("DOMPDF_PDF_BACKEND", "CPDF"); - -/** - * PDFlib license key - * - * If you are using a licensed, commercial version of PDFlib, specify - * your license key here. If you are using PDFlib-Lite or are evaluating - * the commercial version of PDFlib, comment out this setting. - * - * @link http://www.pdflib.com - * - * If pdflib present in web server and auto or selected explicitely above, - * a real license code must exist! - */ -//def("DOMPDF_PDFLIB_LICENSE", "your license key here"); - -/** - * html target media view which should be rendered into pdf. - * List of types and parsing rules for future extensions: - * http://www.w3.org/TR/REC-html40/types.html - * screen, tty, tv, projection, handheld, print, braille, aural, all - * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3. - * Note, even though the generated pdf file is intended for print output, - * the desired content might be different (e.g. screen or projection view of html file). - * Therefore allow specification of content here. - */ -def("DOMPDF_DEFAULT_MEDIA_TYPE", "screen"); - -/** - * The default paper size. - * - * North America standard is "letter"; other countries generally "a4" - * - * @see CPDF_Adapter::PAPER_SIZES for valid sizes - */ -def("DOMPDF_DEFAULT_PAPER_SIZE", "letter"); - -/** - * The default font family - * - * Used if no suitable fonts can be found. This must exist in the font folder. - * @var string - */ -def("DOMPDF_DEFAULT_FONT", "Helvetica"); - -/** - * Image DPI setting - * - * This setting determines the default DPI setting for images and fonts. The - * DPI may be overridden for inline images by explictly setting the - * image's width & height style attributes (i.e. if the image's native - * width is 600 pixels and you specify the image's width as 72 points, - * the image will have a DPI of 600 in the rendered PDF. The DPI of - * background images can not be overridden and is controlled entirely - * via this parameter. - * - * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI). - * If a size in html is given as px (or without unit as image size), - * this tells the corresponding size in pt at 72 DPI. - * This adjusts the relative sizes to be similar to the rendering of the - * html page in a reference browser. - * - * In pdf, always 1 pt = 1/72 inch - * - * Rendering resolution of various browsers in px per inch: - * Windows Firefox and Internet Explorer: - * SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:? - * Linux Firefox: - * about:config *resolution: Default:96 - * (xorg screen dimension in mm and Desktop font dpi settings are ignored) - * - * Take care about extra font/image zoom factor of browser. - * - * In images, size in pixel attribute, img css style, are overriding - * the real image dimension in px for rendering. - * - * @var int - */ -def("DOMPDF_DPI", 96); - -/** - * Enable inline PHP - * - * If this setting is set to true then DOMPDF will automatically evaluate - * inline PHP contained within tags. - * - * Enabling this for documents you do not trust (e.g. arbitrary remote html - * pages) is a security risk. Set this option to false if you wish to process - * untrusted documents. - * - * @var bool - */ -def("DOMPDF_ENABLE_PHP", false); - -/** - * Enable inline Javascript - * - * If this setting is set to true then DOMPDF will automatically insert - * JavaScript code contained within tags. - * - * @var bool - */ -def("DOMPDF_ENABLE_JAVASCRIPT", true); - -/** - * Enable remote file access - * - * If this setting is set to true, DOMPDF will access remote sites for - * images and CSS files as required. - * This is required for part of test case www/test/image_variants.html through www/examples.php - * - * Attention! - * This can be a security risk, in particular in combination with DOMPDF_ENABLE_PHP and - * allowing remote access to dompdf.php or on allowing remote html code to be passed to - * $dompdf = new DOMPDF(); $dompdf->load_html(...); - * This allows anonymous users to download legally doubtful internet content which on - * tracing back appears to being downloaded by your server, or allows malicious php code - * in remote html pages to be executed by your server with your account privileges. - * - * @var bool - */ -def("DOMPDF_ENABLE_REMOTE", false); - -/** - * The debug output log - * @var string - */ -def("DOMPDF_LOG_OUTPUT_FILE", DOMPDF_FONT_DIR."log.htm"); - -/** - * A ratio applied to the fonts height to be more like browsers' line height - */ -def("DOMPDF_FONT_HEIGHT_RATIO", 1.1); - -/** - * Enable CSS float - * - * Allows people to disabled CSS float support - * @var bool - */ -def("DOMPDF_ENABLE_CSS_FLOAT", true); - -/** - * Enable the built in DOMPDF autoloader - * - * @var bool - */ -def("DOMPDF_ENABLE_AUTOLOAD", true); - -/** - * Prepend the DOMPDF autoload function to the spl_autoload stack - * - * @var bool - */ -def("DOMPDF_AUTOLOAD_PREPEND", false); - -/** - * Use the more-than-experimental HTML5 Lib parser - */ -def("DOMPDF_ENABLE_HTML5PARSER", false); -require_once(DOMPDF_LIB_DIR . "/html5lib/Parser.php"); - -// ### End of user-configurable options ### - -/** - * Load autoloader - */ -if (DOMPDF_ENABLE_AUTOLOAD) { - require_once(DOMPDF_INC_DIR . "/autoload.inc.php"); - require_once(DOMPDF_LIB_DIR . "/php-font-lib/classes/Font.php"); -} - -/** - * Ensure that PHP is working with text internally using UTF8 character encoding. - */ -mb_internal_encoding('UTF-8'); - -/** - * Global array of warnings generated by DomDocument parser and - * stylesheet class - * - * @var array - */ -global $_dompdf_warnings; -$_dompdf_warnings = array(); - -/** - * If true, $_dompdf_warnings is dumped on script termination when using - * dompdf/dompdf.php or after rendering when using the DOMPDF class. - * When using the class, setting this value to true will prevent you from - * streaming the PDF. - * - * @var bool - */ -global $_dompdf_show_warnings; -$_dompdf_show_warnings = false; - -/** - * If true, the entire tree is dumped to stdout in dompdf.cls.php. - * Setting this value to true will prevent you from streaming the PDF. - * - * @var bool - */ -global $_dompdf_debug; -$_dompdf_debug = false; - -/** - * Array of enabled debug message types - * - * @var array - */ -global $_DOMPDF_DEBUG_TYPES; -$_DOMPDF_DEBUG_TYPES = array(); //array("page-break" => 1); - -/* Optionally enable different classes of debug output before the pdf content. - * Visible if displaying pdf as text, - * E.g. on repeated display of same pdf in browser when pdf is not taken out of - * the browser cache and the premature output prevents setting of the mime type. - */ -def('DEBUGPNG', false); -def('DEBUGKEEPTEMP', false); -def('DEBUGCSS', false); - -/* Layout debugging. Will display rectangles around different block levels. - * Visible in the PDF itself. - */ -def('DEBUG_LAYOUT', false); -def('DEBUG_LAYOUT_LINES', false); -def('DEBUG_LAYOUT_BLOCKS', false); -def('DEBUG_LAYOUT_INLINE', false); -def('DEBUG_LAYOUT_PADDINGBOX', false); diff --git a/application/helpers/dompdf/include/absolute_positioner.cls.php b/application/helpers/dompdf/include/absolute_positioner.cls.php deleted file mode 100755 index 050db49f7..000000000 --- a/application/helpers/dompdf/include/absolute_positioner.cls.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Positions absolutely positioned frames - */ -class Absolute_Positioner extends Positioner { - - function __construct(Frame_Decorator $frame) { parent::__construct($frame); } - - function position() { - - $frame = $this->_frame; - $style = $frame->get_style(); - - $p = $frame->find_positionned_parent(); - - list($x, $y, $w, $h) = $frame->get_containing_block(); - - $top = $style->length_in_pt($style->top, $h); - $right = $style->length_in_pt($style->right, $w); - $bottom = $style->length_in_pt($style->bottom, $h); - $left = $style->length_in_pt($style->left, $w); - - if ( $p && !($left === "auto" && $right === "auto") ) { - // Get the parent's padding box (see http://www.w3.org/TR/CSS21/visuren.html#propdef-top) - list($x, $y, $w, $h) = $p->get_padding_box(); - } - - list($width, $height) = array($frame->get_margin_width(), $frame->get_margin_height()); - - $orig_style = $this->_frame->get_original_style(); - $orig_width = $orig_style->width; - $orig_height = $orig_style->height; - - /**************************** - - Width auto: - ____________| left=auto | left=fixed | - right=auto | A | B | - right=fixed | C | D | - - Width fixed: - ____________| left=auto | left=fixed | - right=auto | E | F | - right=fixed | G | H | - - *****************************/ - - if ( $left === "auto" ) { - if ( $right === "auto" ) { - // A or E - Keep the frame at the same position - $x = $x + $frame->find_block_parent()->get_current_line_box()->w; - } - else { - if ( $orig_width === "auto" ) { - // C - $x += $w - $width - $right; - } - else { - // G - $x += $w - $width - $right; - } - } - } - else { - if ( $right === "auto" ) { - // B or F - $x += $left; - } - else { - if ( $orig_width === "auto" ) { - // D - TODO change width - $x += $left; - } - else { - // H - Everything is fixed: left + width win - $x += $left; - } - } - } - - // The same vertically - if ( $top === "auto" ) { - if ( $bottom === "auto" ) { - // A or E - Keep the frame at the same position - $y = $frame->find_block_parent()->get_current_line_box()->y; - } - else { - if ( $orig_height === "auto" ) { - // C - $y += $h - $height - $bottom; - } - else { - // G - $y += $h - $height - $bottom; - } - } - } - else { - if ( $bottom === "auto" ) { - // B or F - $y += $top; - } - else { - if ( $orig_height === "auto" ) { - // D - TODO change height - $y += $top; - } - else { - // H - Everything is fixed: top + height win - $y += $top; - } - } - } - - $frame->set_position($x, $y); - - } -} \ No newline at end of file diff --git a/application/helpers/dompdf/include/abstract_renderer.cls.php b/application/helpers/dompdf/include/abstract_renderer.cls.php deleted file mode 100755 index fc27aec10..000000000 --- a/application/helpers/dompdf/include/abstract_renderer.cls.php +++ /dev/null @@ -1,759 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Base renderer class - * - * @access private - * @package dompdf - */ -abstract class Abstract_Renderer { - - /** - * Rendering backend - * - * @var Canvas - */ - protected $_canvas; - - /** - * Current dompdf instance - * - * @var DOMPDF - */ - protected $_dompdf; - - /** - * Class constructor - * - * @param DOMPDF $dompdf The current dompdf instance - */ - function __construct(DOMPDF $dompdf) { - $this->_dompdf = $dompdf; - $this->_canvas = $dompdf->get_canvas(); - } - - /** - * Render a frame. - * - * Specialized in child classes - * - * @param Frame $frame The frame to render - */ - abstract function render(Frame $frame); - - //........................................................................ - - /** - * Render a background image over a rectangular area - * - * @param string $url The background image to load - * @param float $x The left edge of the rectangular area - * @param float $y The top edge of the rectangular area - * @param float $width The width of the rectangular area - * @param float $height The height of the rectangular area - * @param Style $style The associated Style object - * - * @throws Exception - */ - protected function _background_image($url, $x, $y, $width, $height, $style) { - if ( !function_exists("imagecreatetruecolor") ) { - throw new Exception("The PHP GD extension is required, but is not installed."); - } - - $sheet = $style->get_stylesheet(); - - // Skip degenerate cases - if ( $width == 0 || $height == 0 ) { - return; - } - - $box_width = $width; - $box_height = $height; - - //debugpng - if (DEBUGPNG) print '[_background_image '.$url.']'; - - list($img, $type, /*$msg*/) = Image_Cache::resolve_url( - $url, - $sheet->get_protocol(), - $sheet->get_host(), - $sheet->get_base_path(), - $this->_dompdf - ); - - // Bail if the image is no good - if ( Image_Cache::is_broken($img) ) { - return; - } - - //Try to optimize away reading and composing of same background multiple times - //Postponing read with imagecreatefrom ...() - //final composition parameters and name not known yet - //Therefore read dimension directly from file, instead of creating gd object first. - //$img_w = imagesx($src); $img_h = imagesy($src); - - list($img_w, $img_h) = dompdf_getimagesize($img); - if (!isset($img_w) || $img_w == 0 || !isset($img_h) || $img_h == 0) { - return; - } - - $repeat = $style->background_repeat; - $dpi = $this->_dompdf->get_option("dpi"); - - //Increase background resolution and dependent box size according to image resolution to be placed in - //Then image can be copied in without resize - $bg_width = round((float)($width * $dpi) / 72); - $bg_height = round((float)($height * $dpi) / 72); - - //Need %bg_x, $bg_y as background pos, where img starts, converted to pixel - - list($bg_x, $bg_y) = $style->background_position; - - if ( is_percent($bg_x) ) { - // The point $bg_x % from the left edge of the image is placed - // $bg_x % from the left edge of the background rectangle - $p = ((float)$bg_x)/100.0; - $x1 = $p * $img_w; - $x2 = $p * $bg_width; - - $bg_x = $x2 - $x1; - } - else { - $bg_x = (float)($style->length_in_pt($bg_x)*$dpi) / 72; - } - - $bg_x = round($bg_x + $style->length_in_pt($style->border_left_width)*$dpi / 72); - - if ( is_percent($bg_y) ) { - // The point $bg_y % from the left edge of the image is placed - // $bg_y % from the left edge of the background rectangle - $p = ((float)$bg_y)/100.0; - $y1 = $p * $img_h; - $y2 = $p * $bg_height; - - $bg_y = $y2 - $y1; - } - else { - $bg_y = (float)($style->length_in_pt($bg_y)*$dpi) / 72; - } - - $bg_y = round($bg_y + $style->length_in_pt($style->border_top_width)*$dpi / 72); - - //clip background to the image area on partial repeat. Nothing to do if img off area - //On repeat, normalize start position to the tile at immediate left/top or 0/0 of area - //On no repeat with positive offset: move size/start to have offset==0 - //Handle x/y Dimensions separately - - if ( $repeat !== "repeat" && $repeat !== "repeat-x" ) { - //No repeat x - if ($bg_x < 0) { - $bg_width = $img_w + $bg_x; - } - else { - $x += ($bg_x * 72)/$dpi; - $bg_width = $bg_width - $bg_x; - if ($bg_width > $img_w) { - $bg_width = $img_w; - } - $bg_x = 0; - } - - if ($bg_width <= 0) { - return; - } - - $width = (float)($bg_width * 72)/$dpi; - } - else { - //repeat x - if ($bg_x < 0) { - $bg_x = - ((-$bg_x) % $img_w); - } - else { - $bg_x = $bg_x % $img_w; - if ($bg_x > 0) { - $bg_x -= $img_w; - } - } - } - - if ( $repeat !== "repeat" && $repeat !== "repeat-y" ) { - //no repeat y - if ($bg_y < 0) { - $bg_height = $img_h + $bg_y; - } - else { - $y += ($bg_y * 72)/$dpi; - $bg_height = $bg_height - $bg_y; - if ($bg_height > $img_h) { - $bg_height = $img_h; - } - $bg_y = 0; - } - if ($bg_height <= 0) { - return; - } - $height = (float)($bg_height * 72)/$dpi; - } - else { - //repeat y - if ($bg_y < 0) { - $bg_y = - ((-$bg_y) % $img_h); - } - else { - $bg_y = $bg_y % $img_h; - if ($bg_y > 0) { - $bg_y -= $img_h; - } - } - } - - //Optimization, if repeat has no effect - if ( $repeat === "repeat" && $bg_y <= 0 && $img_h+$bg_y >= $bg_height ) { - $repeat = "repeat-x"; - } - - if ( $repeat === "repeat" && $bg_x <= 0 && $img_w+$bg_x >= $bg_width ) { - $repeat = "repeat-y"; - } - - if ( ($repeat === "repeat-x" && $bg_x <= 0 && $img_w+$bg_x >= $bg_width) || - ($repeat === "repeat-y" && $bg_y <= 0 && $img_h+$bg_y >= $bg_height) ) { - $repeat = "no-repeat"; - } - - //Use filename as indicator only - //different names for different variants to have different copies in the pdf - //This is not dependent of background color of box! .'_'.(is_array($bg_color) ? $bg_color["hex"] : $bg_color) - //Note: Here, bg_* are the start values, not end values after going through the tile loops! - - $filedummy = $img; - - $is_png = false; - $filedummy .= '_'.$bg_width.'_'.$bg_height.'_'.$bg_x.'_'.$bg_y.'_'.$repeat; - - //Optimization to avoid multiple times rendering the same image. - //If check functions are existing and identical image already cached, - //then skip creation of duplicate, because it is not needed by addImagePng - if ( $this->_canvas instanceof CPDF_Adapter && - $this->_canvas->get_cpdf()->image_iscached($filedummy) ) { - $bg = null; - } - - else { - - // Create a new image to fit over the background rectangle - $bg = imagecreatetruecolor($bg_width, $bg_height); - - switch (strtolower($type)) { - case IMAGETYPE_PNG: - $is_png = true; - imagesavealpha($bg, true); - imagealphablending($bg, false); - $src = imagecreatefrompng($img); - break; - - case IMAGETYPE_JPEG: - $src = imagecreatefromjpeg($img); - break; - - case IMAGETYPE_GIF: - $src = imagecreatefromgif($img); - break; - - case IMAGETYPE_BMP: - $src = imagecreatefrombmp($img); - break; - - default: - return; // Unsupported image type - } - - if ( $src == null ) { - return; - } - - //Background color if box is not relevant here - //Non transparent image: box clipped to real size. Background non relevant. - //Transparent image: The image controls the transparency and lets shine through whatever background. - //However on transparent image preset the composed image with the transparency color, - //to keep the transparency when copying over the non transparent parts of the tiles. - $ti = imagecolortransparent($src); - - if ( $ti >= 0 ) { - $tc = imagecolorsforindex($src, $ti); - $ti = imagecolorallocate($bg, $tc['red'], $tc['green'], $tc['blue']); - imagefill($bg, 0, 0, $ti); - imagecolortransparent($bg, $ti); - } - - //This has only an effect for the non repeatable dimension. - //compute start of src and dest coordinates of the single copy - if ( $bg_x < 0 ) { - $dst_x = 0; - $src_x = -$bg_x; - } - else { - $src_x = 0; - $dst_x = $bg_x; - } - - if ( $bg_y < 0 ) { - $dst_y = 0; - $src_y = -$bg_y; - } - else { - $src_y = 0; - $dst_y = $bg_y; - } - - //For historical reasons exchange meanings of variables: - //start_* will be the start values, while bg_* will be the temporary start values in the loops - $start_x = $bg_x; - $start_y = $bg_y; - - // Copy regions from the source image to the background - if ( $repeat === "no-repeat" ) { - - // Simply place the image on the background - imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $img_h); - - } - else if ( $repeat === "repeat-x" ) { - - for ( $bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w ) { - if ( $bg_x < 0 ) { - $dst_x = 0; - $src_x = -$bg_x; - $w = $img_w + $bg_x; - } - else { - $dst_x = $bg_x; - $src_x = 0; - $w = $img_w; - } - imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $img_h); - } - - } - else if ( $repeat === "repeat-y" ) { - - for ( $bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h ) { - if ( $bg_y < 0 ) { - $dst_y = 0; - $src_y = -$bg_y; - $h = $img_h + $bg_y; - } - else { - $dst_y = $bg_y; - $src_y = 0; - $h = $img_h; - } - imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $h); - - } - - } - else if ( $repeat === "repeat" ) { - - for ( $bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h ) { - for ( $bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w ) { - - if ( $bg_x < 0 ) { - $dst_x = 0; - $src_x = -$bg_x; - $w = $img_w + $bg_x; - } - else { - $dst_x = $bg_x; - $src_x = 0; - $w = $img_w; - } - - if ( $bg_y < 0 ) { - $dst_y = 0; - $src_y = -$bg_y; - $h = $img_h + $bg_y; - } - else { - $dst_y = $bg_y; - $src_y = 0; - $h = $img_h; - } - imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $h); - } - } - } - - else { - print 'Unknown repeat!'; - } - - imagedestroy($src); - - } /* End optimize away creation of duplicates */ - - $this->_canvas->clipping_rectangle($x, $y, $box_width, $box_height); - - //img: image url string - //img_w, img_h: original image size in px - //width, height: box size in pt - //bg_width, bg_height: box size in px - //x, y: left/top edge of box on page in pt - //start_x, start_y: placement of image relative to pattern - //$repeat: repeat mode - //$bg: GD object of result image - //$src: GD object of original image - //When using cpdf and optimization to direct png creation from gd object is available, - //don't create temp file, but place gd object directly into the pdf - if ( !$is_png && $this->_canvas instanceof CPDF_Adapter ) { - // Note: CPDF_Adapter image converts y position - $this->_canvas->get_cpdf()->addImagePng($filedummy, $x, $this->_canvas->get_height() - $y - $height, $width, $height, $bg); - } - - else { - $tmp_dir = $this->_dompdf->get_option("temp_dir"); - $tmp_name = tempnam($tmp_dir, "bg_dompdf_img_"); - @unlink($tmp_name); - $tmp_file = "$tmp_name.png"; - - //debugpng - if (DEBUGPNG) print '[_background_image '.$tmp_file.']'; - - imagepng($bg, $tmp_file); - $this->_canvas->image($tmp_file, $x, $y, $width, $height); - imagedestroy($bg); - - //debugpng - if (DEBUGPNG) print '[_background_image unlink '.$tmp_file.']'; - - if (!DEBUGKEEPTEMP) { - unlink($tmp_file); - } - } - - $this->_canvas->clipping_end(); - } - - protected function _get_dash_pattern($style, $width) { - $pattern = array(); - - switch ($style) { - default: - /*case "solid": - case "double": - case "groove": - case "inset": - case "outset": - case "ridge":*/ - case "none": break; - - case "dotted": - if ( $width <= 1 ) - $pattern = array($width, $width*2); - else - $pattern = array($width); - break; - - case "dashed": - $pattern = array(3 * $width); - break; - } - - return $pattern; - } - - protected function _border_none($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - return; - } - - protected function _border_hidden($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - return; - } - - // Border rendering functions - - protected function _border_dotted($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dotted", $r1, $r2); - } - - - protected function _border_dashed($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dashed", $r1, $r2); - } - - - protected function _border_solid($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - // TODO: Solve rendering where one corner is beveled (radius == 0), one corner isn't. - if ( $corner_style !== "bevel" || $r1 > 0 || $r2 > 0 ) { - // do it the simple way - $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "solid", $r1, $r2); - return; - } - - list($top, $right, $bottom, $left) = $widths; - - // All this polygon business is for beveled corners... - switch ($side) { - case "top": - $points = array($x, $y, - $x + $length, $y, - $x + $length - $right, $y + $top, - $x + $left, $y + $top); - $this->_canvas->polygon($points, $color, null, null, true); - break; - - case "bottom": - $points = array($x, $y, - $x + $length, $y, - $x + $length - $right, $y - $bottom, - $x + $left, $y - $bottom); - $this->_canvas->polygon($points, $color, null, null, true); - break; - - case "left": - $points = array($x, $y, - $x, $y + $length, - $x + $left, $y + $length - $bottom, - $x + $left, $y + $top); - $this->_canvas->polygon($points, $color, null, null, true); - break; - - case "right": - $points = array($x, $y, - $x, $y + $length, - $x - $right, $y + $length - $bottom, - $x - $right, $y + $top); - $this->_canvas->polygon($points, $color, null, null, true); - break; - - default: - return; - } - } - - protected function _apply_ratio($side, $ratio, $top, $right, $bottom, $left, &$x, &$y, &$length, &$r1, &$r2) { - switch ($side) { - - case "top": - $r1 -= $left * $ratio; - $r2 -= $right * $ratio; - $x += $left * $ratio; - $y += $top * $ratio; - $length -= $left * $ratio + $right * $ratio; - break; - - case "bottom": - $r1 -= $right * $ratio; - $r2 -= $left * $ratio; - $x += $left * $ratio; - $y -= $bottom * $ratio; - $length -= $left * $ratio + $right * $ratio; - break; - - case "left": - $r1 -= $top * $ratio; - $r2 -= $bottom * $ratio; - $x += $left * $ratio; - $y += $top * $ratio; - $length -= $top * $ratio + $bottom * $ratio; - break; - - case "right": - $r1 -= $bottom * $ratio; - $r2 -= $top * $ratio; - $x -= $right * $ratio; - $y += $top * $ratio; - $length -= $top * $ratio + $bottom * $ratio; - break; - - default: - return; - - } - } - - protected function _border_double($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - list($top, $right, $bottom, $left) = $widths; - - $third_widths = array($top / 3, $right / 3, $bottom / 3, $left / 3); - - // draw the outer border - $this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2); - - $this->_apply_ratio($side, 2/3, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2); - - $this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2); - } - - protected function _border_groove($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - list($top, $right, $bottom, $left) = $widths; - - $half_widths = array($top / 2, $right / 2, $bottom / 2, $left / 2); - - $this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); - - $this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2); - - $this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); - - } - - protected function _border_ridge($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - list($top, $right, $bottom, $left) = $widths; - - $half_widths = array($top / 2, $right / 2, $bottom / 2, $left / 2); - - $this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); - - $this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2); - - $this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); - - } - - protected function _tint($c) { - if ( !is_numeric($c) ) - return $c; - - return min(1, $c + 0.16); - } - - protected function _shade($c) { - if ( !is_numeric($c) ) - return $c; - - return max(0, $c - 0.33); - } - - protected function _border_inset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - switch ($side) { - case "top": - case "left": - $shade = array_map(array($this, "_shade"), $color); - $this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2); - break; - - case "bottom": - case "right": - $tint = array_map(array($this, "_tint"), $color); - $this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2); - break; - - default: - return; - } - } - - protected function _border_outset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) { - switch ($side) { - case "top": - case "left": - $tint = array_map(array($this, "_tint"), $color); - $this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2); - break; - - case "bottom": - case "right": - $shade = array_map(array($this, "_shade"), $color); - $this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2); - break; - - default: - return; - } - } - // Draws a solid, dotted, or dashed line, observing the border radius - protected function _border_line($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $pattern_name, $r1 = 0, $r2 = 0) { - list($top, $right, $bottom, $left) = $widths; - - $width = $$side; - $pattern = $this->_get_dash_pattern($pattern_name, $width); - - $half_width = $width/2; - $r1 -= $half_width; - $r2 -= $half_width; - $adjust = $r1/80; - $length -= $width; - - switch ($side) { - case "top": - $x += $half_width; - $y += $half_width; - - if ( $r1 > 0 ) { - $this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 90-$adjust, 135+$adjust, $color, $width, $pattern); - } - - $this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern); - - if ( $r2 > 0 ) { - $this->_canvas->arc($x + $length - $r2, $y + $r2, $r2, $r2, 45-$adjust, 90+$adjust, $color, $width, $pattern); - } - break; - - case "bottom": - $x += $half_width; - $y -= $half_width; - - if ( $r1 > 0 ) { - $this->_canvas->arc($x + $r1, $y - $r1, $r1, $r1, 225-$adjust, 270+$adjust, $color, $width, $pattern); - } - - $this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern); - - if ( $r2 > 0 ) { - $this->_canvas->arc($x + $length - $r2, $y - $r2, $r2, $r2, 270-$adjust, 315+$adjust, $color, $width, $pattern); - } - break; - - case "left": - $y += $half_width; - $x += $half_width; - - if ( $r1 > 0 ) { - $this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 135-$adjust, 180+$adjust, $color, $width, $pattern); - } - - $this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern); - - if ( $r2 > 0 ) { - $this->_canvas->arc($x + $r2, $y + $length - $r2, $r2, $r2, 180-$adjust, 225+$adjust, $color, $width, $pattern); - } - break; - - case "right": - $y += $half_width; - $x -= $half_width; - - if ( $r1 > 0 ) { - $this->_canvas->arc($x - $r1, $y + $r1, $r1, $r1, 0-$adjust, 45+$adjust, $color, $width, $pattern); - } - - $this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern); - - if ( $r2 > 0 ) { - $this->_canvas->arc($x - $r2, $y + $length - $r2, $r2, $r2, 315-$adjust, 360+$adjust, $color, $width, $pattern); - } - break; - } - } - - protected function _set_opacity($opacity) { - if ( is_numeric($opacity) && $opacity <= 1.0 && $opacity >= 0.0 ) { - $this->_canvas->set_opacity( $opacity ); - } - } - - protected function _debug_layout($box, $color = "red", $style = array()) { - $this->_canvas->rectangle($box[0], $box[1], $box[2], $box[3], CSS_Color::parse($color), 0.1, $style); - } -} diff --git a/application/helpers/dompdf/include/attribute_translator.cls.php b/application/helpers/dompdf/include/attribute_translator.cls.php deleted file mode 100755 index 68da668c1..000000000 --- a/application/helpers/dompdf/include/attribute_translator.cls.php +++ /dev/null @@ -1,592 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Translates HTML 4.0 attributes into CSS rules - * - * @package dompdf - */ -class Attribute_Translator { - static $_style_attr = "_html_style_attribute"; - - // Munged data originally from - // http://www.w3.org/TR/REC-html40/index/attributes.html - // http://www.cs.tut.fi/~jkorpela/html2css.html - static private $__ATTRIBUTE_LOOKUP = array( - //'caption' => array ( 'align' => '', ), - 'img' => array( - 'align' => array( - 'bottom' => 'vertical-align: baseline;', - 'middle' => 'vertical-align: middle;', - 'top' => 'vertical-align: top;', - 'left' => 'float: left;', - 'right' => 'float: right;' - ), - 'border' => 'border: %0.2F px solid;', - 'height' => 'height: %s px;', - 'hspace' => 'padding-left: %1$0.2F px; padding-right: %1$0.2F px;', - 'vspace' => 'padding-top: %1$0.2F px; padding-bottom: %1$0.2F px;', - 'width' => 'width: %s px;', - ), - 'table' => array( - 'align' => array( - 'left' => 'margin-left: 0; margin-right: auto;', - 'center' => 'margin-left: auto; margin-right: auto;', - 'right' => 'margin-left: auto; margin-right: 0;' - ), - 'bgcolor' => 'background-color: %s;', - 'border' => '!set_table_border', - 'cellpadding' => '!set_table_cellpadding',//'border-spacing: %0.2F; border-collapse: separate;', - 'cellspacing' => '!set_table_cellspacing', - 'frame' => array( - 'void' => 'border-style: none;', - 'above' => 'border-top-style: solid;', - 'below' => 'border-bottom-style: solid;', - 'hsides' => 'border-left-style: solid; border-right-style: solid;', - 'vsides' => 'border-top-style: solid; border-bottom-style: solid;', - 'lhs' => 'border-left-style: solid;', - 'rhs' => 'border-right-style: solid;', - 'box' => 'border-style: solid;', - 'border' => 'border-style: solid;' - ), - 'rules' => '!set_table_rules', - 'width' => 'width: %s;', - ), - 'hr' => array( - 'align' => '!set_hr_align', // Need to grab width to set 'left' & 'right' correctly - 'noshade' => 'border-style: solid;', - 'size' => '!set_hr_size', //'border-width: %0.2F px;', - 'width' => 'width: %s;', - ), - 'div' => array( - 'align' => 'text-align: %s;', - ), - 'h1' => array( - 'align' => 'text-align: %s;', - ), - 'h2' => array( - 'align' => 'text-align: %s;', - ), - 'h3' => array( - 'align' => 'text-align: %s;', - ), - 'h4' => array( - 'align' => 'text-align: %s;', - ), - 'h5' => array( - 'align' => 'text-align: %s;', - ), - 'h6' => array( - 'align' => 'text-align: %s;', - ), - 'p' => array( - 'align' => 'text-align: %s;', - ), -// 'col' => array( -// 'align' => '', -// 'valign' => '', -// ), -// 'colgroup' => array( -// 'align' => '', -// 'valign' => '', -// ), - 'tbody' => array( - 'align' => '!set_table_row_align', - 'valign' => '!set_table_row_valign', - ), - 'td' => array( - 'align' => 'text-align: %s;', - 'bgcolor' => '!set_background_color', - 'height' => 'height: %s;', - 'nowrap' => 'white-space: nowrap;', - 'valign' => 'vertical-align: %s;', - 'width' => 'width: %s;', - ), - 'tfoot' => array( - 'align' => '!set_table_row_align', - 'valign' => '!set_table_row_valign', - ), - 'th' => array( - 'align' => 'text-align: %s;', - 'bgcolor' => '!set_background_color', - 'height' => 'height: %s;', - 'nowrap' => 'white-space: nowrap;', - 'valign' => 'vertical-align: %s;', - 'width' => 'width: %s;', - ), - 'thead' => array( - 'align' => '!set_table_row_align', - 'valign' => '!set_table_row_valign', - ), - 'tr' => array( - 'align' => '!set_table_row_align', - 'bgcolor' => '!set_table_row_bgcolor', - 'valign' => '!set_table_row_valign', - ), - 'body' => array( - 'background' => 'background-image: url(%s);', - 'bgcolor' => '!set_background_color', - 'link' => '!set_body_link', - 'text' => '!set_color', - ), - 'br' => array( - 'clear' => 'clear: %s;', - ), - 'basefont' => array( - 'color' => '!set_color', - 'face' => 'font-family: %s;', - 'size' => '!set_basefont_size', - ), - 'font' => array( - 'color' => '!set_color', - 'face' => 'font-family: %s;', - 'size' => '!set_font_size', - ), - 'dir' => array( - 'compact' => 'margin: 0.5em 0;', - ), - 'dl' => array( - 'compact' => 'margin: 0.5em 0;', - ), - 'menu' => array( - 'compact' => 'margin: 0.5em 0;', - ), - 'ol' => array( - 'compact' => 'margin: 0.5em 0;', - 'start' => 'counter-reset: -dompdf-default-counter %d;', - 'type' => 'list-style-type: %s;', - ), - 'ul' => array( - 'compact' => 'margin: 0.5em 0;', - 'type' => 'list-style-type: %s;', - ), - 'li' => array( - 'type' => 'list-style-type: %s;', - 'value' => 'counter-reset: -dompdf-default-counter %d;', - ), - 'pre' => array( - 'width' => 'width: %s;', - ), - ); - - static protected $_last_basefont_size = 3; - static protected $_font_size_lookup = array( - // For basefont support - -3 => "4pt", - -2 => "5pt", - -1 => "6pt", - 0 => "7pt", - - 1 => "8pt", - 2 => "10pt", - 3 => "12pt", - 4 => "14pt", - 5 => "18pt", - 6 => "24pt", - 7 => "34pt", - - // For basefont support - 8 => "48pt", - 9 => "44pt", - 10 => "52pt", - 11 => "60pt", - ); - - /** - * @param Frame $frame - */ - static function translate_attributes(Frame $frame) { - $node = $frame->get_node(); - $tag = $node->nodeName; - - if ( !isset(self::$__ATTRIBUTE_LOOKUP[$tag]) ) { - return; - } - - $valid_attrs = self::$__ATTRIBUTE_LOOKUP[$tag]; - $attrs = $node->attributes; - $style = rtrim($node->getAttribute(self::$_style_attr), "; "); - if ( $style != "" ) { - $style .= ";"; - } - - foreach ($attrs as $attr => $attr_node ) { - if ( !isset($valid_attrs[$attr]) ) { - continue; - } - - $value = $attr_node->value; - - $target = $valid_attrs[$attr]; - - // Look up $value in $target, if $target is an array: - if ( is_array($target) ) { - if ( isset($target[$value]) ) { - $style .= " " . self::_resolve_target($node, $target[$value], $value); - } - } - else { - // otherwise use target directly - $style .= " " . self::_resolve_target($node, $target, $value); - } - } - - if ( !is_null($style) ) { - $style = ltrim($style); - $node->setAttribute(self::$_style_attr, $style); - } - - } - - /** - * @param DOMNode $node - * @param string $target - * @param string $value - * - * @return string - */ - static protected function _resolve_target(DOMNode $node, $target, $value) { - if ( $target[0] === "!" ) { - // Function call - $func = "_" . mb_substr($target, 1); - return self::$func($node, $value); - } - - return $value ? sprintf($target, $value) : ""; - } - - /** - * @param DOMElement $node - * @param string $new_style - */ - static function append_style(DOMElement $node, $new_style) { - $style = rtrim($node->getAttribute(self::$_style_attr), ";"); - $style .= $new_style; - $style = ltrim($style, ";"); - $node->setAttribute(self::$_style_attr, $style); - } - - /** - * @param DOMNode $node - * - * @return DOMNodeList|DOMElement[] - */ - static protected function get_cell_list(DOMNode $node) { - $xpath = new DOMXpath($node->ownerDocument); - - switch($node->nodeName) { - default: - case "table": - $query = "tr/td | thead/tr/td | tbody/tr/td | tfoot/tr/td | tr/th | thead/tr/th | tbody/tr/th | tfoot/tr/th"; - break; - - case "tbody": - case "tfoot": - case "thead": - $query = "tr/td | tr/th"; - break; - - case "tr": - $query = "td | th"; - break; - } - - return $xpath->query($query, $node); - } - - /** - * @param string $value - * - * @return string - */ - static protected function _get_valid_color($value) { - if ( preg_match('/^#?([0-9A-F]{6})$/i', $value, $matches) ) { - $value = "#$matches[1]"; - } - - return $value; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return string - */ - static protected function _set_color(DOMElement $node, $value) { - $value = self::_get_valid_color($value); - return "color: $value;"; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return string - */ - static protected function _set_background_color(DOMElement $node, $value) { - $value = self::_get_valid_color($value); - return "background-color: $value;"; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null - */ - static protected function _set_table_cellpadding(DOMElement $node, $value) { - $cell_list = self::get_cell_list($node); - - foreach ($cell_list as $cell) { - self::append_style($cell, "; padding: {$value}px;"); - } - - return null; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return string - */ - static protected function _set_table_border(DOMElement $node, $value) { - $cell_list = self::get_cell_list($node); - - foreach ($cell_list as $cell) { - $style = rtrim($cell->getAttribute(self::$_style_attr)); - $style .= "; border-width: " . ($value > 0 ? 1 : 0) . "pt; border-style: inset;"; - $style = ltrim($style, ";"); - $cell->setAttribute(self::$_style_attr, $style); - } - - $style = rtrim($node->getAttribute(self::$_style_attr), ";"); - $style .= "; border-width: $value" . "px; "; - return ltrim($style, "; "); - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return string - */ - static protected function _set_table_cellspacing(DOMElement $node, $value) { - $style = rtrim($node->getAttribute(self::$_style_attr), ";"); - - if ( $value == 0 ) { - $style .= "; border-collapse: collapse;"; - } - else { - $style .= "; border-spacing: {$value}px; border-collapse: separate;"; - } - - return ltrim($style, ";"); - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null|string - */ - static protected function _set_table_rules(DOMElement $node, $value) { - $new_style = "; border-collapse: collapse;"; - - switch ($value) { - case "none": - $new_style .= "border-style: none;"; - break; - - case "groups": - // FIXME: unsupported - return null; - - case "rows": - $new_style .= "border-style: solid none solid none; border-width: 1px; "; - break; - - case "cols": - $new_style .= "border-style: none solid none solid; border-width: 1px; "; - break; - - case "all": - $new_style .= "border-style: solid; border-width: 1px; "; - break; - - default: - // Invalid value - return null; - } - - $cell_list = self::get_cell_list($node); - - foreach ($cell_list as $cell) { - $style = $cell->getAttribute(self::$_style_attr); - $style .= $new_style; - $cell->setAttribute(self::$_style_attr, $style); - } - - $style = rtrim($node->getAttribute(self::$_style_attr), ";"); - $style .= "; border-collapse: collapse; "; - - return ltrim($style, "; "); - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return string - */ - static protected function _set_hr_size(DOMElement $node, $value) { - $style = rtrim($node->getAttribute(self::$_style_attr), ";"); - $style .= "; border-width: ".max(0, $value-2)."; "; - return ltrim($style, "; "); - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null|string - */ - static protected function _set_hr_align(DOMElement $node, $value) { - $style = rtrim($node->getAttribute(self::$_style_attr),";"); - $width = $node->getAttribute("width"); - - if ( $width == "" ) { - $width = "100%"; - } - - $remainder = 100 - (double)rtrim($width, "% "); - - switch ($value) { - case "left": - $style .= "; margin-right: $remainder %;"; - break; - - case "right": - $style .= "; margin-left: $remainder %;"; - break; - - case "center": - $style .= "; margin-left: auto; margin-right: auto;"; - break; - - default: - return null; - } - - return ltrim($style, "; "); - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null - */ - static protected function _set_table_row_align(DOMElement $node, $value) { - $cell_list = self::get_cell_list($node); - - foreach ($cell_list as $cell) { - self::append_style($cell, "; text-align: $value;"); - } - - return null; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null - */ - static protected function _set_table_row_valign(DOMElement $node, $value) { - $cell_list = self::get_cell_list($node); - - foreach ($cell_list as $cell) { - self::append_style($cell, "; vertical-align: $value;"); - } - - return null; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null - */ - static protected function _set_table_row_bgcolor(DOMElement $node, $value) { - $cell_list = self::get_cell_list($node); - $value = self::_get_valid_color($value); - - foreach ($cell_list as $cell) { - self::append_style($cell, "; background-color: $value;"); - } - - return null; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null - */ - static protected function _set_body_link(DOMElement $node, $value) { - $a_list = $node->getElementsByTagName("a"); - $value = self::_get_valid_color($value); - - foreach ($a_list as $a) { - self::append_style($a, "; color: $value;"); - } - - return null; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return null - */ - static protected function _set_basefont_size(DOMElement $node, $value) { - // FIXME: ? we don't actually set the font size of anything here, just - // the base size for later modification by tags. - self::$_last_basefont_size = $value; - return null; - } - - /** - * @param DOMElement $node - * @param string $value - * - * @return string - */ - static protected function _set_font_size(DOMElement $node, $value) { - $style = $node->getAttribute(self::$_style_attr); - - if ( $value[0] === "-" || $value[0] === "+" ) { - $value = self::$_last_basefont_size + (int)$value; - } - - if ( isset(self::$_font_size_lookup[$value]) ) { - $style .= "; font-size: " . self::$_font_size_lookup[$value] . ";"; - } - else { - $style .= "; font-size: $value;"; - } - - return ltrim($style, "; "); - } -} diff --git a/application/helpers/dompdf/include/autoload.inc.php b/application/helpers/dompdf/include/autoload.inc.php deleted file mode 100755 index 509d3e3bc..000000000 --- a/application/helpers/dompdf/include/autoload.inc.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * DOMPDF autoload function - * - * If you have an existing autoload function, add a call to this function - * from your existing __autoload() implementation. - * - * @param string $class - */ -function DOMPDF_autoload($class) { - $filename = DOMPDF_INC_DIR . "/" . mb_strtolower($class) . ".cls.php"; - - if ( is_file($filename) ) { - include_once $filename; - } -} - -// If SPL autoload functions are available (PHP >= 5.1.2) -if ( function_exists("spl_autoload_register") ) { - $autoload = "DOMPDF_autoload"; - $funcs = spl_autoload_functions(); - - // No functions currently in the stack. - if ( !DOMPDF_AUTOLOAD_PREPEND || $funcs === false ) { - spl_autoload_register($autoload); - } - - // If PHP >= 5.3 the $prepend argument is available - else if ( PHP_VERSION_ID >= 50300 ) { - spl_autoload_register($autoload, true, true); - } - - else { - // Unregister existing autoloaders... - $compat = (PHP_VERSION_ID <= 50102 && PHP_VERSION_ID >= 50100); - - foreach ($funcs as $func) { - if (is_array($func)) { - // :TRICKY: There are some compatibility issues and some - // places where we need to error out - $reflector = new ReflectionMethod($func[0], $func[1]); - if (!$reflector->isStatic()) { - throw new Exception('This function is not compatible with non-static object methods due to PHP Bug #44144.'); - } - - // Suprisingly, spl_autoload_register supports the - // Class::staticMethod callback format, although call_user_func doesn't - if ($compat) $func = implode('::', $func); - } - - spl_autoload_unregister($func); - } - - // Register the new one, thus putting it at the front of the stack... - spl_autoload_register($autoload); - - // Now, go back and re-register all of our old ones. - foreach ($funcs as $func) { - spl_autoload_register($func); - } - - // Be polite and ensure that userland autoload gets retained - if ( function_exists("__autoload") ) { - spl_autoload_register("__autoload"); - } - } -} - -else if ( !function_exists("__autoload") ) { - /** - * Default __autoload() function - * - * @param string $class - */ - function __autoload($class) { - DOMPDF_autoload($class); - } -} diff --git a/application/helpers/dompdf/include/block_frame_decorator.cls.php b/application/helpers/dompdf/include/block_frame_decorator.cls.php deleted file mode 100755 index 407635c0e..000000000 --- a/application/helpers/dompdf/include/block_frame_decorator.cls.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Decorates frames for block layout - * - * @access private - * @package dompdf - */ -class Block_Frame_Decorator extends Frame_Decorator { - /** - * Current line index - * - * @var int - */ - protected $_cl; - - /** - * The block's line boxes - * - * @var Line_Box[] - */ - protected $_line_boxes; - - function __construct(Frame $frame, DOMPDF $dompdf) { - parent::__construct($frame, $dompdf); - - $this->_line_boxes = array(new Line_Box($this)); - $this->_cl = 0; - } - - function reset() { - parent::reset(); - - $this->_line_boxes = array(new Line_Box($this)); - $this->_cl = 0; - } - - /** - * @return Line_Box - */ - function get_current_line_box() { - return $this->_line_boxes[$this->_cl]; - } - - /** - * @return integer - */ - function get_current_line_number() { - return $this->_cl; - } - - /** - * @return Line_Box[] - */ - function get_line_boxes() { - return $this->_line_boxes; - } - - /** - * @param integer $i - */ - function clear_line($i) { - if ( isset($this->_line_boxes[$i]) ) { - unset($this->_line_boxes[$i]); - } - } - - /** - * @param Frame $frame - */ - function add_frame_to_line(Frame $frame) { - if ( !$frame->is_in_flow() ) { - return; - } - - $style = $frame->get_style(); - - $frame->set_containing_line($this->_line_boxes[$this->_cl]); - - /* - // Adds a new line after a block, only if certain conditions are met - if ((($frame instanceof Inline_Frame_Decorator && $frame->get_node()->nodeName !== "br") || - $frame instanceof Text_Frame_Decorator && trim($frame->get_text())) && - ($frame->get_prev_sibling() && $frame->get_prev_sibling()->get_style()->display === "block" && - $this->_line_boxes[$this->_cl]->w > 0 )) { - - $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame ); - $this->add_line(); - - // Add each child of the inline frame to the line individually - foreach ($frame->get_children() as $child) - $this->add_frame_to_line( $child ); - } - else*/ - - // Handle inline frames (which are effectively wrappers) - if ( $frame instanceof Inline_Frame_Decorator ) { - - // Handle line breaks - if ( $frame->get_node()->nodeName === "br" ) { - $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame ); - $this->add_line(true); - } - - return; - } - - // Trim leading text if this is an empty line. Kinda a hack to put it here, - // but what can you do... - if ( $this->get_current_line_box()->w == 0 && - $frame->is_text_node() && - !$frame->is_pre() ) { - - $frame->set_text( ltrim($frame->get_text()) ); - $frame->recalculate_width(); - } - - $w = $frame->get_margin_width(); - - if ( $w == 0 ) { - return; - } - - // Debugging code: - /* - pre_r("\n

Adding frame to line:

"); - - // pre_r("Me: " . $this->get_node()->nodeName . " (" . spl_object_hash($this->get_node()) . ")"); - // pre_r("Node: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")"); - if ( $frame->is_text_node() ) - pre_r('"'.$frame->get_node()->nodeValue.'"'); - - pre_r("Line width: " . $this->_line_boxes[$this->_cl]->w); - pre_r("Frame: " . get_class($frame)); - pre_r("Frame width: " . $w); - pre_r("Frame height: " . $frame->get_margin_height()); - pre_r("Containing block width: " . $this->get_containing_block("w")); - */ - // End debugging - - $line = $this->_line_boxes[$this->_cl]; - if ( $line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) { - $this->add_line(); - } - - $frame->position(); - - $current_line = $this->_line_boxes[$this->_cl]; - $current_line->add_frame($frame); - - if ( $frame->is_text_node() ) { - $current_line->wc += count(preg_split("/\s+/", trim($frame->get_text()))); - } - - $this->increase_line_width($w); - - $this->maximize_line_height($frame->get_margin_height(), $frame); - } - - function remove_frames_from_line(Frame $frame) { - // Search backwards through the lines for $frame - $i = $this->_cl; - $j = null; - - while ($i >= 0) { - if ( ($j = in_array($frame, $this->_line_boxes[$i]->get_frames(), true)) !== false ) { - break; - } - - $i--; - } - - if ( $j === false ) { - return; - } - - // Remove $frame and all frames that follow - while ($j < count($this->_line_boxes[$i]->get_frames())) { - $frames = $this->_line_boxes[$i]->get_frames(); - $f = $frames[$j]; - $frames[$j] = null; - unset($frames[$j]); - $j++; - $this->_line_boxes[$i]->w -= $f->get_margin_width(); - } - - // Recalculate the height of the line - $h = 0; - foreach ($this->_line_boxes[$i]->get_frames() as $f) { - $h = max( $h, $f->get_margin_height() ); - } - - $this->_line_boxes[$i]->h = $h; - - // Remove all lines that follow - while ($this->_cl > $i) { - $this->_line_boxes[ $this->_cl ] = null; - unset($this->_line_boxes[ $this->_cl ]); - $this->_cl--; - } - } - - function increase_line_width($w) { - $this->_line_boxes[ $this->_cl ]->w += $w; - } - - function maximize_line_height($val, Frame $frame) { - if ( $val > $this->_line_boxes[ $this->_cl ]->h ) { - $this->_line_boxes[ $this->_cl ]->tallest_frame = $frame; - $this->_line_boxes[ $this->_cl ]->h = $val; - } - } - - function add_line($br = false) { - -// if ( $this->_line_boxes[$this->_cl]["h"] == 0 ) //count($this->_line_boxes[$i]["frames"]) == 0 || -// return; - - $this->_line_boxes[$this->_cl]->br = $br; - $y = $this->_line_boxes[$this->_cl]->y + $this->_line_boxes[$this->_cl]->h; - - $new_line = new Line_Box($this, $y); - - $this->_line_boxes[ ++$this->_cl ] = $new_line; - } - - //........................................................................ -} diff --git a/application/helpers/dompdf/include/block_frame_reflower.cls.php b/application/helpers/dompdf/include/block_frame_reflower.cls.php deleted file mode 100755 index bbbdba96d..000000000 --- a/application/helpers/dompdf/include/block_frame_reflower.cls.php +++ /dev/null @@ -1,805 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Reflows block frames - * - * @access private - * @package dompdf - */ -class Block_Frame_Reflower extends Frame_Reflower { - // Minimum line width to justify, as fraction of available width - const MIN_JUSTIFY_WIDTH = 0.80; - - /** - * @var Block_Frame_Decorator - */ - protected $_frame; - - function __construct(Block_Frame_Decorator $frame) { parent::__construct($frame); } - - /** - * Calculate the ideal used value for the width property as per: - * http://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins - * - * @param float $width - * @return array - */ - protected function _calculate_width($width) { - $frame = $this->_frame; - $style = $frame->get_style(); - $w = $frame->get_containing_block("w"); - - if ( $style->position === "fixed" ) { - $w = $frame->get_parent()->get_containing_block("w"); - } - - $rm = $style->length_in_pt($style->margin_right, $w); - $lm = $style->length_in_pt($style->margin_left, $w); - - $left = $style->length_in_pt($style->left, $w); - $right = $style->length_in_pt($style->right, $w); - - // Handle 'auto' values - $dims = array($style->border_left_width, - $style->border_right_width, - $style->padding_left, - $style->padding_right, - $width !== "auto" ? $width : 0, - $rm !== "auto" ? $rm : 0, - $lm !== "auto" ? $lm : 0); - - // absolutely positioned boxes take the 'left' and 'right' properties into account - if ( $frame->is_absolute() ) { - $absolute = true; - $dims[] = $left !== "auto" ? $left : 0; - $dims[] = $right !== "auto" ? $right : 0; - } - else { - $absolute = false; - } - - $sum = $style->length_in_pt($dims, $w); - - // Compare to the containing block - $diff = $w - $sum; - - if ( $diff > 0 ) { - - if ( $absolute ) { - - // resolve auto properties: see - // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width - - if ( $width === "auto" && $left === "auto" && $right === "auto" ) { - - if ( $lm === "auto" ) $lm = 0; - if ( $rm === "auto" ) $rm = 0; - - // Technically, the width should be "shrink-to-fit" i.e. based on the - // preferred width of the content... a little too costly here as a - // special case. Just get the width to take up the slack: - $left = 0; - $right = 0; - $width = $diff; - } - else if ( $width === "auto" ) { - - if ( $lm === "auto" ) $lm = 0; - if ( $rm === "auto" ) $rm = 0; - if ( $left === "auto" ) $left = 0; - if ( $right === "auto" ) $right = 0; - - $width = $diff; - } - else if ( $left === "auto" ) { - - if ( $lm === "auto" ) $lm = 0; - if ( $rm === "auto" ) $rm = 0; - if ( $right === "auto" ) $right = 0; - - $left = $diff; - } - else if ( $right === "auto" ) { - - if ( $lm === "auto" ) $lm = 0; - if ( $rm === "auto" ) $rm = 0; - - $right = $diff; - } - - } - else { - - // Find auto properties and get them to take up the slack - if ( $width === "auto" ) { - $width = $diff; - } - else if ( $lm === "auto" && $rm === "auto" ) { - $lm = $rm = round($diff / 2); - } - else if ( $lm === "auto" ) { - $lm = $diff; - } - else if ( $rm === "auto" ) { - $rm = $diff; - } - } - - } - else if ($diff < 0) { - - // We are over constrained--set margin-right to the difference - $rm = $diff; - - } - - return array( - "width" => $width, - "margin_left" => $lm, - "margin_right" => $rm, - "left" => $left, - "right" => $right, - ); - } - - /** - * Call the above function, but resolve max/min widths - * - * @throws DOMPDF_Exception - * @return array - */ - protected function _calculate_restricted_width() { - $frame = $this->_frame; - $style = $frame->get_style(); - $cb = $frame->get_containing_block(); - - if ( $style->position === "fixed" ) { - $cb = $frame->get_root()->get_containing_block(); - } - - //if ( $style->position === "absolute" ) - // $cb = $frame->find_positionned_parent()->get_containing_block(); - - if ( !isset($cb["w"]) ) { - throw new DOMPDF_Exception("Box property calculation requires containing block width"); - } - - // Treat width 100% as auto - if ( $style->width === "100%" ) { - $width = "auto"; - } - else { - $width = $style->length_in_pt($style->width, $cb["w"]); - } - - extract($this->_calculate_width($width)); - - // Handle min/max width - $min_width = $style->length_in_pt($style->min_width, $cb["w"]); - $max_width = $style->length_in_pt($style->max_width, $cb["w"]); - - if ( $max_width !== "none" && $min_width > $max_width ) { - list($max_width, $min_width) = array($min_width, $max_width); - } - - if ( $max_width !== "none" && $width > $max_width ) { - extract($this->_calculate_width($max_width)); - } - - if ( $width < $min_width ) { - extract($this->_calculate_width($min_width)); - } - - return array($width, $margin_left, $margin_right, $left, $right); - } - - /** - * Determine the unrestricted height of content within the block - * not by adding each line's height, but by getting the last line's position. - * This because lines could have been pushed lower by a clearing element. - * - * @return float - */ - protected function _calculate_content_height() { - $lines = $this->_frame->get_line_boxes(); - $height = 0; - - foreach ($lines as $line) { - $height += $line->h; - } - - /* - $first_line = reset($lines); - $last_line = end($lines); - $height2 = $last_line->y + $last_line->h - $first_line->y; - */ - - return $height; - } - - /** - * Determine the frame's restricted height - * - * @return array - */ - protected function _calculate_restricted_height() { - $frame = $this->_frame; - $style = $frame->get_style(); - $content_height = $this->_calculate_content_height(); - $cb = $frame->get_containing_block(); - - $height = $style->length_in_pt($style->height, $cb["h"]); - - $top = $style->length_in_pt($style->top, $cb["h"]); - $bottom = $style->length_in_pt($style->bottom, $cb["h"]); - - $margin_top = $style->length_in_pt($style->margin_top, $cb["h"]); - $margin_bottom = $style->length_in_pt($style->margin_bottom, $cb["h"]); - - if ( $frame->is_absolute() ) { - - // see http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height - - $dims = array($top !== "auto" ? $top : 0, - $style->margin_top !== "auto" ? $style->margin_top : 0, - $style->padding_top, - $style->border_top_width, - $height !== "auto" ? $height : 0, - $style->border_bottom_width, - $style->padding_bottom, - $style->margin_bottom !== "auto" ? $style->margin_bottom : 0, - $bottom !== "auto" ? $bottom : 0); - - $sum = $style->length_in_pt($dims, $cb["h"]); - - $diff = $cb["h"] - $sum; - - if ( $diff > 0 ) { - - if ( $height === "auto" && $top === "auto" && $bottom === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $height = $diff; - } - else if ( $height === "auto" && $top === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $height = $content_height; - $top = $diff - $content_height; - } - else if ( $height === "auto" && $bottom === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $height = $content_height; - $bottom = $diff - $content_height; - } - else if ( $top === "auto" && $bottom === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $bottom = $diff; - } - else if ( $top === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $top = $diff; - } - else if ( $height === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $height = $diff; - } - else if ( $bottom === "auto" ) { - - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - - $bottom = $diff; - } - else { - - if ( $style->overflow === "visible" ) { - // set all autos to zero - if ( $margin_top === "auto" ) $margin_top = 0; - if ( $margin_bottom === "auto" ) $margin_bottom = 0; - if ( $top === "auto" ) $top = 0; - if ( $bottom === "auto" ) $bottom = 0; - if ( $height === "auto" ) $height = $content_height; - } - - // FIXME: overflow hidden - } - - } - - } - else { - - // Expand the height if overflow is visible - if ( $height === "auto" && $content_height > $height /* && $style->overflow === "visible" */) { - $height = $content_height; - } - - // FIXME: this should probably be moved to a seperate function as per - // _calculate_restricted_width - - // Only handle min/max height if the height is independent of the frame's content - if ( !($style->overflow === "visible" || - ($style->overflow === "hidden" && $height === "auto")) ) { - - $min_height = $style->min_height; - $max_height = $style->max_height; - - if ( isset($cb["h"]) ) { - $min_height = $style->length_in_pt($min_height, $cb["h"]); - $max_height = $style->length_in_pt($max_height, $cb["h"]); - - } - else if ( isset($cb["w"]) ) { - - if ( mb_strpos($min_height, "%") !== false ) { - $min_height = 0; - } - else { - $min_height = $style->length_in_pt($min_height, $cb["w"]); - } - - if ( mb_strpos($max_height, "%") !== false ) { - $max_height = "none"; - } - else { - $max_height = $style->length_in_pt($max_height, $cb["w"]); - } - } - - if ( $max_height !== "none" && $min_height > $max_height ) { - // Swap 'em - list($max_height, $min_height) = array($min_height, $max_height); - } - - if ( $max_height !== "none" && $height > $max_height ) { - $height = $max_height; - } - - if ( $height < $min_height ) { - $height = $min_height; - } - } - - } - - return array($height, $margin_top, $margin_bottom, $top, $bottom); - - } - - /** - * Adjust the justification of each of our lines. - * http://www.w3.org/TR/CSS21/text.html#propdef-text-align - */ - protected function _text_align() { - $style = $this->_frame->get_style(); - $w = $this->_frame->get_containing_block("w"); - $width = $style->length_in_pt($style->width, $w); - - switch ($style->text_align) { - default: - case "left": - foreach ($this->_frame->get_line_boxes() as $line) { - if ( !$line->left ) { - continue; - } - - foreach($line->get_frames() as $frame) { - if ( $frame instanceof Block_Frame_Decorator) { - continue; - } - $frame->set_position( $frame->get_position("x") + $line->left ); - } - } - return; - - case "right": - foreach ($this->_frame->get_line_boxes() as $line) { - // Move each child over by $dx - $dx = $width - $line->w - $line->right; - - foreach($line->get_frames() as $frame) { - // Block frames are not aligned by text-align - if ($frame instanceof Block_Frame_Decorator) { - continue; - } - - $frame->set_position( $frame->get_position("x") + $dx ); - } - } - break; - - - case "justify": - // We justify all lines except the last one - $lines = $this->_frame->get_line_boxes(); // needs to be a variable (strict standards) - array_pop($lines); - - foreach($lines as $i => $line) { - if ( $line->br ) { - unset($lines[$i]); - } - } - - // One space character's width. Will be used to get a more accurate spacing - $space_width = Font_Metrics::get_text_width(" ", $style->font_family, $style->font_size); - - foreach ($lines as $line) { - if ( $line->left ) { - foreach ( $line->get_frames() as $frame ) { - if ( !$frame instanceof Text_Frame_Decorator ) { - continue; - } - - $frame->set_position( $frame->get_position("x") + $line->left ); - } - } - - // Only set the spacing if the line is long enough. This is really - // just an aesthetic choice ;) - //if ( $line["left"] + $line["w"] + $line["right"] > self::MIN_JUSTIFY_WIDTH * $width ) { - - // Set the spacing for each child - if ( $line->wc > 1 ) { - $spacing = ($width - ($line->left + $line->w + $line->right) + $space_width) / ($line->wc - 1); - } - else { - $spacing = 0; - } - - $dx = 0; - foreach($line->get_frames() as $frame) { - if ( !$frame instanceof Text_Frame_Decorator ) { - continue; - } - - $text = $frame->get_text(); - $spaces = mb_substr_count($text, " "); - - $char_spacing = $style->length_in_pt($style->letter_spacing); - $_spacing = $spacing + $char_spacing; - - $frame->set_position( $frame->get_position("x") + $dx ); - $frame->set_text_spacing($_spacing); - - $dx += $spaces * $_spacing; - } - - // The line (should) now occupy the entire width - $line->w = $width; - - //} - } - break; - - case "center": - case "centre": - foreach ($this->_frame->get_line_boxes() as $line) { - // Centre each line by moving each frame in the line by: - $dx = ($width + $line->left - $line->w - $line->right ) / 2; - - foreach ($line->get_frames() as $frame) { - // Block frames are not aligned by text-align - if ($frame instanceof Block_Frame_Decorator) { - continue; - } - - $frame->set_position( $frame->get_position("x") + $dx ); - } - } - break; - } - } - - /** - * Align inline children vertically. - * Aligns each child vertically after each line is reflowed - */ - function vertical_align() { - - $canvas = null; - - foreach ( $this->_frame->get_line_boxes() as $line ) { - - $height = $line->h; - - foreach ( $line->get_frames() as $frame ) { - $style = $frame->get_style(); - - if ( $style->display !== "inline" ) { - continue; - } - - $align = $frame->get_parent()->get_style()->vertical_align; - - if ( !isset($canvas) ) { - $canvas = $frame->get_root()->get_dompdf()->get_canvas(); - } - - $baseline = $canvas->get_font_baseline($style->font_family, $style->font_size); - $y_offset = 0; - - switch ($align) { - case "baseline": - $y_offset = $height*0.8 - $baseline; // The 0.8 ratio is arbitrary until we find it's meaning - break; - - case "middle": - $y_offset = ($height*0.8 - $baseline) / 2; - break; - - case "sub": - $y_offset = 0.3 * $height; - break; - - case "super": - $y_offset = -0.2 * $height; - break; - - case "text-top": - case "top": // Not strictly accurate, but good enough for now - break; - - case "text-bottom": - case "bottom": - $y_offset = $height*0.8 - $baseline; - break; - } - - if ( $y_offset ) { - $frame->move(0, $y_offset); - } - } - } - } - - /** - * @param Frame $child - */ - function process_clear(Frame $child){ - $enable_css_float = $this->get_dompdf()->get_option("enable_css_float"); - if ( !$enable_css_float ) { - return; - } - - $child_style = $child->get_style(); - $root = $this->_frame->get_root(); - - // Handle "clear" - if ( $child_style->clear !== "none" ) { - $lowest_y = $root->get_lowest_float_offset($child); - - // If a float is still applying, we handle it - if ( $lowest_y ) { - if ( $child->is_in_flow() ) { - $line_box = $this->_frame->get_current_line_box(); - $line_box->y = $lowest_y + $child->get_margin_height(); - $line_box->left = 0; - $line_box->right = 0; - } - - $child->move(0, $lowest_y - $child->get_position("y")); - } - } - } - - /** - * @param Frame $child - * @param float $cb_x - * @param float $cb_w - */ - function process_float(Frame $child, $cb_x, $cb_w){ - $enable_css_float = $this->_frame->get_dompdf()->get_option("enable_css_float"); - if ( !$enable_css_float ) { - return; - } - - $child_style = $child->get_style(); - $root = $this->_frame->get_root(); - - // Handle "float" - if ( $child_style->float !== "none" ) { - $root->add_floating_frame($child); - - // Remove next frame's beginning whitespace - $next = $child->get_next_sibling(); - if ( $next && $next instanceof Text_Frame_Decorator) { - $next->set_text(ltrim($next->get_text())); - } - - $line_box = $this->_frame->get_current_line_box(); - list($old_x, $old_y) = $child->get_position(); - - $float_x = $cb_x; - $float_y = $old_y; - $float_w = $child->get_margin_width(); - - if ( $child_style->clear === "none" ) { - switch( $child_style->float ) { - case "left": - $float_x += $line_box->left; - break; - case "right": - $float_x += ($cb_w - $line_box->right - $float_w); - break; - } - } - else { - if ( $child_style->float === "right" ) { - $float_x += ($cb_w - $float_w); - } - } - - if ( $cb_w < $float_x + $float_w - $old_x ) { - // TODO handle when floating elements don't fit - } - - $line_box->get_float_offsets(); - - if ( $child->_float_next_line ) { - $float_y += $line_box->h; - } - - $child->set_position($float_x, $float_y); - $child->move($float_x - $old_x, $float_y - $old_y, true); - } - } - - /** - * @param Frame_Decorator $block - */ - function reflow(Block_Frame_Decorator $block = null) { - - // Check if a page break is forced - $page = $this->_frame->get_root(); - $page->check_forced_page_break($this->_frame); - - // Bail if the page is full - if ( $page->is_full() ) { - return; - } - - // Generated content - $this->_set_content(); - - // Collapse margins if required - $this->_collapse_margins(); - - $style = $this->_frame->get_style(); - $cb = $this->_frame->get_containing_block(); - - if ( $style->position === "fixed" ) { - $cb = $this->_frame->get_root()->get_containing_block(); - } - - // Determine the constraints imposed by this frame: calculate the width - // of the content area: - list($w, $left_margin, $right_margin, $left, $right) = $this->_calculate_restricted_width(); - - // Store the calculated properties - $style->width = $w . "pt"; - $style->margin_left = $left_margin."pt"; - $style->margin_right = $right_margin."pt"; - $style->left = $left ."pt"; - $style->right = $right . "pt"; - - // Update the position - $this->_frame->position(); - list($x, $y) = $this->_frame->get_position(); - - // Adjust the first line based on the text-indent property - $indent = $style->length_in_pt($style->text_indent, $cb["w"]); - $this->_frame->increase_line_width($indent); - - // Determine the content edge - $top = $style->length_in_pt(array($style->margin_top, - $style->padding_top, - $style->border_top_width), $cb["h"]); - - $bottom = $style->length_in_pt(array($style->border_bottom_width, - $style->margin_bottom, - $style->padding_bottom), $cb["h"]); - - $cb_x = $x + $left_margin + $style->length_in_pt(array($style->border_left_width, - $style->padding_left), $cb["w"]); - - $cb_y = $y + $top; - - $cb_h = ($cb["h"] + $cb["y"]) - $bottom - $cb_y; - - // Set the y position of the first line in this block - $line_box = $this->_frame->get_current_line_box(); - $line_box->y = $cb_y; - $line_box->get_float_offsets(); - - // Set the containing blocks and reflow each child - foreach ( $this->_frame->get_children() as $child ) { - - // Bail out if the page is full - if ( $page->is_full() ) { - break; - } - - $child->set_containing_block($cb_x, $cb_y, $w, $cb_h); - - $this->process_clear($child); - - $child->reflow($this->_frame); - - // Don't add the child to the line if a page break has occurred - if ( $page->check_page_break($child) ) { - break; - } - - $this->process_float($child, $cb_x, $w); - } - - // Determine our height - list($height, $margin_top, $margin_bottom, $top, $bottom) = $this->_calculate_restricted_height(); - $style->height = $height; - $style->margin_top = $margin_top; - $style->margin_bottom = $margin_bottom; - $style->top = $top; - $style->bottom = $bottom; - - $needs_reposition = ($style->position === "absolute" && ($style->right !== "auto" || $style->bottom !== "auto")); - - // Absolute positioning measurement - if ( $needs_reposition ) { - $orig_style = $this->_frame->get_original_style(); - if ( $orig_style->width === "auto" && ($orig_style->left === "auto" || $orig_style->right === "auto") ) { - $width = 0; - foreach ($this->_frame->get_line_boxes() as $line) { - $width = max($line->w, $width); - } - $style->width = $width; - } - - $style->left = $orig_style->left; - $style->right = $orig_style->right; - } - - $this->_text_align(); - $this->vertical_align(); - - // Absolute positioning - if ( $needs_reposition ) { - list($x, $y) = $this->_frame->get_position(); - $this->_frame->position(); - list($new_x, $new_y) = $this->_frame->get_position(); - $this->_frame->move($new_x-$x, $new_y-$y, true); - } - - if ( $block && $this->_frame->is_in_flow() ) { - $block->add_frame_to_line($this->_frame); - - // May be inline-block - if ( $style->display === "block" ) { - $block->add_line(); - } - } - } -} diff --git a/application/helpers/dompdf/include/block_positioner.cls.php b/application/helpers/dompdf/include/block_positioner.cls.php deleted file mode 100755 index d7e1c3fbc..000000000 --- a/application/helpers/dompdf/include/block_positioner.cls.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Positions block frames - * - * @access private - * @package dompdf - */ -class Block_Positioner extends Positioner { - - - function __construct(Frame_Decorator $frame) { parent::__construct($frame); } - - //........................................................................ - - function position() { - $frame = $this->_frame; - $style = $frame->get_style(); - $cb = $frame->get_containing_block(); - $p = $frame->find_block_parent(); - - if ( $p ) { - $float = $style->float; - - $enable_css_float = $frame->get_dompdf()->get_option("enable_css_float"); - if ( !$enable_css_float || !$float || $float === "none" ) { - $p->add_line(true); - } - $y = $p->get_current_line_box()->y; - - } - else { - $y = $cb["y"]; - } - - $x = $cb["x"]; - - // Relative positionning - if ( $style->position === "relative" ) { - $top = $style->length_in_pt($style->top, $cb["h"]); - //$right = $style->length_in_pt($style->right, $cb["w"]); - //$bottom = $style->length_in_pt($style->bottom, $cb["h"]); - $left = $style->length_in_pt($style->left, $cb["w"]); - - $x += $left; - $y += $top; - } - - $frame->set_position($x, $y); - } -} diff --git a/application/helpers/dompdf/include/block_renderer.cls.php b/application/helpers/dompdf/include/block_renderer.cls.php deleted file mode 100755 index ef42c93d5..000000000 --- a/application/helpers/dompdf/include/block_renderer.cls.php +++ /dev/null @@ -1,230 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Renders block frames - * - * @access private - * @package dompdf - */ -class Block_Renderer extends Abstract_Renderer { - - //........................................................................ - - function render(Frame $frame) { - $style = $frame->get_style(); - $node = $frame->get_node(); - - list($x, $y, $w, $h) = $frame->get_border_box(); - - $this->_set_opacity( $frame->get_opacity( $style->opacity ) ); - - if ( $node->nodeName === "body" ) { - $h = $frame->get_containing_block("h") - $style->length_in_pt(array( - $style->margin_top, - $style->border_top_width, - $style->border_bottom_width, - $style->margin_bottom), - $style->width); - } - - // Handle anchors & links - if ( $node->nodeName === "a" && $href = $node->getAttribute("href") ) { - $this->_canvas->add_link($href, $x, $y, $w, $h); - } - - // Draw our background, border and content - list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); - - if ( $tl + $tr + $br + $bl > 0 ) { - $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl ); - } - - if ( ($bg = $style->background_color) !== "transparent" ) { - $this->_canvas->filled_rectangle( $x, $y, $w, $h, $bg ); - } - - if ( ($url = $style->background_image) && $url !== "none" ) { - $this->_background_image($url, $x, $y, $w, $h, $style); - } - - if ( $tl + $tr + $br + $bl > 0 ) { - $this->_canvas->clipping_end(); - } - - $border_box = array($x, $y, $w, $h); - $this->_render_border($frame, $border_box); - $this->_render_outline($frame, $border_box); - - if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) { - $this->_debug_layout($frame->get_border_box(), "red"); - if (DEBUG_LAYOUT_PADDINGBOX) { - $this->_debug_layout($frame->get_padding_box(), "red", array(0.5, 0.5)); - } - } - - if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES && $frame->get_decorator()) { - foreach ($frame->get_decorator()->get_line_boxes() as $line) { - $frame->_debug_layout(array($line->x, $line->y, $line->w, $line->h), "orange"); - } - } - } - - protected function _render_border(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") { - $style = $frame->get_style(); - $bp = $style->get_border_properties(); - - if ( empty($border_box) ) { - $border_box = $frame->get_border_box(); - } - - // find the radius - $radius = $style->get_computed_border_radius($border_box[2], $border_box[3]); // w, h - - // Short-cut: If all the borders are "solid" with the same color and style, and no radius, we'd better draw a rectangle - if ( - in_array($bp["top"]["style"], array("solid", "dashed", "dotted")) && - $bp["top"] == $bp["right"] && - $bp["right"] == $bp["bottom"] && - $bp["bottom"] == $bp["left"] && - array_sum($radius) == 0 - ) { - $props = $bp["top"]; - if ( $props["color"] === "transparent" || $props["width"] <= 0 ) return; - - list($x, $y, $w, $h) = $border_box; - $width = $style->length_in_pt($props["width"]); - $pattern = $this->_get_dash_pattern($props["style"], $width); - $this->_canvas->rectangle($x + $width / 2, $y + $width / 2, $w - $width, $h - $width, $props["color"], $width, $pattern); - return; - } - - // Do it the long way - $widths = array($style->length_in_pt($bp["top"]["width"]), - $style->length_in_pt($bp["right"]["width"]), - $style->length_in_pt($bp["bottom"]["width"]), - $style->length_in_pt($bp["left"]["width"])); - - foreach ($bp as $side => $props) { - list($x, $y, $w, $h) = $border_box; - $length = 0; - $r1 = 0; - $r2 = 0; - - if ( !$props["style"] || - $props["style"] === "none" || - $props["width"] <= 0 || - $props["color"] == "transparent" ) - continue; - - switch($side) { - case "top": - $length = $w; - $r1 = $radius["top-left"]; - $r2 = $radius["top-right"]; - break; - - case "bottom": - $length = $w; - $y += $h; - $r1 = $radius["bottom-left"]; - $r2 = $radius["bottom-right"]; - break; - - case "left": - $length = $h; - $r1 = $radius["top-left"]; - $r2 = $radius["bottom-left"]; - break; - - case "right": - $length = $h; - $x += $w; - $r1 = $radius["top-right"]; - $r2 = $radius["bottom-right"]; - break; - default: - break; - } - $method = "_border_" . $props["style"]; - - // draw rounded corners - $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style, $r1, $r2); - } - } - - protected function _render_outline(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") { - $style = $frame->get_style(); - - $props = array( - "width" => $style->outline_width, - "style" => $style->outline_style, - "color" => $style->outline_color, - ); - - if ( !$props["style"] || $props["style"] === "none" || $props["width"] <= 0 ) - return; - - if ( empty($border_box) ) { - $border_box = $frame->get_border_box(); - } - - $offset = $style->length_in_pt($props["width"]); - $pattern = $this->_get_dash_pattern($props["style"], $offset); - - // If the outline style is "solid" we'd better draw a rectangle - if ( in_array($props["style"], array("solid", "dashed", "dotted")) ) { - $border_box[0] -= $offset / 2; - $border_box[1] -= $offset / 2; - $border_box[2] += $offset; - $border_box[3] += $offset; - - list($x, $y, $w, $h) = $border_box; - $this->_canvas->rectangle($x, $y, $w, $h, $props["color"], $offset, $pattern); - return; - } - - $border_box[0] -= $offset; - $border_box[1] -= $offset; - $border_box[2] += $offset * 2; - $border_box[3] += $offset * 2; - - $method = "_border_" . $props["style"]; - $widths = array_fill(0, 4, $props["width"]); - $sides = array("top", "right", "left", "bottom"); - $length = 0; - - foreach ($sides as $side) { - list($x, $y, $w, $h) = $border_box; - - switch($side) { - case "top": - $length = $w; - break; - - case "bottom": - $length = $w; - $y += $h; - break; - - case "left": - $length = $h; - break; - - case "right": - $length = $h; - $x += $w; - break; - default: - break; - } - - $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style); - } - } -} diff --git a/application/helpers/dompdf/include/cached_pdf_decorator.cls.php b/application/helpers/dompdf/include/cached_pdf_decorator.cls.php deleted file mode 100755 index 519e572e8..000000000 --- a/application/helpers/dompdf/include/cached_pdf_decorator.cls.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Caching canvas implementation - * - * Each rendered page is serialized and stored in the {@link Page_Cache}. - * This is useful for static forms/pages that do not need to be re-rendered - * all the time. - * - * This class decorates normal CPDF_Adapters. It is currently completely - * experimental. - * - * @access private - * @package dompdf - */ -class Cached_PDF_Decorator extends CPDF_Adapter implements Canvas { - /** - * @var CPDF_Adapter - */ - protected $_pdf; - protected $_cache_id; - protected $_current_page_id; - protected $_fonts; // fonts used in this document - - function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf) { - $this->_fonts = array(); - } - - /** - * Must be called after constructor - * - * @param int $cache_id - * @param CPDF_Adapter $pdf - */ - function init($cache_id, CPDF_Adapter $pdf) { - $this->_cache_id = $cache_id; - $this->_pdf = $pdf; - $this->_current_page_id = $this->_pdf->open_object(); - } - - //........................................................................ - - function get_cpdf() { return $this->_pdf->get_cpdf(); } - - function open_object() { $this->_pdf->open_object(); } - function reopen_object($object) { $this->_pdf->reopen_object($object); } - - function close_object() { $this->_pdf->close_object(); } - - function add_object($object, $where = 'all') { $this->_pdf->add_object($object, $where); } - - function serialize_object($id) { $this->_pdf->serialize_object($id); } - - function reopen_serialized_object($obj) { $this->_pdf->reopen_serialized_object($obj); } - - //........................................................................ - - function get_width() { return $this->_pdf->get_width(); } - function get_height() { return $this->_pdf->get_height(); } - function get_page_number() { return $this->_pdf->get_page_number(); } - function get_page_count() { return $this->_pdf->get_page_count(); } - - function set_page_number($num) { $this->_pdf->set_page_number($num); } - function set_page_count($count) { $this->_pdf->set_page_count($count); } - - function line($x1, $y1, $x2, $y2, $color, $width, $style = array()) { - $this->_pdf->line($x1, $y1, $x2, $y2, $color, $width, $style); - } - - function rectangle($x1, $y1, $w, $h, $color, $width, $style = array()) { - $this->_pdf->rectangle($x1, $y1, $w, $h, $color, $width, $style); - } - - function filled_rectangle($x1, $y1, $w, $h, $color) { - $this->_pdf->filled_rectangle($x1, $y1, $w, $h, $color); - } - - function polygon($points, $color, $width = null, $style = array(), $fill = false) { - $this->_pdf->polygon($points, $color, $width, $style, $fill); - } - - function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false) { - $this->_pdf->circle($x, $y, $r1, $color, $width, $style, $fill); - } - - function image($img_url, $x, $y, $w, $h, $resolution = "normal") { - $this->_pdf->image($img_url, $x, $y, $w, $h, $resolution); - } - - function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) { - $this->_fonts[$font] = true; - $this->_pdf->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle); - } - - function page_text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) { - - // We want to remove this from cached pages since it may not be correct - $this->_pdf->close_object(); - $this->_pdf->page_text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle); - $this->_pdf->reopen_object($this->_current_page_id); - } - - function page_script($script, $type = 'text/php') { - - // We want to remove this from cached pages since it may not be correct - $this->_pdf->close_object(); - $this->_pdf->page_script($script, $type); - $this->_pdf->reopen_object($this->_current_page_id); - } - - function new_page() { - $this->_pdf->close_object(); - - // Add the object to the current page - $this->_pdf->add_object($this->_current_page_id, "add"); - $this->_pdf->new_page(); - - Page_Cache::store_page($this->_cache_id, - $this->_pdf->get_page_number() - 1, - $this->_pdf->serialize_object($this->_current_page_id)); - - $this->_current_page_id = $this->_pdf->open_object(); - return $this->_current_page_id; - } - - function stream($filename, $options = null) { - // Store the last page in the page cache - if ( !is_null($this->_current_page_id) ) { - $this->_pdf->close_object(); - $this->_pdf->add_object($this->_current_page_id, "add"); - Page_Cache::store_page($this->_cache_id, - $this->_pdf->get_page_number(), - $this->_pdf->serialize_object($this->_current_page_id)); - Page_Cache::store_fonts($this->_cache_id, $this->_fonts); - $this->_current_page_id = null; - } - - $this->_pdf->stream($filename); - - } - - function output($options = null) { - // Store the last page in the page cache - if ( !is_null($this->_current_page_id) ) { - $this->_pdf->close_object(); - $this->_pdf->add_object($this->_current_page_id, "add"); - Page_Cache::store_page($this->_cache_id, - $this->_pdf->get_page_number(), - $this->_pdf->serialize_object($this->_current_page_id)); - $this->_current_page_id = null; - } - - return $this->_pdf->output(); - } - - function get_messages() { return $this->_pdf->get_messages(); } - -} diff --git a/application/helpers/dompdf/include/canvas.cls.php b/application/helpers/dompdf/include/canvas.cls.php deleted file mode 100755 index 0158df6b1..000000000 --- a/application/helpers/dompdf/include/canvas.cls.php +++ /dev/null @@ -1,385 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Main rendering interface - * - * Currently {@link CPDF_Adapter}, {@link PDFLib_Adapter}, {@link TCPDF_Adapter}, and {@link GD_Adapter} - * implement this interface. - * - * Implementations should measure x and y increasing to the left and down, - * respectively, with the origin in the top left corner. Implementations - * are free to use a unit other than points for length, but I can't - * guarantee that the results will look any good. - * - * @package dompdf - */ -interface Canvas { - function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf); - - /** - * @return DOMPDF - */ - function get_dompdf(); - - /** - * Returns the current page number - * - * @return int - */ - function get_page_number(); - - /** - * Returns the total number of pages - * - * @return int - */ - function get_page_count(); - - /** - * Sets the total number of pages - * - * @param int $count - */ - function set_page_count($count); - - /** - * Draws a line from x1,y1 to x2,y2 - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the format of the - * $style parameter (aka dash). - * - * @param float $x1 - * @param float $y1 - * @param float $x2 - * @param float $y2 - * @param array $color - * @param float $width - * @param array $style - */ - function line($x1, $y1, $x2, $y2, $color, $width, $style = null); - - /** - * Draws a rectangle at x1,y1 with width w and height h - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the $style - * parameter (aka dash) - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - * @param array $color - * @param float $width - * @param array $style - */ - function rectangle($x1, $y1, $w, $h, $color, $width, $style = null); - - /** - * Draws a filled rectangle at x1,y1 with width w and height h - * - * See {@link Style::munge_color()} for the format of the color array. - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - * @param array $color - */ - function filled_rectangle($x1, $y1, $w, $h, $color); - - /** - * Starts a clipping rectangle at x1,y1 with width w and height h - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - */ - function clipping_rectangle($x1, $y1, $w, $h); - - /** - * Starts a rounded clipping rectangle at x1,y1 with width w and height h - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - * @param float $tl - * @param float $tr - * @param float $br - * @param float $bl - * - * @return - */ - function clipping_roundrectangle($x1, $y1, $w, $h, $tl, $tr, $br, $bl); - - /** - * Ends the last clipping shape - */ - function clipping_end(); - - /** - * Save current state - */ - function save(); - - /** - * Restore last state - */ - function restore(); - - /** - * Rotate - */ - function rotate($angle, $x, $y); - - /** - * Skew - */ - function skew($angle_x, $angle_y, $x, $y); - - /** - * Scale - */ - function scale($s_x, $s_y, $x, $y); - - /** - * Translate - */ - function translate($t_x, $t_y); - - /** - * Transform - */ - function transform($a, $b, $c, $d, $e, $f); - - /** - * Draws a polygon - * - * The polygon is formed by joining all the points stored in the $points - * array. $points has the following structure: - * - * array(0 => x1, - * 1 => y1, - * 2 => x2, - * 3 => y2, - * ... - * ); - * - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the $style - * parameter (aka dash) - * - * @param array $points - * @param array $color - * @param float $width - * @param array $style - * @param bool $fill Fills the polygon if true - */ - function polygon($points, $color, $width = null, $style = null, $fill = false); - - /** - * Draws a circle at $x,$y with radius $r - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the $style - * parameter (aka dash) - * - * @param float $x - * @param float $y - * @param float $r - * @param array $color - * @param float $width - * @param array $style - * @param bool $fill Fills the circle if true - */ - function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false); - - /** - * Add an image to the pdf. - * - * The image is placed at the specified x and y coordinates with the - * given width and height. - * - * @param string $img_url the path to the image - * @param float $x x position - * @param float $y y position - * @param int $w width (in pixels) - * @param int $h height (in pixels) - * @param string $resolution The resolution of the image - */ - function image($img_url, $x, $y, $w, $h, $resolution = "normal"); - - /** - * Add an arc to the PDF - * See {@link Style::munge_color()} for the format of the color array. - * - * @param float $x X coordinate of the arc - * @param float $y Y coordinate of the arc - * @param float $r1 Radius 1 - * @param float $r2 Radius 2 - * @param float $astart Start angle in degrees - * @param float $aend End angle in degrees - * @param array $color Color - * @param float $width - * @param array $style - * - * @return void - */ - function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array()); - - /** - * Writes text at the specified x and y coordinates - * See {@link Style::munge_color()} for the format of the color array. - * - * @param float $x - * @param float $y - * @param string $text the text to write - * @param string $font the font file to use - * @param float $size the font size, in points - * @param array $color - * @param float $word_space word spacing adjustment - * @param float $char_space char spacing adjustment - * @param float $angle angle - * - * @return void - */ - function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0); - - /** - * Add a named destination (similar to ... in html) - * - * @param string $anchorname The name of the named destination - */ - function add_named_dest($anchorname); - - /** - * Add a link to the pdf - * - * @param string $url The url to link to - * @param float $x The x position of the link - * @param float $y The y position of the link - * @param float $width The width of the link - * @param float $height The height of the link - * - * @return void - */ - function add_link($url, $x, $y, $width, $height); - - /** - * Add meta information to the pdf - * - * @param string $name Label of the value (Creator, Producer, etc.) - * @param string $value The text to set - */ - function add_info($name, $value); - - /** - * Calculates text size, in points - * - * @param string $text the text to be sized - * @param string $font the desired font - * @param float $size the desired font size - * @param float $word_spacing word spacing, if any - * @param float $char_spacing - * - * @return float - */ - function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0); - - /** - * Calculates font height, in points - * - * @param string $font - * @param float $size - * - * @return float - */ - function get_font_height($font, $size); - - /** - * Calculates font baseline, in points - * - * @param string $font - * @param float $size - * - * @return float - */ - function get_font_baseline($font, $size); - - /** - * Returns the font x-height, in points - * - * @param string $font - * @param float $size - * - * @return float - */ - //function get_font_x_height($font, $size); - - /** - * Sets the opacity - * - * @param float $opacity - * @param string $mode - */ - function set_opacity($opacity, $mode = "Normal"); - - /** - * Sets the default view - * - * @param string $view - * 'XYZ' left, top, zoom - * 'Fit' - * 'FitH' top - * 'FitV' left - * 'FitR' left,bottom,right - * 'FitB' - * 'FitBH' top - * 'FitBV' left - * @param array $options - * - * @return void - */ - function set_default_view($view, $options = array()); - - /** - * @param string $script - * - * @return void - */ - function javascript($script); - - /** - * Starts a new page - * - * Subsequent drawing operations will appear on the new page. - */ - function new_page(); - - /** - * Streams the PDF directly to the browser - * - * @param string $filename the name of the PDF file - * @param array $options associative array, 'Attachment' => 0 or 1, 'compress' => 1 or 0 - */ - function stream($filename, $options = null); - - /** - * Returns the PDF as a string - * - * @param array $options associative array: 'compress' => 1 or 0 - * @return string - */ - function output($options = null); -} diff --git a/application/helpers/dompdf/include/canvas_factory.cls.php b/application/helpers/dompdf/include/canvas_factory.cls.php deleted file mode 100755 index ef634e6b0..000000000 --- a/application/helpers/dompdf/include/canvas_factory.cls.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Create canvas instances - * - * The canvas factory creates canvas instances based on the - * availability of rendering backends and config options. - * - * @package dompdf - */ -class Canvas_Factory { - - /** - * Constructor is private: this is a static class - */ - private function __construct() { } - - /** - * @param DOMPDF $dompdf - * @param string|array $paper - * @param string $orientation - * @param string $class - * - * @return Canvas - */ - static function get_instance(DOMPDF $dompdf, $paper = null, $orientation = null, $class = null) { - - $backend = strtolower(DOMPDF_PDF_BACKEND); - - if ( isset($class) && class_exists($class, false) ) { - $class .= "_Adapter"; - } - - else if ( (DOMPDF_PDF_BACKEND === "auto" || $backend === "pdflib" ) && - class_exists("PDFLib", false) ) { - $class = "PDFLib_Adapter"; - } - - // FIXME The TCPDF adapter is not ready yet - //else if ( (DOMPDF_PDF_BACKEND === "auto" || $backend === "cpdf") ) - // $class = "CPDF_Adapter"; - - else if ( $backend === "tcpdf" ) { - $class = "TCPDF_Adapter"; - } - - else if ( $backend === "gd" ) { - $class = "GD_Adapter"; - } - - else { - $class = "CPDF_Adapter"; - } - - return new $class($paper, $orientation, $dompdf); - } -} diff --git a/application/helpers/dompdf/include/cellmap.cls.php b/application/helpers/dompdf/include/cellmap.cls.php deleted file mode 100755 index 0982849b3..000000000 --- a/application/helpers/dompdf/include/cellmap.cls.php +++ /dev/null @@ -1,790 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Maps table cells to the table grid. - * - * This class resolves borders in tables with collapsed borders and helps - * place row & column spanned table cells. - * - * @access private - * @package dompdf - */ -class Cellmap { - - /** - * Border style weight lookup for collapsed border resolution. - * - * @var array - */ - static protected $_BORDER_STYLE_SCORE = array( - "inset" => 1, - "groove" => 2, - "outset" => 3, - "ridge" => 4, - "dotted" => 5, - "dashed" => 6, - "solid" => 7, - "double" => 8, - "hidden" => 9, - "none" => 0, - ); - - /** - * The table object this cellmap is attached to. - * - * @var Table_Frame_Decorator - */ - protected $_table; - - /** - * The total number of rows in the table - * - * @var int - */ - protected $_num_rows; - - /** - * The total number of columns in the table - * - * @var int - */ - protected $_num_cols; - - /** - * 2D array mapping to frames - * - * @var Frame[][] - */ - protected $_cells; - - /** - * 1D array of column dimensions - * - * @var array - */ - protected $_columns; - - /** - * 1D array of row dimensions - * - * @var array - */ - protected $_rows; - - /** - * 2D array of border specs - * - * @var array - */ - protected $_borders; - - /** - * 1D Array mapping frames to (multiple) pairs, keyed on frame_id. - * - * @var Frame[] - */ - protected $_frames; - - /** - * Current column when adding cells, 0-based - * - * @var int - */ - private $__col; - - /** - * Current row when adding cells, 0-based - * - * @var int - */ - private $__row; - - /** - * Tells wether the columns' width can be modified - * - * @var bool - */ - private $_columns_locked = false; - - /** - * Tells wether the table has table-layout:fixed - * - * @var bool - */ - private $_fixed_layout = false; - - //........................................................................ - - function __construct(Table_Frame_Decorator $table) { - $this->_table = $table; - $this->reset(); - } - - function __destruct() { - clear_object($this); - } - //........................................................................ - - function reset() { - $this->_num_rows = 0; - $this->_num_cols = 0; - - $this->_cells = array(); - $this->_frames = array(); - - if ( !$this->_columns_locked ) { - $this->_columns = array(); - } - - $this->_rows = array(); - - $this->_borders = array(); - - $this->__col = $this->__row = 0; - } - - //........................................................................ - - function lock_columns() { - $this->_columns_locked = true; - } - - function is_columns_locked() { - return $this->_columns_locked; - } - - function set_layout_fixed($fixed) { - $this->_fixed_layout = $fixed; - } - - function is_layout_fixed() { - return $this->_fixed_layout; - } - - function get_num_rows() { return $this->_num_rows; } - function get_num_cols() { return $this->_num_cols; } - - function &get_columns() { - return $this->_columns; - } - - function set_columns($columns) { - $this->_columns = $columns; - } - - function &get_column($i) { - if ( !isset($this->_columns[$i]) ) { - $this->_columns[$i] = array( - "x" => 0, - "min-width" => 0, - "max-width" => 0, - "used-width" => null, - "absolute" => 0, - "percent" => 0, - "auto" => true, - ); - } - - return $this->_columns[$i]; - } - - function &get_rows() { - return $this->_rows; - } - - function &get_row($j) { - if ( !isset($this->_rows[$j]) ) { - $this->_rows[$j] = array( - "y" => 0, - "first-column" => 0, - "height" => null, - ); - } - - return $this->_rows[$j]; - } - - function get_border($i, $j, $h_v, $prop = null) { - if ( !isset($this->_borders[$i][$j][$h_v]) ) { - $this->_borders[$i][$j][$h_v] = array( - "width" => 0, - "style" => "solid", - "color" => "black", - ); - } - - if ( isset($prop) ) { - return $this->_borders[$i][$j][$h_v][$prop]; - } - - return $this->_borders[$i][$j][$h_v]; - } - - function get_border_properties($i, $j) { - return array( - "top" => $this->get_border($i, $j, "horizontal"), - "right" => $this->get_border($i, $j+1, "vertical"), - "bottom" => $this->get_border($i+1, $j, "horizontal"), - "left" => $this->get_border($i, $j, "vertical"), - ); - } - - //........................................................................ - - function get_spanned_cells(Frame $frame) { - $key = $frame->get_id(); - - if ( !isset($this->_frames[$key]) ) { - throw new DOMPDF_Exception("Frame not found in cellmap"); - } - - return $this->_frames[$key]; - - } - - function frame_exists_in_cellmap(Frame $frame) { - $key = $frame->get_id(); - return isset($this->_frames[$key]); - } - - function get_frame_position(Frame $frame) { - global $_dompdf_warnings; - - $key = $frame->get_id(); - - if ( !isset($this->_frames[$key]) ) { - throw new DOMPDF_Exception("Frame not found in cellmap"); - } - - $col = $this->_frames[$key]["columns"][0]; - $row = $this->_frames[$key]["rows"][0]; - - if ( !isset($this->_columns[$col])) { - $_dompdf_warnings[] = "Frame not found in columns array. Check your table layout for missing or extra TDs."; - $x = 0; - } - else { - $x = $this->_columns[$col]["x"]; - } - - if ( !isset($this->_rows[$row])) { - $_dompdf_warnings[] = "Frame not found in row array. Check your table layout for missing or extra TDs."; - $y = 0; - } - else { - $y = $this->_rows[$row]["y"]; - } - - return array($x, $y, "x" => $x, "y" => $y); - } - - function get_frame_width(Frame $frame) { - $key = $frame->get_id(); - - if ( !isset($this->_frames[$key]) ) { - throw new DOMPDF_Exception("Frame not found in cellmap"); - } - - $cols = $this->_frames[$key]["columns"]; - $w = 0; - foreach ($cols as $i) { - $w += $this->_columns[$i]["used-width"]; - } - - return $w; - } - - function get_frame_height(Frame $frame) { - $key = $frame->get_id(); - - if ( !isset($this->_frames[$key]) ) { - throw new DOMPDF_Exception("Frame not found in cellmap"); - } - - $rows = $this->_frames[$key]["rows"]; - $h = 0; - foreach ($rows as $i) { - if ( !isset($this->_rows[$i]) ) { - throw new Exception("The row #$i could not be found, please file an issue in the tracker with the HTML code"); - } - - $h += $this->_rows[$i]["height"]; - } - - return $h; - } - - - //........................................................................ - - function set_column_width($j, $width) { - if ( $this->_columns_locked ) { - return; - } - - $col =& $this->get_column($j); - $col["used-width"] = $width; - $next_col =& $this->get_column($j+1); - $next_col["x"] = $next_col["x"] + $width; - } - - function set_row_height($i, $height) { - $row =& $this->get_row($i); - - if ( $row["height"] !== null && $height <= $row["height"] ) { - return; - } - - $row["height"] = $height; - $next_row =& $this->get_row($i+1); - $next_row["y"] = $row["y"] + $height; - - } - - //........................................................................ - - - protected function _resolve_border($i, $j, $h_v, $border_spec) { - $n_width = $border_spec["width"]; - $n_style = $border_spec["style"]; - - if ( !isset($this->_borders[$i][$j][$h_v]) ) { - $this->_borders[$i][$j][$h_v] = $border_spec; - return $this->_borders[$i][$j][$h_v]["width"]; - } - - $border = &$this->_borders[$i][$j][$h_v]; - - $o_width = $border["width"]; - $o_style = $border["style"]; - - if ( ($n_style === "hidden" || - $n_width > $o_width || - $o_style === "none") - - or - - ($o_width == $n_width && - in_array($n_style, self::$_BORDER_STYLE_SCORE) && - self::$_BORDER_STYLE_SCORE[ $n_style ] > self::$_BORDER_STYLE_SCORE[ $o_style ]) ) { - $border = $border_spec; - } - - return $border["width"]; - } - - //........................................................................ - - function add_frame(Frame $frame) { - - $style = $frame->get_style(); - $display = $style->display; - - $collapse = $this->_table->get_style()->border_collapse == "collapse"; - - // Recursively add the frames within tables, table-row-groups and table-rows - if ( $display === "table-row" || - $display === "table" || - $display === "inline-table" || - in_array($display, Table_Frame_Decorator::$ROW_GROUPS) ) { - - $start_row = $this->__row; - foreach ( $frame->get_children() as $child ) { - $this->add_frame( $child ); - } - - if ( $display === "table-row" ) { - $this->add_row(); - } - - $num_rows = $this->__row - $start_row - 1; - $key = $frame->get_id(); - - // Row groups always span across the entire table - $this->_frames[$key]["columns"] = range(0,max(0,$this->_num_cols-1)); - $this->_frames[$key]["rows"] = range($start_row, max(0, $this->__row - 1)); - $this->_frames[$key]["frame"] = $frame; - - if ( $display !== "table-row" && $collapse ) { - - $bp = $style->get_border_properties(); - - // Resolve the borders - for ( $i = 0; $i < $num_rows+1; $i++) { - $this->_resolve_border($start_row + $i, 0, "vertical", $bp["left"]); - $this->_resolve_border($start_row + $i, $this->_num_cols, "vertical", $bp["right"]); - } - - for ( $j = 0; $j < $this->_num_cols; $j++) { - $this->_resolve_border($start_row, $j, "horizontal", $bp["top"]); - $this->_resolve_border($this->__row, $j, "horizontal", $bp["bottom"]); - } - } - - - return; - } - - $node = $frame->get_node(); - - // Determine where this cell is going - $colspan = $node->getAttribute("colspan"); - $rowspan = $node->getAttribute("rowspan"); - - if ( !$colspan ) { - $colspan = 1; - $node->setAttribute("colspan",1); - } - - if ( !$rowspan ) { - $rowspan = 1; - $node->setAttribute("rowspan",1); - } - $key = $frame->get_id(); - - $bp = $style->get_border_properties(); - - - // Add the frame to the cellmap - $max_left = $max_right = 0; - - // Find the next available column (fix by Ciro Mondueri) - $ac = $this->__col; - while ( isset($this->_cells[$this->__row][$ac]) ) { - $ac++; - } - - $this->__col = $ac; - - // Rows: - for ( $i = 0; $i < $rowspan; $i++ ) { - $row = $this->__row + $i; - - $this->_frames[$key]["rows"][] = $row; - - for ( $j = 0; $j < $colspan; $j++) { - $this->_cells[$row][$this->__col + $j] = $frame; - } - - if ( $collapse ) { - // Resolve vertical borders - $max_left = max($max_left, $this->_resolve_border($row, $this->__col, "vertical", $bp["left"])); - $max_right = max($max_right, $this->_resolve_border($row, $this->__col + $colspan, "vertical", $bp["right"])); - } - } - - $max_top = $max_bottom = 0; - - // Columns: - for ( $j = 0; $j < $colspan; $j++ ) { - $col = $this->__col + $j; - $this->_frames[$key]["columns"][] = $col; - - if ( $collapse ) { - // Resolve horizontal borders - $max_top = max($max_top, $this->_resolve_border($this->__row, $col, "horizontal", $bp["top"])); - $max_bottom = max($max_bottom, $this->_resolve_border($this->__row + $rowspan, $col, "horizontal", $bp["bottom"])); - } - } - - $this->_frames[$key]["frame"] = $frame; - - // Handle seperated border model - if ( !$collapse ) { - list($h, $v) = $this->_table->get_style()->border_spacing; - - // Border spacing is effectively a margin between cells - $v = $style->length_in_pt($v) / 2; - $h = $style->length_in_pt($h) / 2; - $style->margin = "$v $h"; - - // The additional 1/2 width gets added to the table proper - } - else { - // Drop the frame's actual border - $style->border_left_width = $max_left / 2; - $style->border_right_width = $max_right / 2; - $style->border_top_width = $max_top / 2; - $style->border_bottom_width = $max_bottom / 2; - $style->margin = "none"; - } - - if ( !$this->_columns_locked ) { - // Resolve the frame's width - if ( $this->_fixed_layout ) { - list($frame_min, $frame_max) = array(0, 10e-10); - } - else { - list($frame_min, $frame_max) = $frame->get_min_max_width(); - } - - $width = $style->width; - - $val = null; - if ( is_percent($width) ) { - $var = "percent"; - $val = (float)rtrim($width, "% ") / $colspan; - } - else if ( $width !== "auto" ) { - $var = "absolute"; - $val = $style->length_in_pt($frame_min) / $colspan; - } - - $min = 0; - $max = 0; - for ( $cs = 0; $cs < $colspan; $cs++ ) { - - // Resolve the frame's width(s) with other cells - $col =& $this->get_column( $this->__col + $cs ); - - // Note: $var is either 'percent' or 'absolute'. We compare the - // requested percentage or absolute values with the existing widths - // and adjust accordingly. - if ( isset($var) && $val > $col[$var] ) { - $col[$var] = $val; - $col["auto"] = false; - } - - $min += $col["min-width"]; - $max += $col["max-width"]; - } - - if ( $frame_min > $min ) { - // The frame needs more space. Expand each sub-column - // FIXME try to avoid putting this dummy value when table-layout:fixed - $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_min - $min) / $colspan); - for ($c = 0; $c < $colspan; $c++) { - $col =& $this->get_column($this->__col + $c); - $col["min-width"] += $inc; - } - } - - if ( $frame_max > $max ) { - // FIXME try to avoid putting this dummy value when table-layout:fixed - $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_max - $max) / $colspan); - for ($c = 0; $c < $colspan; $c++) { - $col =& $this->get_column($this->__col + $c); - $col["max-width"] += $inc; - } - } - } - - $this->__col += $colspan; - if ( $this->__col > $this->_num_cols ) - $this->_num_cols = $this->__col; - - } - - //........................................................................ - - function add_row() { - - $this->__row++; - $this->_num_rows++; - - // Find the next available column - $i = 0; - while ( isset($this->_cells[$this->__row][$i]) ) { - $i++; - } - - $this->__col = $i; - - } - - //........................................................................ - - /** - * Remove a row from the cellmap. - * - * @param Frame - */ - function remove_row(Frame $row) { - - $key = $row->get_id(); - if ( !isset($this->_frames[$key]) ) { - return; // Presumably this row has alredy been removed - } - - $this->_row = $this->_num_rows--; - - $rows = $this->_frames[$key]["rows"]; - $columns = $this->_frames[$key]["columns"]; - - // Remove all frames from this row - foreach ( $rows as $r ) { - foreach ( $columns as $c ) { - if ( isset($this->_cells[$r][$c]) ) { - $id = $this->_cells[$r][$c]->get_id(); - - $this->_frames[$id] = null; - unset($this->_frames[$id]); - - $this->_cells[$r][$c] = null; - unset($this->_cells[$r][$c]); - } - } - - $this->_rows[$r] = null; - unset($this->_rows[$r]); - } - - $this->_frames[$key] = null; - unset($this->_frames[$key]); - - } - - /** - * Remove a row group from the cellmap. - * - * @param Frame $group The group to remove - */ - function remove_row_group(Frame $group) { - - $key = $group->get_id(); - if ( !isset($this->_frames[$key]) ) { - return; // Presumably this row has alredy been removed - } - - $iter = $group->get_first_child(); - while ($iter) { - $this->remove_row($iter); - $iter = $iter->get_next_sibling(); - } - - $this->_frames[$key] = null; - unset($this->_frames[$key]); - } - - /** - * Update a row group after rows have been removed - * - * @param Frame $group The group to update - * @param Frame $last_row The last row in the row group - */ - function update_row_group(Frame $group, Frame $last_row) { - - $g_key = $group->get_id(); - $r_key = $last_row->get_id(); - - $r_rows = $this->_frames[$r_key]["rows"]; - $this->_frames[$g_key]["rows"] = range( $this->_frames[$g_key]["rows"][0], end($r_rows) ); - - } - - //........................................................................ - - function assign_x_positions() { - // Pre-condition: widths must be resolved and assigned to columns and - // column[0]["x"] must be set. - - if ( $this->_columns_locked ) { - return; - } - - $x = $this->_columns[0]["x"]; - foreach ( array_keys($this->_columns) as $j ) { - $this->_columns[$j]["x"] = $x; - $x += $this->_columns[$j]["used-width"]; - } - - } - - function assign_frame_heights() { - // Pre-condition: widths and heights of each column & row must be - // calcluated - - foreach ( $this->_frames as $arr ) { - $frame = $arr["frame"]; - - $h = 0; - foreach( $arr["rows"] as $row ) { - if ( !isset($this->_rows[$row]) ) { - // The row has been removed because of a page split, so skip it. - continue; - } - - $h += $this->_rows[$row]["height"]; - } - - if ( $frame instanceof Table_Cell_Frame_Decorator ) { - $frame->set_cell_height($h); - } - else { - $frame->get_style()->height = $h; - } - } - - } - - //........................................................................ - - /** - * Re-adjust frame height if the table height is larger than its content - */ - function set_frame_heights($table_height, $content_height) { - - - // Distribute the increased height proportionally amongst each row - foreach ( $this->_frames as $arr ) { - $frame = $arr["frame"]; - - $h = 0; - foreach ($arr["rows"] as $row ) { - if ( !isset($this->_rows[$row]) ) { - continue; - } - - $h += $this->_rows[$row]["height"]; - } - - if ( $content_height > 0 ) { - $new_height = ($h / $content_height) * $table_height; - } - else { - $new_height = 0; - } - - if ( $frame instanceof Table_Cell_Frame_Decorator ) { - $frame->set_cell_height($new_height); - } - else { - $frame->get_style()->height = $new_height; - } - } - - } - - //........................................................................ - - // Used for debugging: - function __toString() { - $str = ""; - $str .= "Columns:
"; - $str .= pre_r($this->_columns, true); - $str .= "Rows:
"; - $str .= pre_r($this->_rows, true); - - $str .= "Frames:
"; - $arr = array(); - foreach ( $this->_frames as $key => $val ) { - $arr[$key] = array("columns" => $val["columns"], "rows" => $val["rows"]); - } - - $str .= pre_r($arr, true); - - if ( php_sapi_name() == "cli" ) { - $str = strip_tags(str_replace(array("
","",""), - array("\n",chr(27)."[01;33m", chr(27)."[0m"), - $str)); - } - - return $str; - } -} diff --git a/application/helpers/dompdf/include/cpdf_adapter.cls.php b/application/helpers/dompdf/include/cpdf_adapter.cls.php deleted file mode 100755 index 06947b505..000000000 --- a/application/helpers/dompdf/include/cpdf_adapter.cls.php +++ /dev/null @@ -1,877 +0,0 @@ - - * @author Orion Richardson - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -// FIXME: Need to sanity check inputs to this class -require_once(DOMPDF_LIB_DIR . "/class.pdf.php"); - -/** - * PDF rendering interface - * - * CPDF_Adapter provides a simple stateless interface to the stateful one - * provided by the Cpdf class. - * - * Unless otherwise mentioned, all dimensions are in points (1/72 in). The - * coordinate origin is in the top left corner, and y values increase - * downwards. - * - * See {@link http://www.ros.co.nz/pdf/} for more complete documentation - * on the underlying {@link Cpdf} class. - * - * @package dompdf - */ -class CPDF_Adapter implements Canvas { - - /** - * Dimensions of paper sizes in points - * - * @var array; - */ - static $PAPER_SIZES = array( - "4a0" => array(0,0,4767.87,6740.79), - "2a0" => array(0,0,3370.39,4767.87), - "a0" => array(0,0,2383.94,3370.39), - "a1" => array(0,0,1683.78,2383.94), - "a2" => array(0,0,1190.55,1683.78), - "a3" => array(0,0,841.89,1190.55), - "a4" => array(0,0,595.28,841.89), - "a5" => array(0,0,419.53,595.28), - "a6" => array(0,0,297.64,419.53), - "a7" => array(0,0,209.76,297.64), - "a8" => array(0,0,147.40,209.76), - "a9" => array(0,0,104.88,147.40), - "a10" => array(0,0,73.70,104.88), - "b0" => array(0,0,2834.65,4008.19), - "b1" => array(0,0,2004.09,2834.65), - "b2" => array(0,0,1417.32,2004.09), - "b3" => array(0,0,1000.63,1417.32), - "b4" => array(0,0,708.66,1000.63), - "b5" => array(0,0,498.90,708.66), - "b6" => array(0,0,354.33,498.90), - "b7" => array(0,0,249.45,354.33), - "b8" => array(0,0,175.75,249.45), - "b9" => array(0,0,124.72,175.75), - "b10" => array(0,0,87.87,124.72), - "c0" => array(0,0,2599.37,3676.54), - "c1" => array(0,0,1836.85,2599.37), - "c2" => array(0,0,1298.27,1836.85), - "c3" => array(0,0,918.43,1298.27), - "c4" => array(0,0,649.13,918.43), - "c5" => array(0,0,459.21,649.13), - "c6" => array(0,0,323.15,459.21), - "c7" => array(0,0,229.61,323.15), - "c8" => array(0,0,161.57,229.61), - "c9" => array(0,0,113.39,161.57), - "c10" => array(0,0,79.37,113.39), - "ra0" => array(0,0,2437.80,3458.27), - "ra1" => array(0,0,1729.13,2437.80), - "ra2" => array(0,0,1218.90,1729.13), - "ra3" => array(0,0,864.57,1218.90), - "ra4" => array(0,0,609.45,864.57), - "sra0" => array(0,0,2551.18,3628.35), - "sra1" => array(0,0,1814.17,2551.18), - "sra2" => array(0,0,1275.59,1814.17), - "sra3" => array(0,0,907.09,1275.59), - "sra4" => array(0,0,637.80,907.09), - "letter" => array(0,0,612.00,792.00), - "legal" => array(0,0,612.00,1008.00), - "ledger" => array(0,0,1224.00, 792.00), - "tabloid" => array(0,0,792.00, 1224.00), - "executive" => array(0,0,521.86,756.00), - "folio" => array(0,0,612.00,936.00), - "commercial #10 envelope" => array(0,0,684,297), - "catalog #10 1/2 envelope" => array(0,0,648,864), - "8.5x11" => array(0,0,612.00,792.00), - "8.5x14" => array(0,0,612.00,1008.0), - "11x17" => array(0,0,792.00, 1224.00), - ); - - /** - * The DOMPDF object - * - * @var DOMPDF - */ - private $_dompdf; - - /** - * Instance of Cpdf class - * - * @var Cpdf - */ - private $_pdf; - - /** - * PDF width, in points - * - * @var float - */ - private $_width; - - /** - * PDF height, in points - * - * @var float; - */ - private $_height; - - /** - * Current page number - * - * @var int - */ - private $_page_number; - - /** - * Total number of pages - * - * @var int - */ - private $_page_count; - - /** - * Text to display on every page - * - * @var array - */ - private $_page_text; - - /** - * Array of pages for accesing after rendering is initially complete - * - * @var array - */ - private $_pages; - - /** - * Array of temporary cached images to be deleted when processing is complete - * - * @var array - */ - private $_image_cache; - - /** - * Class constructor - * - * @param mixed $paper The size of paper to use in this PDF ({@link CPDF_Adapter::$PAPER_SIZES}) - * @param string $orientation The orientation of the document (either 'landscape' or 'portrait') - * @param DOMPDF $dompdf The DOMPDF instance - */ - function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf) { - if ( is_array($paper) ) { - $size = $paper; - } - else if ( isset(self::$PAPER_SIZES[mb_strtolower($paper)]) ) { - $size = self::$PAPER_SIZES[mb_strtolower($paper)]; - } - else { - $size = self::$PAPER_SIZES["letter"]; - } - - if ( mb_strtolower($orientation) === "landscape" ) { - list($size[2], $size[3]) = array($size[3], $size[2]); - } - - $this->_dompdf = $dompdf; - - $this->_pdf = new Cpdf( - $size, - $dompdf->get_option("enable_unicode"), - $dompdf->get_option("font_cache"), - $dompdf->get_option("temp_dir") - ); - - $this->_pdf->addInfo("Creator", "DOMPDF"); - $time = substr_replace(date('YmdHisO'), '\'', -2, 0).'\''; - $this->_pdf->addInfo("CreationDate", "D:$time"); - $this->_pdf->addInfo("ModDate", "D:$time"); - - $this->_width = $size[2] - $size[0]; - $this->_height= $size[3] - $size[1]; - - $this->_page_number = $this->_page_count = 1; - $this->_page_text = array(); - - $this->_pages = array($this->_pdf->getFirstPageId()); - - $this->_image_cache = array(); - } - - function get_dompdf(){ - return $this->_dompdf; - } - - /** - * Class destructor - * - * Deletes all temporary image files - */ - function __destruct() { - foreach ($this->_image_cache as $img) { - // The file might be already deleted by 3rd party tmp cleaner, - // the file might not have been created at all - // (if image outputting commands failed) - // or because the destructor was called twice accidentally. - if (!file_exists($img)) { - continue; - } - - if (DEBUGPNG) print '[__destruct unlink '.$img.']'; - if (!DEBUGKEEPTEMP) unlink($img); - } - } - - /** - * Returns the Cpdf instance - * - * @return Cpdf - */ - function get_cpdf() { - return $this->_pdf; - } - - /** - * Add meta information to the PDF - * - * @param string $label label of the value (Creator, Producer, etc.) - * @param string $value the text to set - */ - function add_info($label, $value) { - $this->_pdf->addInfo($label, $value); - } - - /** - * Opens a new 'object' - * - * While an object is open, all drawing actions are recored in the object, - * as opposed to being drawn on the current page. Objects can be added - * later to a specific page or to several pages. - * - * The return value is an integer ID for the new object. - * - * @see CPDF_Adapter::close_object() - * @see CPDF_Adapter::add_object() - * - * @return int - */ - function open_object() { - $ret = $this->_pdf->openObject(); - $this->_pdf->saveState(); - return $ret; - } - - /** - * Reopens an existing 'object' - * - * @see CPDF_Adapter::open_object() - * @param int $object the ID of a previously opened object - */ - function reopen_object($object) { - $this->_pdf->reopenObject($object); - $this->_pdf->saveState(); - } - - /** - * Closes the current 'object' - * - * @see CPDF_Adapter::open_object() - */ - function close_object() { - $this->_pdf->restoreState(); - $this->_pdf->closeObject(); - } - - /** - * Adds a specified 'object' to the document - * - * $object int specifying an object created with {@link - * CPDF_Adapter::open_object()}. $where can be one of: - * - 'add' add to current page only - * - 'all' add to every page from the current one onwards - * - 'odd' add to all odd numbered pages from now on - * - 'even' add to all even numbered pages from now on - * - 'next' add the object to the next page only - * - 'nextodd' add to all odd numbered pages from the next one - * - 'nexteven' add to all even numbered pages from the next one - * - * @see Cpdf::addObject() - * - * @param int $object - * @param string $where - */ - function add_object($object, $where = 'all') { - $this->_pdf->addObject($object, $where); - } - - /** - * Stops the specified 'object' from appearing in the document. - * - * The object will stop being displayed on the page following the current - * one. - * - * @param int $object - */ - function stop_object($object) { - $this->_pdf->stopObject($object); - } - - /** - * @access private - */ - function serialize_object($id) { - // Serialize the pdf object's current state for retrieval later - return $this->_pdf->serializeObject($id); - } - - /** - * @access private - */ - function reopen_serialized_object($obj) { - return $this->_pdf->restoreSerializedObject($obj); - } - - //........................................................................ - - /** - * Returns the PDF's width in points - * @return float - */ - function get_width() { return $this->_width; } - - /** - * Returns the PDF's height in points - * @return float - */ - function get_height() { return $this->_height; } - - /** - * Returns the current page number - * @return int - */ - function get_page_number() { return $this->_page_number; } - - /** - * Returns the total number of pages in the document - * @return int - */ - function get_page_count() { return $this->_page_count; } - - /** - * Sets the current page number - * - * @param int $num - */ - function set_page_number($num) { $this->_page_number = $num; } - - /** - * Sets the page count - * - * @param int $count - */ - function set_page_count($count) { $this->_page_count = $count; } - - /** - * Sets the stroke color - * - * See {@link Style::set_color()} for the format of the color array. - * @param array $color - */ - protected function _set_stroke_color($color) { - $this->_pdf->setStrokeColor($color); - } - - /** - * Sets the fill colour - * - * See {@link Style::set_color()} for the format of the colour array. - * @param array $color - */ - protected function _set_fill_color($color) { - $this->_pdf->setColor($color); - } - - /** - * Sets line transparency - * @see Cpdf::setLineTransparency() - * - * Valid blend modes are (case-sensitive): - * - * Normal, Multiply, Screen, Overlay, Darken, Lighten, - * ColorDodge, ColorBurn, HardLight, SoftLight, Difference, - * Exclusion - * - * @param string $mode the blending mode to use - * @param float $opacity 0.0 fully transparent, 1.0 fully opaque - */ - protected function _set_line_transparency($mode, $opacity) { - $this->_pdf->setLineTransparency($mode, $opacity); - } - - /** - * Sets fill transparency - * @see Cpdf::setFillTransparency() - * - * Valid blend modes are (case-sensitive): - * - * Normal, Multiply, Screen, Overlay, Darken, Lighten, - * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, - * Exclusion - * - * @param string $mode the blending mode to use - * @param float $opacity 0.0 fully transparent, 1.0 fully opaque - */ - protected function _set_fill_transparency($mode, $opacity) { - $this->_pdf->setFillTransparency($mode, $opacity); - } - - /** - * Sets the line style - * - * @see Cpdf::setLineStyle() - * - * @param float $width - * @param string $cap - * @param string $join - * @param array $dash - */ - protected function _set_line_style($width, $cap, $join, $dash) { - $this->_pdf->setLineStyle($width, $cap, $join, $dash); - } - - /** - * Sets the opacity - * - * @param $opacity - * @param $mode - */ - function set_opacity($opacity, $mode = "Normal") { - $this->_set_line_transparency($mode, $opacity); - $this->_set_fill_transparency($mode, $opacity); - } - - function set_default_view($view, $options = array()) { - array_unshift($options, $view); - call_user_func_array(array($this->_pdf, "openHere"), $options); - } - - /** - * Remaps y coords from 4th to 1st quadrant - * - * @param float $y - * @return float - */ - protected function y($y) { - return $this->_height - $y; - } - - // Canvas implementation - function line($x1, $y1, $x2, $y2, $color, $width, $style = array()) { - $this->_set_stroke_color($color); - $this->_set_line_style($width, "butt", "", $style); - - $this->_pdf->line($x1, $this->y($y1), - $x2, $this->y($y2)); - } - - function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array()) { - $this->_set_stroke_color($color); - $this->_set_line_style($width, "butt", "", $style); - - $this->_pdf->ellipse($x, $this->y($y), $r1, $r2, 0, 8, $astart, $aend, false, false, true, false); - } - - //........................................................................ - - /** - * Convert a GIF or BMP image to a PNG image - * - * @param string $image_url - * @param integer $type - * - * @throws DOMPDF_Exception - * @return string The url of the newly converted image - */ - protected function _convert_gif_bmp_to_png($image_url, $type) { - $image_type = Image_Cache::type_to_ext($type); - $func_name = "imagecreatefrom$image_type"; - - if ( !function_exists($func_name) ) { - throw new DOMPDF_Exception("Function $func_name() not found. Cannot convert $image_type image: $image_url. Please install the image PHP extension."); - } - - set_error_handler("record_warnings"); - $im = $func_name($image_url); - - if ( $im ) { - imageinterlace($im, false); - - $tmp_dir = $this->_dompdf->get_option("temp_dir"); - $tmp_name = tempnam($tmp_dir, "{$image_type}dompdf_img_"); - @unlink($tmp_name); - $filename = "$tmp_name.png"; - $this->_image_cache[] = $filename; - - imagepng($im, $filename); - imagedestroy($im); - } - else { - $filename = Image_Cache::$broken_image; - } - - restore_error_handler(); - - return $filename; - } - - function rectangle($x1, $y1, $w, $h, $color, $width, $style = array()) { - $this->_set_stroke_color($color); - $this->_set_line_style($width, "butt", "", $style); - $this->_pdf->rectangle($x1, $this->y($y1) - $h, $w, $h); - } - - function filled_rectangle($x1, $y1, $w, $h, $color) { - $this->_set_fill_color($color); - $this->_pdf->filledRectangle($x1, $this->y($y1) - $h, $w, $h); - } - - function clipping_rectangle($x1, $y1, $w, $h) { - $this->_pdf->clippingRectangle($x1, $this->y($y1) - $h, $w, $h); - } - - function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) { - $this->_pdf->clippingRectangleRounded($x1, $this->y($y1) - $h, $w, $h, $rTL, $rTR, $rBR, $rBL); - } - - function clipping_end() { - $this->_pdf->clippingEnd(); - } - - function save() { - $this->_pdf->saveState(); - } - - function restore() { - $this->_pdf->restoreState(); - } - - function rotate($angle, $x, $y) { - $this->_pdf->rotate($angle, $x, $y); - } - - function skew($angle_x, $angle_y, $x, $y) { - $this->_pdf->skew($angle_x, $angle_y, $x, $y); - } - - function scale($s_x, $s_y, $x, $y) { - $this->_pdf->scale($s_x, $s_y, $x, $y); - } - - function translate($t_x, $t_y) { - $this->_pdf->translate($t_x, $t_y); - } - - function transform($a, $b, $c, $d, $e, $f) { - $this->_pdf->transform(array($a, $b, $c, $d, $e, $f)); - } - - function polygon($points, $color, $width = null, $style = array(), $fill = false) { - $this->_set_fill_color($color); - $this->_set_stroke_color($color); - - // Adjust y values - for ( $i = 1; $i < count($points); $i += 2) { - $points[$i] = $this->y($points[$i]); - } - - $this->_pdf->polygon($points, count($points) / 2, $fill); - } - - function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false) { - $this->_set_fill_color($color); - $this->_set_stroke_color($color); - - if ( !$fill && isset($width) ) { - $this->_set_line_style($width, "round", "round", $style); - } - - $this->_pdf->ellipse($x, $this->y($y), $r1, 0, 0, 8, 0, 360, 1, $fill); - } - - function image($img, $x, $y, $w, $h, $resolution = "normal") { - list($width, $height, $type) = dompdf_getimagesize($img); - - $debug_png = $this->_dompdf->get_option("debug_png"); - - if ($debug_png) print "[image:$img|$width|$height|$type]"; - - switch ($type) { - case IMAGETYPE_JPEG: - if ($debug_png) print '!!!jpg!!!'; - $this->_pdf->addJpegFromFile($img, $x, $this->y($y) - $h, $w, $h); - break; - - case IMAGETYPE_GIF: - case IMAGETYPE_BMP: - if ($debug_png) print '!!!bmp or gif!!!'; - // @todo use cache for BMP and GIF - $img = $this->_convert_gif_bmp_to_png($img, $type); - - case IMAGETYPE_PNG: - if ($debug_png) print '!!!png!!!'; - - $this->_pdf->addPngFromFile($img, $x, $this->y($y) - $h, $w, $h); - break; - - default: - if ($debug_png) print '!!!unknown!!!'; - } - } - - function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) { - $pdf = $this->_pdf; - - $pdf->setColor($color); - - $font .= ".afm"; - $pdf->selectFont($font); - - //Font_Metrics::get_font_height($font, $size) == - //$this->get_font_height($font, $size) == - //$this->_pdf->selectFont($font),$this->_pdf->getFontHeight($size) - //- FontBBoxheight+FontHeightOffset, scaled to $size, in pt - //$this->_pdf->getFontDescender($size) - //- Descender scaled to size - // - //$this->_pdf->fonts[$this->_pdf->currentFont] sizes: - //['FontBBox'][0] left, ['FontBBox'][1] bottom, ['FontBBox'][2] right, ['FontBBox'][3] top - //Maximum extent of all glyphs of the font from the baseline point - //['Ascender'] maximum height above baseline except accents - //['Descender'] maximum depth below baseline, negative number means below baseline - //['FontHeightOffset'] manual enhancement of .afm files to trim windows fonts. currently not used. - //Values are in 1/1000 pt for a font size of 1 pt - // - //['FontBBox'][1] should be close to ['Descender'] - //['FontBBox'][3] should be close to ['Ascender']+Accents - //in practice, FontBBox values are a little bigger - // - //The text position is referenced to the baseline, not to the lower corner of the FontBBox, - //for what the left,top corner is given. - //FontBBox spans also the background box for the text. - //If the lower corner would be used as reference point, the Descents of the glyphs would - //hang over the background box border. - //Therefore compensate only the extent above the Baseline. - // - //print '
['.$font.','.$size.','.$pdf->getFontHeight($size).','.$pdf->getFontDescender($size).','.$pdf->fonts[$pdf->currentFont]['FontBBox'][3].','.$pdf->fonts[$pdf->currentFont]['FontBBox'][1].','.$pdf->fonts[$pdf->currentFont]['FontHeightOffset'].','.$pdf->fonts[$pdf->currentFont]['Ascender'].','.$pdf->fonts[$pdf->currentFont]['Descender'].']
'; - // - //$pdf->addText($x, $this->y($y) - ($pdf->fonts[$pdf->currentFont]['FontBBox'][3]*$size)/1000, $size, $text, $angle, $word_space, $char_space); - $pdf->addText($x, $this->y($y) - $pdf->getFontHeight($size), $size, $text, $angle, $word_space, $char_space); - } - - //........................................................................ - - function javascript($code) { - $this->_pdf->addJavascript($code); - } - - //........................................................................ - - /** - * Add a named destination (similar to ... in html) - * - * @param string $anchorname The name of the named destination - */ - function add_named_dest($anchorname) { - $this->_pdf->addDestination($anchorname, "Fit"); - } - - //........................................................................ - - /** - * Add a link to the pdf - * - * @param string $url The url to link to - * @param float $x The x position of the link - * @param float $y The y position of the link - * @param float $width The width of the link - * @param float $height The height of the link - */ - function add_link($url, $x, $y, $width, $height) { - - $y = $this->y($y) - $height; - - if ( strpos($url, '#') === 0 ) { - // Local link - $name = substr($url,1); - if ( $name ) { - $this->_pdf->addInternalLink($name, $x, $y, $x + $width, $y + $height); - } - - } - else { - $this->_pdf->addLink(rawurldecode($url), $x, $y, $x + $width, $y + $height); - } - } - - function get_text_width($text, $font, $size, $word_spacing = 0, $char_spacing = 0) { - $this->_pdf->selectFont($font); - - $unicode = $this->_dompdf->get_option("enable_unicode"); - if (!$unicode) { - $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8'); - } - - return $this->_pdf->getTextWidth($size, $text, $word_spacing, $char_spacing); - } - - function register_string_subset($font, $string) { - $this->_pdf->registerText($font, $string); - } - - function get_font_height($font, $size) { - $this->_pdf->selectFont($font); - - $ratio = $this->_dompdf->get_option("font_height_ratio"); - return $this->_pdf->getFontHeight($size) * $ratio; - } - - /*function get_font_x_height($font, $size) { - $this->_pdf->selectFont($font); - $ratio = $this->_dompdf->get_option("font_height_ratio"); - return $this->_pdf->getFontXHeight($size) * $ratio; - }*/ - - function get_font_baseline($font, $size) { - $ratio = $this->_dompdf->get_option("font_height_ratio"); - return $this->get_font_height($font, $size) / $ratio; - } - - /** - * Writes text at the specified x and y coordinates on every page - * - * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced - * with their current values. - * - * See {@link Style::munge_color()} for the format of the colour array. - * - * @param float $x - * @param float $y - * @param string $text the text to write - * @param string $font the font file to use - * @param float $size the font size, in points - * @param array $color - * @param float $word_space word spacing adjustment - * @param float $char_space char spacing adjustment - * @param float $angle angle to write the text at, measured CW starting from the x-axis - */ - function page_text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) { - $_t = "text"; - $this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle"); - } - - /** - * Processes a script on every page - * - * The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available. - * - * This function can be used to add page numbers to all pages - * after the first one, for example. - * - * @param string $code the script code - * @param string $type the language type for script - */ - function page_script($code, $type = "text/php") { - $_t = "script"; - $this->_page_text[] = compact("_t", "code", "type"); - } - - function new_page() { - $this->_page_number++; - $this->_page_count++; - - $ret = $this->_pdf->newPage(); - $this->_pages[] = $ret; - return $ret; - } - - /** - * Add text to each page after rendering is complete - */ - protected function _add_page_text() { - - if ( !count($this->_page_text) ) { - return; - } - - $page_number = 1; - $eval = null; - - foreach ($this->_pages as $pid) { - $this->reopen_object($pid); - - foreach ($this->_page_text as $pt) { - extract($pt); - - switch ($_t) { - case "text": - $text = str_replace(array("{PAGE_NUM}","{PAGE_COUNT}"), - array($page_number, $this->_page_count), $text); - $this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle); - break; - - case "script": - if ( !$eval ) { - $eval = new PHP_Evaluator($this); - } - $eval->evaluate($code, array('PAGE_NUM' => $page_number, 'PAGE_COUNT' => $this->_page_count)); - break; - } - } - - $this->close_object(); - $page_number++; - } - } - - /** - * Streams the PDF directly to the browser - * - * @param string $filename the name of the PDF file - * @param array $options associative array, 'Attachment' => 0 or 1, 'compress' => 1 or 0 - */ - function stream($filename, $options = null) { - // Add page text - $this->_add_page_text(); - - $options["Content-Disposition"] = $filename; - $this->_pdf->stream($options); - } - - /** - * Returns the PDF as a string - * - * @param array $options Output options - * @return string - */ - function output($options = null) { - $this->_add_page_text(); - - $debug = isset($options["compress"]) && $options["compress"] != 1; - - return $this->_pdf->output($debug); - } - - /** - * Returns logging messages generated by the Cpdf class - * - * @return string - */ - function get_messages() { - return $this->_pdf->messages; - } -} diff --git a/application/helpers/dompdf/include/css_color.cls.php b/application/helpers/dompdf/include/css_color.cls.php deleted file mode 100755 index 481751db5..000000000 --- a/application/helpers/dompdf/include/css_color.cls.php +++ /dev/null @@ -1,287 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -class CSS_Color { - static $cssColorNames = array( - "aliceblue" => "F0F8FF", - "antiquewhite" => "FAEBD7", - "aqua" => "00FFFF", - "aquamarine" => "7FFFD4", - "azure" => "F0FFFF", - "beige" => "F5F5DC", - "bisque" => "FFE4C4", - "black" => "000000", - "blanchedalmond" => "FFEBCD", - "blue" => "0000FF", - "blueviolet" => "8A2BE2", - "brown" => "A52A2A", - "burlywood" => "DEB887", - "cadetblue" => "5F9EA0", - "chartreuse" => "7FFF00", - "chocolate" => "D2691E", - "coral" => "FF7F50", - "cornflowerblue" => "6495ED", - "cornsilk" => "FFF8DC", - "crimson" => "DC143C", - "cyan" => "00FFFF", - "darkblue" => "00008B", - "darkcyan" => "008B8B", - "darkgoldenrod" => "B8860B", - "darkgray" => "A9A9A9", - "darkgreen" => "006400", - "darkgrey" => "A9A9A9", - "darkkhaki" => "BDB76B", - "darkmagenta" => "8B008B", - "darkolivegreen" => "556B2F", - "darkorange" => "FF8C00", - "darkorchid" => "9932CC", - "darkred" => "8B0000", - "darksalmon" => "E9967A", - "darkseagreen" => "8FBC8F", - "darkslateblue" => "483D8B", - "darkslategray" => "2F4F4F", - "darkslategrey" => "2F4F4F", - "darkturquoise" => "00CED1", - "darkviolet" => "9400D3", - "deeppink" => "FF1493", - "deepskyblue" => "00BFFF", - "dimgray" => "696969", - "dimgrey" => "696969", - "dodgerblue" => "1E90FF", - "firebrick" => "B22222", - "floralwhite" => "FFFAF0", - "forestgreen" => "228B22", - "fuchsia" => "FF00FF", - "gainsboro" => "DCDCDC", - "ghostwhite" => "F8F8FF", - "gold" => "FFD700", - "goldenrod" => "DAA520", - "gray" => "808080", - "green" => "008000", - "greenyellow" => "ADFF2F", - "grey" => "808080", - "honeydew" => "F0FFF0", - "hotpink" => "FF69B4", - "indianred" => "CD5C5C", - "indigo" => "4B0082", - "ivory" => "FFFFF0", - "khaki" => "F0E68C", - "lavender" => "E6E6FA", - "lavenderblush" => "FFF0F5", - "lawngreen" => "7CFC00", - "lemonchiffon" => "FFFACD", - "lightblue" => "ADD8E6", - "lightcoral" => "F08080", - "lightcyan" => "E0FFFF", - "lightgoldenrodyellow" => "FAFAD2", - "lightgray" => "D3D3D3", - "lightgreen" => "90EE90", - "lightgrey" => "D3D3D3", - "lightpink" => "FFB6C1", - "lightsalmon" => "FFA07A", - "lightseagreen" => "20B2AA", - "lightskyblue" => "87CEFA", - "lightslategray" => "778899", - "lightslategrey" => "778899", - "lightsteelblue" => "B0C4DE", - "lightyellow" => "FFFFE0", - "lime" => "00FF00", - "limegreen" => "32CD32", - "linen" => "FAF0E6", - "magenta" => "FF00FF", - "maroon" => "800000", - "mediumaquamarine" => "66CDAA", - "mediumblue" => "0000CD", - "mediumorchid" => "BA55D3", - "mediumpurple" => "9370DB", - "mediumseagreen" => "3CB371", - "mediumslateblue" => "7B68EE", - "mediumspringgreen" => "00FA9A", - "mediumturquoise" => "48D1CC", - "mediumvioletred" => "C71585", - "midnightblue" => "191970", - "mintcream" => "F5FFFA", - "mistyrose" => "FFE4E1", - "moccasin" => "FFE4B5", - "navajowhite" => "FFDEAD", - "navy" => "000080", - "oldlace" => "FDF5E6", - "olive" => "808000", - "olivedrab" => "6B8E23", - "orange" => "FFA500", - "orangered" => "FF4500", - "orchid" => "DA70D6", - "palegoldenrod" => "EEE8AA", - "palegreen" => "98FB98", - "paleturquoise" => "AFEEEE", - "palevioletred" => "DB7093", - "papayawhip" => "FFEFD5", - "peachpuff" => "FFDAB9", - "peru" => "CD853F", - "pink" => "FFC0CB", - "plum" => "DDA0DD", - "powderblue" => "B0E0E6", - "purple" => "800080", - "red" => "FF0000", - "rosybrown" => "BC8F8F", - "royalblue" => "4169E1", - "saddlebrown" => "8B4513", - "salmon" => "FA8072", - "sandybrown" => "F4A460", - "seagreen" => "2E8B57", - "seashell" => "FFF5EE", - "sienna" => "A0522D", - "silver" => "C0C0C0", - "skyblue" => "87CEEB", - "slateblue" => "6A5ACD", - "slategray" => "708090", - "slategrey" => "708090", - "snow" => "FFFAFA", - "springgreen" => "00FF7F", - "steelblue" => "4682B4", - "tan" => "D2B48C", - "teal" => "008080", - "thistle" => "D8BFD8", - "tomato" => "FF6347", - "turquoise" => "40E0D0", - "violet" => "EE82EE", - "wheat" => "F5DEB3", - "white" => "FFFFFF", - "whitesmoke" => "F5F5F5", - "yellow" => "FFFF00", - "yellowgreen" => "9ACD32", - ); - - static function parse($color) { - if ( is_array($color) ) { - // Assume the array has the right format... - // FIXME: should/could verify this. - return $color; - } - - static $cache = array(); - - $color = strtolower($color); - - if ( isset($cache[$color]) ) { - return $cache[$color]; - } - - if ( in_array($color, array("transparent", "inherit")) ) { - return $cache[$color] = $color; - } - - if ( isset(self::$cssColorNames[$color]) ) { - return $cache[$color] = self::getArray(self::$cssColorNames[$color]); - } - - $length = mb_strlen($color); - - // #rgb format - if ( $length == 4 && $color[0] === "#" ) { - return $cache[$color] = self::getArray($color[1].$color[1].$color[2].$color[2].$color[3].$color[3]); - } - - // #rrggbb format - else if ( $length == 7 && $color[0] === "#" ) { - return $cache[$color] = self::getArray(mb_substr($color, 1, 6)); - } - - // rgb( r,g,b ) / rgbaa( r,g,b,α ) format - else if ( mb_strpos($color, "rgb") !== false ) { - $i = mb_strpos($color, "("); - $j = mb_strpos($color, ")"); - - // Bad color value - if ( $i === false || $j === false ) { - return null; - } - - $triplet = explode(",", mb_substr($color, $i+1, $j-$i-1)); - - // alpha transparency - // FIXME: not currently using transparency - $alpha = 1; - if ( count( $triplet ) == 4 ) { - $alpha = (float) ( trim( array_pop( $triplet ) ) ); - // bad value, set to fully opaque - if ( $alpha > 1 || $alpha < 0 ) { - $alpha = 1; - } - } - - if ( count($triplet) != 3 ) { - return null; - } - - foreach (array_keys($triplet) as $c) { - $triplet[$c] = trim($triplet[$c]); - - if ( $triplet[$c][mb_strlen($triplet[$c]) - 1] === "%" ) { - $triplet[$c] = round($triplet[$c] * 2.55); - } - } - - return $cache[$color] = self::getArray(vsprintf("%02X%02X%02X", $triplet)); - - } - - // cmyk( c,m,y,k ) format - // http://www.w3.org/TR/css3-gcpm/#cmyk-colors - else if ( mb_strpos($color, "cmyk") !== false ) { - $i = mb_strpos($color, "("); - $j = mb_strpos($color, ")"); - - // Bad color value - if ( $i === false || $j === false ) { - return null; - } - - $values = explode(",", mb_substr($color, $i+1, $j-$i-1)); - - if ( count($values) != 4 ) { - return null; - } - - foreach ($values as &$c) { - $c = floatval(trim($c)); - if ($c > 1.0) $c = 1.0; - if ($c < 0.0) $c = 0.0; - } - - return $cache[$color] = self::getArray($values); - } - - return null; - } - - static function getArray($color) { - $c = array(null, null, null, null, "hex" => null); - - if (is_array($color)) { - $c = $color; - $c["c"] = $c[0]; - $c["m"] = $c[1]; - $c["y"] = $c[2]; - $c["k"] = $c[3]; - $c["hex"] = "cmyk($c[0],$c[1],$c[2],$c[3])"; - } - else { - $c[0] = hexdec(mb_substr($color, 0, 2)) / 0xff; - $c[1] = hexdec(mb_substr($color, 2, 2)) / 0xff; - $c[2] = hexdec(mb_substr($color, 4, 2)) / 0xff; - $c["r"] = $c[0]; - $c["g"] = $c[1]; - $c["b"] = $c[2]; - $c["hex"] = "#$color"; - } - - return $c; - } -} diff --git a/application/helpers/dompdf/include/dompdf.cls.php b/application/helpers/dompdf/include/dompdf.cls.php deleted file mode 100755 index 1be1f8284..000000000 --- a/application/helpers/dompdf/include/dompdf.cls.php +++ /dev/null @@ -1,1077 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * DOMPDF - PHP5 HTML to PDF renderer - * - * DOMPDF loads HTML and does its best to render it as a PDF. It gets its - * name from the new DomDocument PHP5 extension. Source HTML is first - * parsed by a DomDocument object. DOMPDF takes the resulting DOM tree and - * attaches a {@link Frame} object to each node. {@link Frame} objects store - * positioning and layout information and each has a reference to a {@link - * Style} object. - * - * Style information is loaded and parsed (see {@link Stylesheet}) and is - * applied to the frames in the tree by using XPath. CSS selectors are - * converted into XPath queries, and the computed {@link Style} objects are - * applied to the {@link Frame}s. - * - * {@link Frame}s are then decorated (in the design pattern sense of the - * word) based on their CSS display property ({@link - * http://www.w3.org/TR/CSS21/visuren.html#propdef-display}). - * Frame_Decorators augment the basic {@link Frame} class by adding - * additional properties and methods specific to the particular type of - * {@link Frame}. For example, in the CSS layout model, block frames - * (display: block;) contain line boxes that are usually filled with text or - * other inline frames. The Block_Frame_Decorator therefore adds a $lines - * property as well as methods to add {@link Frame}s to lines and to add - * additional lines. {@link Frame}s also are attached to specific - * Positioner and {@link Frame_Reflower} objects that contain the - * positioining and layout algorithm for a specific type of frame, - * respectively. This is an application of the Strategy pattern. - * - * Layout, or reflow, proceeds recursively (post-order) starting at the root - * of the document. Space constraints (containing block width & height) are - * pushed down, and resolved positions and sizes bubble up. Thus, every - * {@link Frame} in the document tree is traversed once (except for tables - * which use a two-pass layout algorithm). If you are interested in the - * details, see the reflow() method of the Reflower classes. - * - * Rendering is relatively straightforward once layout is complete. {@link - * Frame}s are rendered using an adapted {@link Cpdf} class, originally - * written by Wayne Munro, http://www.ros.co.nz/pdf/. (Some performance - * related changes have been made to the original {@link Cpdf} class, and - * the {@link CPDF_Adapter} class provides a simple, stateless interface to - * PDF generation.) PDFLib support has now also been added, via the {@link - * PDFLib_Adapter}. - * - * - * @package dompdf - */ -class DOMPDF { - - /** - * DomDocument representing the HTML document - * - * @var DOMDocument - */ - protected $_xml; - - /** - * Frame_Tree derived from the DOM tree - * - * @var Frame_Tree - */ - protected $_tree; - - /** - * Stylesheet for the document - * - * @var Stylesheet - */ - protected $_css; - - /** - * Actual PDF renderer - * - * @var Canvas - */ - protected $_pdf; - - /** - * Desired paper size ('letter', 'legal', 'A4', etc.) - * - * @var string - */ - protected $_paper_size; - - /** - * Paper orientation ('portrait' or 'landscape') - * - * @var string - */ - protected $_paper_orientation; - - /** - * Callbacks on new page and new element - * - * @var array - */ - protected $_callbacks; - - /** - * Experimental caching capability - * - * @var string - */ - private $_cache_id; - - /** - * Base hostname - * - * Used for relative paths/urls - * @var string - */ - protected $_base_host; - - /** - * Absolute base path - * - * Used for relative paths/urls - * @var string - */ - protected $_base_path; - - /** - * Protcol used to request file (file://, http://, etc) - * - * @var string - */ - protected $_protocol; - - /** - * HTTP context created with stream_context_create() - * Will be used for file_get_contents - * - * @var resource - */ - protected $_http_context; - - /** - * Timestamp of the script start time - * - * @var int - */ - private $_start_time = null; - - /** - * The system's locale - * - * @var string - */ - private $_system_locale = null; - - /** - * Tells if the system's locale is the C standard one - * - * @var bool - */ - private $_locale_standard = false; - - /** - * The default view of the PDF in the viewer - * - * @var string - */ - private $_default_view = "Fit"; - - /** - * The default view options of the PDF in the viewer - * - * @var array - */ - private $_default_view_options = array(); - - /** - * Tells wether the DOM document is in quirksmode (experimental) - * - * @var bool - */ - private $_quirksmode = false; - - /** - * The list of built-in fonts - * - * @var array - */ - public static $native_fonts = array( - "courier", "courier-bold", "courier-oblique", "courier-boldoblique", - "helvetica", "helvetica-bold", "helvetica-oblique", "helvetica-boldoblique", - "times-roman", "times-bold", "times-italic", "times-bolditalic", - "symbol", "zapfdinbats" - ); - - private $_options = array( - // Directories - "temp_dir" => DOMPDF_TEMP_DIR, - "font_dir" => DOMPDF_FONT_DIR, - "font_cache" => DOMPDF_FONT_CACHE, - "chroot" => DOMPDF_CHROOT, - "log_output_file" => DOMPDF_LOG_OUTPUT_FILE, - - // Rendering - "default_media_type" => DOMPDF_DEFAULT_MEDIA_TYPE, - "default_paper_size" => DOMPDF_DEFAULT_PAPER_SIZE, - "default_font" => DOMPDF_DEFAULT_FONT, - "dpi" => DOMPDF_DPI, - "font_height_ratio" => DOMPDF_FONT_HEIGHT_RATIO, - - // Features - "enable_unicode" => DOMPDF_UNICODE_ENABLED, - "enable_php" => DOMPDF_ENABLE_PHP, - "enable_remote" => DOMPDF_ENABLE_REMOTE, - "enable_css_float" => DOMPDF_ENABLE_CSS_FLOAT, - "enable_javascript" => DOMPDF_ENABLE_JAVASCRIPT, - "enable_html5_parser" => DOMPDF_ENABLE_HTML5PARSER, - "enable_font_subsetting" => DOMPDF_ENABLE_FONTSUBSETTING, - - // Debug - "debug_png" => DEBUGPNG, - "debug_keep_temp" => DEBUGKEEPTEMP, - "debug_css" => DEBUGCSS, - "debug_layout" => DEBUG_LAYOUT, - "debug_layout_lines" => DEBUG_LAYOUT_LINES, - "debug_layout_blocks" => DEBUG_LAYOUT_BLOCKS, - "debug_layout_inline" => DEBUG_LAYOUT_INLINE, - "debug_layout_padding_box" => DEBUG_LAYOUT_PADDINGBOX, - - // Admin - "admin_username" => DOMPDF_ADMIN_USERNAME, - "admin_password" => DOMPDF_ADMIN_PASSWORD, - ); - - /** - * Class constructor - */ - function __construct() { - $this->_locale_standard = sprintf('%.1f', 1.0) == '1.0'; - - $this->save_locale(); - - $this->_messages = array(); - $this->_css = new Stylesheet($this); - $this->_pdf = null; - $this->_paper_size = DOMPDF_DEFAULT_PAPER_SIZE; - $this->_paper_orientation = "portrait"; - $this->_base_protocol = ""; - $this->_base_host = ""; - $this->_base_path = ""; - $this->_http_context = null; - $this->_callbacks = array(); - $this->_cache_id = null; - - $this->restore_locale(); - } - - /** - * Class destructor - */ - function __destruct() { - clear_object($this); - } - - /** - * Get the dompdf option value - * - * @param string $key - * - * @return mixed - * @throws DOMPDF_Exception - */ - function get_option($key) { - if ( !array_key_exists($key, $this->_options) ) { - throw new DOMPDF_Exception("Option '$key' doesn't exist"); - } - - return $this->_options[$key]; - } - - /** - * @param string $key - * @param mixed $value - * - * @throws DOMPDF_Exception - */ - function set_option($key, $value) { - if ( !array_key_exists($key, $this->_options) ) { - throw new DOMPDF_Exception("Option '$key' doesn't exist"); - } - - $this->_options[$key] = $value; - } - - /** - * @param array $options - */ - function set_options(array $options) { - foreach ($options as $key => $value) { - $this->set_option($key, $value); - } - } - - /** - * Save the system's locale configuration and - * set the right value for numeric formatting - */ - private function save_locale() { - if ( $this->_locale_standard ) { - return; - } - - $this->_system_locale = setlocale(LC_NUMERIC, "0"); - setlocale(LC_NUMERIC, "C"); - } - - /** - * Restore the system's locale configuration - */ - private function restore_locale() { - if ( $this->_locale_standard ) { - return; - } - - setlocale(LC_NUMERIC, $this->_system_locale); - } - - /** - * Returns the underlying {@link Frame_Tree} object - * - * @return Frame_Tree - */ - function get_tree() { - return $this->_tree; - } - - /** - * Sets the protocol to use - * FIXME validate these - * - * @param string $proto - */ - function set_protocol($proto) { - $this->_protocol = $proto; - } - - /** - * Sets the base hostname - * - * @param string $host - */ - function set_host($host) { - $this->_base_host = $host; - } - - /** - * Sets the base path - * - * @param string $path - */ - function set_base_path($path) { - $this->_base_path = $path; - } - - /** - * Sets the HTTP context - * - * @param resource $http_context - */ - function set_http_context($http_context) { - $this->_http_context = $http_context; - } - - /** - * Sets the default view - * - * @param string $default_view The default document view - * @param array $options The view's options - */ - function set_default_view($default_view, $options) { - $this->_default_view = $default_view; - $this->_default_view_options = $options; - } - - /** - * Returns the protocol in use - * - * @return string - */ - function get_protocol() { - return $this->_protocol; - } - - /** - * Returns the base hostname - * - * @return string - */ - function get_host() { - return $this->_base_host; - } - - /** - * Returns the base path - * - * @return string - */ - function get_base_path() { - return $this->_base_path; - } - - /** - * Returns the HTTP context - * - * @return resource - */ - function get_http_context() { - return $this->_http_context; - } - - /** - * Return the underlying Canvas instance (e.g. CPDF_Adapter, GD_Adapter) - * - * @return Canvas - */ - function get_canvas() { - return $this->_pdf; - } - - /** - * Returns the callbacks array - * - * @return array - */ - function get_callbacks() { - return $this->_callbacks; - } - - /** - * Returns the stylesheet - * - * @return Stylesheet - */ - function get_css() { - return $this->_css; - } - - /** - * @return DOMDocument - */ - function get_dom() { - return $this->_xml; - } - - /** - * Loads an HTML file - * Parse errors are stored in the global array _dompdf_warnings. - * - * @param string $file a filename or url to load - * - * @throws DOMPDF_Exception - */ - function load_html_file($file) { - $this->save_locale(); - - // Store parsing warnings as messages (this is to prevent output to the - // browser if the html is ugly and the dom extension complains, - // preventing the pdf from being streamed.) - if ( !$this->_protocol && !$this->_base_host && !$this->_base_path ) { - list($this->_protocol, $this->_base_host, $this->_base_path) = explode_url($file); - } - - if ( !$this->get_option("enable_remote") && ($this->_protocol != "" && $this->_protocol !== "file://" ) ) { - throw new DOMPDF_Exception("Remote file requested, but DOMPDF_ENABLE_REMOTE is false."); - } - - if ($this->_protocol == "" || $this->_protocol === "file://") { - - // Get the full path to $file, returns false if the file doesn't exist - $realfile = realpath($file); - if ( !$realfile ) { - throw new DOMPDF_Exception("File '$file' not found."); - } - - $chroot = $this->get_option("chroot"); - if ( strpos($realfile, $chroot) !== 0 ) { - throw new DOMPDF_Exception("Permission denied on $file. The file could not be found under the directory specified by DOMPDF_CHROOT."); - } - - // Exclude dot files (e.g. .htaccess) - if ( substr(basename($realfile), 0, 1) === "." ) { - throw new DOMPDF_Exception("Permission denied on $file."); - } - - $file = $realfile; - } - - $contents = file_get_contents($file, null, $this->_http_context); - $encoding = null; - - // See http://the-stickman.com/web-development/php/getting-http-response-headers-when-using-file_get_contents/ - if ( isset($http_response_header) ) { - foreach($http_response_header as $_header) { - if ( preg_match("@Content-Type:\s*[\w/]+;\s*?charset=([^\s]+)@i", $_header, $matches) ) { - $encoding = strtoupper($matches[1]); - break; - } - } - } - - $this->restore_locale(); - - $this->load_html($contents, $encoding); - } - - /** - * Loads an HTML string - * Parse errors are stored in the global array _dompdf_warnings. - * @todo use the $encoding variable - * - * @param string $str HTML text to load - * @param string $encoding Not used yet - */ - function load_html($str, $encoding = null) { - $this->save_locale(); - - // FIXME: Determine character encoding, switch to UTF8, update meta tag. Need better http/file stream encoding detection, currently relies on text or meta tag. - mb_detect_order('auto'); - - if (mb_detect_encoding($str) !== 'UTF-8') { - $metatags = array( - '@]*charset\s*=\s*["\']?\s*([^"\' ]+)@i', - ); - - foreach($metatags as $metatag) { - if (preg_match($metatag, $str, $matches)) break; - } - - if (mb_detect_encoding($str) == '') { - if (isset($matches[1])) { - $encoding = strtoupper($matches[1]); - } - else { - $encoding = 'UTF-8'; - } - } - else { - if ( isset($matches[1]) ) { - $encoding = strtoupper($matches[1]); - } - else { - $encoding = 'auto'; - } - } - - if ( $encoding !== 'UTF-8' ) { - $str = mb_convert_encoding($str, 'UTF-8', $encoding); - } - - if ( isset($matches[1]) ) { - $str = preg_replace('/charset=([^\s"]+)/i', 'charset=UTF-8', $str); - } - else { - $str = str_replace('', '', $str); - } - } - else { - $encoding = 'UTF-8'; - } - - // remove BOM mark from UTF-8, it's treated as document text by DOMDocument - // FIXME: roll this into the encoding detection using UTF-8/16/32 BOM (http://us2.php.net/manual/en/function.mb-detect-encoding.php#91051)? - if ( substr($str, 0, 3) == chr(0xEF).chr(0xBB).chr(0xBF) ) { - $str = substr($str, 3); - } - - // if the document contains non utf-8 with a utf-8 meta tag chars and was - // detected as utf-8 by mbstring, problems could happen. - // http://devzone.zend.com/article/8855 - if ( $encoding !== 'UTF-8' ) { - $re = '/]*)((?:charset=[^"\' ]+)([^>]*)|(?:charset=["\'][^"\' ]+["\']))([^>]*)>/i'; - $str = preg_replace($re, '', $str); - } - - // Store parsing warnings as messages - set_error_handler("record_warnings"); - - // @todo Take the quirksmode into account - // http://hsivonen.iki.fi/doctype/ - // https://developer.mozilla.org/en/mozilla's_quirks_mode - $quirksmode = false; - - if ( $this->get_option("enable_html5_parser") ) { - $tokenizer = new HTML5_Tokenizer($str); - $tokenizer->parse(); - $doc = $tokenizer->save(); - - // Remove #text children nodes in nodes that shouldn't have - $tag_names = array("html", "table", "tbody", "thead", "tfoot", "tr"); - foreach($tag_names as $tag_name) { - $nodes = $doc->getElementsByTagName($tag_name); - - foreach($nodes as $node) { - self::remove_text_nodes($node); - } - } - - $quirksmode = ($tokenizer->getTree()->getQuirksMode() > HTML5_TreeBuilder::NO_QUIRKS); - } - else { - // loadHTML assumes ISO-8859-1 unless otherwise specified, but there are - // bugs in how DOMDocument determines the actual encoding. Converting to - // HTML-ENTITIES prior to import appears to resolve the issue. - // http://devzone.zend.com/1538/php-dom-xml-extension-encoding-processing/ (see #4) - // http://stackoverflow.com/a/11310258/264628 - $doc = new DOMDocument(); - $doc->preserveWhiteSpace = true; - $doc->loadHTML( mb_convert_encoding( $str , 'HTML-ENTITIES' , 'UTF-8' ) ); - - // If some text is before the doctype, we are in quirksmode - if ( preg_match("/^(.+) - if ( !$doc->doctype->publicId && !$doc->doctype->systemId ) { - $quirksmode = false; - } - - // not XHTML - if ( !preg_match("/xhtml/i", $doc->doctype->publicId) ) { - $quirksmode = true; - } - } - } - - $this->_xml = $doc; - $this->_quirksmode = $quirksmode; - - $this->_tree = new Frame_Tree($this->_xml); - - restore_error_handler(); - - $this->restore_locale(); - } - - static function remove_text_nodes(DOMNode $node) { - $children = array(); - for ($i = 0; $i < $node->childNodes->length; $i++) { - $child = $node->childNodes->item($i); - if ( $child->nodeName === "#text" ) { - $children[] = $child; - } - } - - foreach($children as $child) { - $node->removeChild($child); - } - } - - /** - * Builds the {@link Frame_Tree}, loads any CSS and applies the styles to - * the {@link Frame_Tree} - */ - protected function _process_html() { - $this->_tree->build_tree(); - - $this->_css->load_css_file(Stylesheet::DEFAULT_STYLESHEET, Stylesheet::ORIG_UA); - - $acceptedmedia = Stylesheet::$ACCEPTED_GENERIC_MEDIA_TYPES; - $acceptedmedia[] = $this->get_option("default_media_type"); - - // - $base_nodes = $this->_xml->getElementsByTagName("base"); - if ( $base_nodes->length && ($href = $base_nodes->item(0)->getAttribute("href")) ) { - list($this->_protocol, $this->_base_host, $this->_base_path) = explode_url($href); - } - - // Set the base path of the Stylesheet to that of the file being processed - $this->_css->set_protocol($this->_protocol); - $this->_css->set_host($this->_base_host); - $this->_css->set_base_path($this->_base_path); - - // Get all the stylesheets so that they are processed in document order - $xpath = new DOMXPath($this->_xml); - $stylesheets = $xpath->query("//*[name() = 'link' or name() = 'style']"); - - foreach($stylesheets as $tag) { - switch (strtolower($tag->nodeName)) { - // load tags - case "link": - if ( mb_strtolower(stripos($tag->getAttribute("rel"), "stylesheet") !== false) || // may be "appendix stylesheet" - mb_strtolower($tag->getAttribute("type")) === "text/css" ) { - //Check if the css file is for an accepted media type - //media not given then always valid - $formedialist = preg_split("/[\s\n,]/", $tag->getAttribute("media"),-1, PREG_SPLIT_NO_EMPTY); - if ( count($formedialist) > 0 ) { - $accept = false; - foreach ( $formedialist as $type ) { - if ( in_array(mb_strtolower(trim($type)), $acceptedmedia) ) { - $accept = true; - break; - } - } - - if (!$accept) { - //found at least one mediatype, but none of the accepted ones - //Skip this css file. - continue; - } - } - - $url = $tag->getAttribute("href"); - $url = build_url($this->_protocol, $this->_base_host, $this->_base_path, $url); - - $this->_css->load_css_file($url, Stylesheet::ORIG_AUTHOR); - } - break; - - // load - $child = $child->nextSibling; - } - } - else { - $css = $tag->nodeValue; - } - - $this->_css->load_css($css); - break; - } - } - } - - /** - * Sets the paper size & orientation - * - * @param string $size 'letter', 'legal', 'A4', etc. {@link CPDF_Adapter::$PAPER_SIZES} - * @param string $orientation 'portrait' or 'landscape' - */ - function set_paper($size, $orientation = "portrait") { - $this->_paper_size = $size; - $this->_paper_orientation = $orientation; - } - - /** - * Enable experimental caching capability - * @access private - */ - function enable_caching($cache_id) { - $this->_cache_id = $cache_id; - } - - /** - * Sets callbacks for events like rendering of pages and elements. - * The callbacks array contains arrays with 'event' set to 'begin_page', - * 'end_page', 'begin_frame', or 'end_frame' and 'f' set to a function or - * object plus method to be called. - * - * The function 'f' must take an array as argument, which contains info - * about the event. - * - * @param array $callbacks the set of callbacks to set - */ - function set_callbacks($callbacks) { - if (is_array($callbacks)) { - $this->_callbacks = array(); - foreach ($callbacks as $c) { - if (is_array($c) && isset($c['event']) && isset($c['f'])) { - $event = $c['event']; - $f = $c['f']; - if (is_callable($f) && is_string($event)) { - $this->_callbacks[$event][] = $f; - } - } - } - } - } - - /** - * Get the quirks mode - * - * @return boolean true if quirks mode is active - */ - function get_quirksmode(){ - return $this->_quirksmode; - } - - function parse_default_view($value) { - $valid = array("XYZ", "Fit", "FitH", "FitV", "FitR", "FitB", "FitBH", "FitBV"); - - $options = preg_split("/\s*,\s*/", trim($value)); - $default_view = array_shift($options); - - if ( !in_array($default_view, $valid) ) { - return false; - } - - $this->set_default_view($default_view, $options); - return true; - } - - /** - * Renders the HTML to PDF - */ - function render() { - $this->save_locale(); - - $log_output_file = $this->get_option("log_output_file"); - if ( $log_output_file ) { - if ( !file_exists($log_output_file) && is_writable(dirname($log_output_file)) ) { - touch($log_output_file); - } - - $this->_start_time = microtime(true); - ob_start(); - } - - //enable_mem_profile(); - - $this->_process_html(); - - $this->_css->apply_styles($this->_tree); - - // @page style rules : size, margins - $page_styles = $this->_css->get_page_styles(); - - $base_page_style = $page_styles["base"]; - unset($page_styles["base"]); - - foreach($page_styles as $_page_style) { - $_page_style->inherit($base_page_style); - } - - if ( is_array($base_page_style->size) ) { - $this->set_paper(array(0, 0, $base_page_style->size[0], $base_page_style->size[1])); - } - - $this->_pdf = Canvas_Factory::get_instance($this, $this->_paper_size, $this->_paper_orientation); - Font_Metrics::init($this->_pdf); - - if ( $this->get_option("enable_font_subsetting") && $this->_pdf instanceof CPDF_Adapter ) { - foreach ($this->_tree->get_frames() as $frame) { - $style = $frame->get_style(); - $node = $frame->get_node(); - - // Handle text nodes - if ( $node->nodeName === "#text" ) { - $this->_pdf->register_string_subset($style->font_family, $node->nodeValue); - continue; - } - - // Handle generated content (list items) - if ( $style->display === "list-item" ) { - $chars = List_Bullet_Renderer::get_counter_chars($style->list_style_type); - $this->_pdf->register_string_subset($style->font_family, $chars); - continue; - } - - // Handle other generated content (pseudo elements) - // FIXME: This only captures the text of the stylesheet declaration, - // not the actual generated content, and forces all possible counter - // values. See notes in issue #750. - if ( $frame->get_node()->nodeName == "dompdf_generated" ) { - // all possible counter values - $chars = List_Bullet_Renderer::get_counter_chars('decimal'); - $this->_pdf->register_string_subset($style->font_family, $chars); - $chars = List_Bullet_Renderer::get_counter_chars('upper-alpha'); - $this->_pdf->register_string_subset($style->font_family, $chars); - $chars = List_Bullet_Renderer::get_counter_chars('lower-alpha'); - $this->_pdf->register_string_subset($style->font_family, $chars); - $chars = List_Bullet_Renderer::get_counter_chars('lower-greek'); - $this->_pdf->register_string_subset($style->font_family, $chars); - // the text of the stylesheet declaration - $this->_pdf->register_string_subset($style->font_family, $style->content); - continue; - } - } - } - - $root = null; - - foreach ($this->_tree->get_frames() as $frame) { - // Set up the root frame - if ( is_null($root) ) { - $root = Frame_Factory::decorate_root( $this->_tree->get_root(), $this ); - continue; - } - - // Create the appropriate decorators, reflowers & positioners. - Frame_Factory::decorate_frame($frame, $this, $root); - } - - // Add meta information - $title = $this->_xml->getElementsByTagName("title"); - if ( $title->length ) { - $this->_pdf->add_info("Title", trim($title->item(0)->nodeValue)); - } - - $metas = $this->_xml->getElementsByTagName("meta"); - $labels = array( - "author" => "Author", - "keywords" => "Keywords", - "description" => "Subject", - ); - foreach($metas as $meta) { - $name = mb_strtolower($meta->getAttribute("name")); - $value = trim($meta->getAttribute("content")); - - if ( isset($labels[$name]) ) { - $this->_pdf->add_info($labels[$name], $value); - continue; - } - - if ( $name === "dompdf.view" && $this->parse_default_view($value) ) { - $this->_pdf->set_default_view($this->_default_view, $this->_default_view_options); - } - } - - $root->set_containing_block(0, 0, $this->_pdf->get_width(), $this->_pdf->get_height()); - $root->set_renderer(new Renderer($this)); - - // This is where the magic happens: - $root->reflow(); - - // Clean up cached images - Image_Cache::clear(); - - global $_dompdf_warnings, $_dompdf_show_warnings; - if ( $_dompdf_show_warnings ) { - echo 'DOMPDF Warnings
';
-      foreach ($_dompdf_warnings as $msg) {
-        echo $msg . "\n";
-      }
-      echo $this->get_canvas()->get_cpdf()->messages;
-      echo '
'; - flush(); - } - - $this->restore_locale(); - } - - /** - * Add meta information to the PDF after rendering - */ - function add_info($label, $value) { - if ( !is_null($this->_pdf) ) { - $this->_pdf->add_info($label, $value); - } - } - - /** - * Writes the output buffer in the log file - * - * @return void - */ - private function write_log() { - $log_output_file = $this->get_option("log_output_file"); - if ( !$log_output_file || !is_writable($log_output_file) ) { - return; - } - - $frames = Frame::$ID_COUNTER; - $memory = DOMPDF_memory_usage() / 1024; - $time = (microtime(true) - $this->_start_time) * 1000; - - $out = sprintf( - "%6d". - "%10.2f KB". - "%10.2f ms". - " ". - ($this->_quirksmode ? " ON" : "OFF"). - "
", $frames, $memory, $time); - - $out .= ob_get_clean(); - - $log_output_file = $this->get_option("log_output_file"); - file_put_contents($log_output_file, $out); - } - - /** - * Streams the PDF to the client - * - * The file will open a download dialog by default. The options - * parameter controls the output. Accepted options are: - * - * 'Accept-Ranges' => 1 or 0 - if this is not set to 1, then this - * header is not included, off by default this header seems to - * have caused some problems despite the fact that it is supposed - * to solve them, so I am leaving it off by default. - * - * 'compress' = > 1 or 0 - apply content stream compression, this is - * on (1) by default - * - * 'Attachment' => 1 or 0 - if 1, force the browser to open a - * download dialog, on (1) by default - * - * @param string $filename the name of the streamed file - * @param array $options header options (see above) - */ - function stream($filename, $options = null) { - $this->save_locale(); - - $this->write_log(); - - if ( !is_null($this->_pdf) ) { - $this->_pdf->stream($filename, $options); - } - - $this->restore_locale(); - } - - /** - * Returns the PDF as a string - * - * The file will open a download dialog by default. The options - * parameter controls the output. Accepted options are: - * - * - * 'compress' = > 1 or 0 - apply content stream compression, this is - * on (1) by default - * - * - * @param array $options options (see above) - * - * @return string - */ - function output($options = null) { - $this->save_locale(); - - $this->write_log(); - - if ( is_null($this->_pdf) ) { - return null; - } - - $output = $this->_pdf->output( $options ); - - $this->restore_locale(); - - return $output; - } - - /** - * Returns the underlying HTML document as a string - * - * @return string - */ - function output_html() { - return $this->_xml->saveHTML(); - } -} diff --git a/application/helpers/dompdf/include/dompdf_exception.cls.php b/application/helpers/dompdf/include/dompdf_exception.cls.php deleted file mode 100755 index ca47fa036..000000000 --- a/application/helpers/dompdf/include/dompdf_exception.cls.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Standard exception thrown by DOMPDF classes - * - * @package dompdf - */ -class DOMPDF_Exception extends Exception { - - /** - * Class constructor - * - * @param string $message Error message - * @param int $code Error code - */ - function __construct($message = null, $code = 0) { - parent::__construct($message, $code); - } - -} diff --git a/application/helpers/dompdf/include/dompdf_image_exception.cls.php b/application/helpers/dompdf/include/dompdf_image_exception.cls.php deleted file mode 100755 index 8fdecec52..000000000 --- a/application/helpers/dompdf/include/dompdf_image_exception.cls.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Image exception thrown by DOMPDF - * - * @package dompdf - */ -class DOMPDF_Image_Exception extends DOMPDF_Exception { - - /** - * Class constructor - * - * @param string $message Error message - * @param int $code Error code - */ - function __construct($message = null, $code = 0) { - parent::__construct($message, $code); - } - -} diff --git a/application/helpers/dompdf/include/file.skel b/application/helpers/dompdf/include/file.skel deleted file mode 100755 index 1f5fba936..000000000 --- a/application/helpers/dompdf/include/file.skel +++ /dev/null @@ -1,8 +0,0 @@ - - * @author ... - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ diff --git a/application/helpers/dompdf/include/fixed_positioner.cls.php b/application/helpers/dompdf/include/fixed_positioner.cls.php deleted file mode 100755 index 31a2a079c..000000000 --- a/application/helpers/dompdf/include/fixed_positioner.cls.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Positions fixely positioned frames - */ -class Fixed_Positioner extends Positioner { - - function __construct(Frame_Decorator $frame) { parent::__construct($frame); } - - function position() { - - $frame = $this->_frame; - $style = $frame->get_original_style(); - $root = $frame->get_root(); - $initialcb = $root->get_containing_block(); - $initialcb_style = $root->get_style(); - - $p = $frame->find_block_parent(); - if ( $p ) { - $p->add_line(); - } - - // Compute the margins of the @page style - $margin_top = $initialcb_style->length_in_pt($initialcb_style->margin_top, $initialcb["h"]); - $margin_right = $initialcb_style->length_in_pt($initialcb_style->margin_right, $initialcb["w"]); - $margin_bottom = $initialcb_style->length_in_pt($initialcb_style->margin_bottom, $initialcb["h"]); - $margin_left = $initialcb_style->length_in_pt($initialcb_style->margin_left, $initialcb["w"]); - - // The needed computed style of the element - $height = $style->length_in_pt($style->height, $initialcb["h"]); - $width = $style->length_in_pt($style->width, $initialcb["w"]); - - $top = $style->length_in_pt($style->top, $initialcb["h"]); - $right = $style->length_in_pt($style->right, $initialcb["w"]); - $bottom = $style->length_in_pt($style->bottom, $initialcb["h"]); - $left = $style->length_in_pt($style->left, $initialcb["w"]); - - $y = $margin_top; - if ( isset($top) ) { - $y = $top + $margin_top; - if ( $top === "auto" ) { - $y = $margin_top; - if ( isset($bottom) && $bottom !== "auto" ) { - $y = $initialcb["h"] - $bottom - $margin_bottom; - $margin_height = $this->_frame->get_margin_height(); - if ( $margin_height !== "auto" ) { - $y -= $margin_height; - } - else { - $y -= $height; - } - } - } - } - - $x = $margin_left; - if ( isset($left) ) { - $x = $left + $margin_left; - if ( $left === "auto" ) { - $x = $margin_left; - if ( isset($right) && $right !== "auto" ) { - $x = $initialcb["w"] - $right - $margin_right; - $margin_width = $this->_frame->get_margin_width(); - if ( $margin_width !== "auto" ) { - $x -= $margin_width; - } - else { - $x -= $width; - } - } - } - } - - $frame->set_position($x, $y); - - $children = $frame->get_children(); - foreach($children as $child) { - $child->set_position($x, $y); - } - } -} \ No newline at end of file diff --git a/application/helpers/dompdf/include/font_metrics.cls.php b/application/helpers/dompdf/include/font_metrics.cls.php deleted file mode 100755 index ad20d9119..000000000 --- a/application/helpers/dompdf/include/font_metrics.cls.php +++ /dev/null @@ -1,363 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -require_once DOMPDF_LIB_DIR . "/class.pdf.php"; - -/** - * Name of the font cache file - * - * This file must be writable by the webserver process only to update it - * with save_font_families() after adding the .afm file references of a new font family - * with Font_Metrics::save_font_families(). - * This is typically done only from command line with load_font.php on converting - * ttf fonts to ufm with php-font-lib. - * - * Declared here because PHP5 prevents constants from being declared with expressions - */ -define('__DOMPDF_FONT_CACHE_FILE', DOMPDF_FONT_DIR . "dompdf_font_family_cache.php"); - -/** - * The font metrics class - * - * This class provides information about fonts and text. It can resolve - * font names into actual installed font files, as well as determine the - * size of text in a particular font and size. - * - * @static - * @package dompdf - */ -class Font_Metrics { - - /** - * @see __DOMPDF_FONT_CACHE_FILE - */ - const CACHE_FILE = __DOMPDF_FONT_CACHE_FILE; - - /** - * Underlying {@link Canvas} object to perform text size calculations - * - * @var Canvas - */ - static protected $_pdf = null; - - /** - * Array of font family names to font files - * - * Usually cached by the {@link load_font.php} script - * - * @var array - */ - static protected $_font_lookup = array(); - - - /** - * Class initialization - * - */ - static function init(Canvas $canvas = null) { - if (!self::$_pdf) { - if (!$canvas) { - $canvas = Canvas_Factory::get_instance(new DOMPDF()); - } - - self::$_pdf = $canvas; - } - } - - /** - * Calculates text size, in points - * - * @param string $text the text to be sized - * @param string $font the desired font - * @param float $size the desired font size - * @param float $word_spacing - * @param float $char_spacing - * - * @internal param float $spacing word spacing, if any - * @return float - */ - static function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0) { - //return self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing); - - // @todo Make sure this cache is efficient before enabling it - static $cache = array(); - - if ( $text === "" ) { - return 0; - } - - // Don't cache long strings - $use_cache = !isset($text[50]); // Faster than strlen - - $key = "$font/$size/$word_spacing/$char_spacing"; - - if ( $use_cache && isset($cache[$key][$text]) ) { - return $cache[$key]["$text"]; - } - - $width = self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing); - - if ( $use_cache ) { - $cache[$key][$text] = $width; - } - - return $width; - } - - /** - * Calculates font height - * - * @param string $font - * @param float $size - * @return float - */ - static function get_font_height($font, $size) { - return self::$_pdf->get_font_height($font, $size); - } - - /** - * Resolves a font family & subtype into an actual font file - * Subtype can be one of 'normal', 'bold', 'italic' or 'bold_italic'. If - * the particular font family has no suitable font file, the default font - * ({@link DOMPDF_DEFAULT_FONT}) is used. The font file returned - * is the absolute pathname to the font file on the system. - * - * @param string $family_raw - * @param string $subtype_raw - * - * @return string - */ - static function get_font($family_raw, $subtype_raw = "normal") { - static $cache = array(); - - if ( isset($cache[$family_raw][$subtype_raw]) ) { - return $cache[$family_raw][$subtype_raw]; - } - - /* Allow calling for various fonts in search path. Therefore not immediately - * return replacement on non match. - * Only when called with NULL try replacement. - * When this is also missing there is really trouble. - * If only the subtype fails, nevertheless return failure. - * Only on checking the fallback font, check various subtypes on same font. - */ - - $subtype = strtolower($subtype_raw); - - if ( $family_raw ) { - $family = str_replace( array("'", '"'), "", strtolower($family_raw)); - - if ( isset(self::$_font_lookup[$family][$subtype]) ) { - return $cache[$family_raw][$subtype_raw] = self::$_font_lookup[$family][$subtype]; - } - - return null; - } - - $family = "serif"; - - if ( isset(self::$_font_lookup[$family][$subtype]) ) { - return $cache[$family_raw][$subtype_raw] = self::$_font_lookup[$family][$subtype]; - } - - if ( !isset(self::$_font_lookup[$family]) ) { - return null; - } - - $family = self::$_font_lookup[$family]; - - foreach ( $family as $sub => $font ) { - if (strpos($subtype, $sub) !== false) { - return $cache[$family_raw][$subtype_raw] = $font; - } - } - - if ($subtype !== "normal") { - foreach ( $family as $sub => $font ) { - if ($sub !== "normal") { - return $cache[$family_raw][$subtype_raw] = $font; - } - } - } - - $subtype = "normal"; - - if ( isset($family[$subtype]) ) { - return $cache[$family_raw][$subtype_raw] = $family[$subtype]; - } - - return null; - } - - static function get_family($family) { - $family = str_replace( array("'", '"'), "", mb_strtolower($family)); - - if ( isset(self::$_font_lookup[$family]) ) { - return self::$_font_lookup[$family]; - } - - return null; - } - - /** - * Saves the stored font family cache - * - * The name and location of the cache file are determined by {@link - * Font_Metrics::CACHE_FILE}. This file should be writable by the - * webserver process. - * - * @see Font_Metrics::load_font_families() - */ - static function save_font_families() { - // replace the path to the DOMPDF font directories with the corresponding constants (allows for more portability) - $cache_data = var_export(self::$_font_lookup, true); - $cache_data = str_replace('\''.DOMPDF_FONT_DIR , 'DOMPDF_FONT_DIR . \'' , $cache_data); - $cache_data = str_replace('\''.DOMPDF_DIR , 'DOMPDF_DIR . \'' , $cache_data); - $cache_data = "<"."?php return $cache_data ?".">"; - file_put_contents(self::CACHE_FILE, $cache_data); - } - - /** - * Loads the stored font family cache - * - * @see save_font_families() - */ - static function load_font_families() { - $dist_fonts = require_once DOMPDF_DIR . "/lib/fonts/dompdf_font_family_cache.dist.php"; - - // FIXME: temporary step for font cache created before the font cache fix - if ( is_readable( DOMPDF_FONT_DIR . "dompdf_font_family_cache" ) ) { - $old_fonts = require_once DOMPDF_FONT_DIR . "dompdf_font_family_cache"; - // If the font family cache is still in the old format - if ( $old_fonts === 1 ) { - $cache_data = file_get_contents(DOMPDF_FONT_DIR . "dompdf_font_family_cache"); - file_put_contents(DOMPDF_FONT_DIR . "dompdf_font_family_cache", "<"."?php return $cache_data ?".">"); - $old_fonts = require_once DOMPDF_FONT_DIR . "dompdf_font_family_cache"; - } - $dist_fonts += $old_fonts; - } - - if ( !is_readable(self::CACHE_FILE) ) { - self::$_font_lookup = $dist_fonts; - return; - } - - self::$_font_lookup = require_once self::CACHE_FILE; - - // If the font family cache is still in the old format - if ( self::$_font_lookup === 1 ) { - $cache_data = file_get_contents(self::CACHE_FILE); - file_put_contents(self::CACHE_FILE, "<"."?php return $cache_data ?".">"); - self::$_font_lookup = require_once self::CACHE_FILE; - } - - // Merge provided fonts - self::$_font_lookup += $dist_fonts; - } - - static function get_type($type) { - if (preg_match("/bold/i", $type)) { - if (preg_match("/italic|oblique/i", $type)) { - $type = "bold_italic"; - } - else { - $type = "bold"; - } - } - elseif (preg_match("/italic|oblique/i", $type)) { - $type = "italic"; - } - else { - $type = "normal"; - } - - return $type; - } - - static function install_fonts($files) { - $names = array(); - - foreach($files as $file) { - $font = Font::load($file); - $records = $font->getData("name", "records"); - $type = self::get_type($records[2]); - $names[mb_strtolower($records[1])][$type] = $file; - } - - return $names; - } - - static function get_system_fonts() { - $files = glob("/usr/share/fonts/truetype/*.ttf") + - glob("/usr/share/fonts/truetype/*/*.ttf") + - glob("/usr/share/fonts/truetype/*/*/*.ttf") + - glob("C:\\Windows\\fonts\\*.ttf") + - glob("C:\\WinNT\\fonts\\*.ttf") + - glob("/mnt/c_drive/WINDOWS/Fonts/"); - - return self::install_fonts($files); - } - - /** - * Returns the current font lookup table - * - * @return array - */ - static function get_font_families() { - return self::$_font_lookup; - } - - static function set_font_family($fontname, $entry) { - self::$_font_lookup[mb_strtolower($fontname)] = $entry; - } - - static function register_font($style, $remote_file) { - $fontname = mb_strtolower($style["family"]); - $families = Font_Metrics::get_font_families(); - - $entry = array(); - if ( isset($families[$fontname]) ) { - $entry = $families[$fontname]; - } - - $local_file = DOMPDF_FONT_DIR . md5($remote_file); - $cache_entry = $local_file; - $local_file .= ".ttf"; - - $style_string = Font_Metrics::get_type("{$style['weight']} {$style['style']}"); - - if ( !isset($entry[$style_string]) ) { - $entry[$style_string] = $cache_entry; - - Font_Metrics::set_font_family($fontname, $entry); - - // Download the remote file - if ( !is_file($local_file) ) { - file_put_contents($local_file, file_get_contents($remote_file)); - } - - $font = Font::load($local_file); - - if (!$font) { - return false; - } - - $font->parse(); - $font->saveAdobeFontMetrics("$cache_entry.ufm"); - - // Save the changes - Font_Metrics::save_font_families(); - } - - return true; - } -} - -Font_Metrics::load_font_families(); diff --git a/application/helpers/dompdf/include/frame.cls.php b/application/helpers/dompdf/include/frame.cls.php deleted file mode 100755 index bc2f26d40..000000000 --- a/application/helpers/dompdf/include/frame.cls.php +++ /dev/null @@ -1,1191 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * The main Frame class - * - * This class represents a single HTML element. This class stores - * positioning information as well as containing block location and - * dimensions. Style information for the element is stored in a {@link - * Style} object. Tree structure is maintained via the parent & children - * links. - * - * @access protected - * @package dompdf - */ -class Frame { - - /** - * The DOMElement or DOMText object this frame represents - * - * @var DOMElement|DOMText - */ - protected $_node; - - /** - * Unique identifier for this frame. Used to reference this frame - * via the node. - * - * @var string - */ - protected $_id; - - /** - * Unique id counter - */ - static /*protected*/ $ID_COUNTER = 0; - - /** - * This frame's calculated style - * - * @var Style - */ - protected $_style; - - /** - * This frame's original style. Needed for cases where frames are - * split across pages. - * - * @var Style - */ - protected $_original_style; - - /** - * This frame's parent in the document tree. - * - * @var Frame - */ - protected $_parent; - - /** - * This frame's children - * - * @var Frame[] - */ - protected $_frame_list; - - /** - * This frame's first child. All children are handled as a - * doubly-linked list. - * - * @var Frame - */ - protected $_first_child; - - /** - * This frame's last child. - * - * @var Frame - */ - protected $_last_child; - - /** - * This frame's previous sibling in the document tree. - * - * @var Frame - */ - protected $_prev_sibling; - - /** - * This frame's next sibling in the document tree. - * - * @var Frame - */ - protected $_next_sibling; - - /** - * This frame's containing block (used in layout): array(x, y, w, h) - * - * @var float[] - */ - protected $_containing_block; - - /** - * Position on the page of the top-left corner of the margin box of - * this frame: array(x,y) - * - * @var float[] - */ - protected $_position; - - /** - * Absolute opacity of this frame - * - * @var float - */ - protected $_opacity; - - /** - * This frame's decorator - * - * @var Frame_Decorator - */ - protected $_decorator; - - /** - * This frame's containing line box - * - * @var Line_Box - */ - protected $_containing_line; - - protected $_is_cache = array(); - - /** - * Tells wether the frame was already pushed to the next page - * - * @var bool - */ - public $_already_pushed = false; - - public $_float_next_line = false; - - /** - * Tells wether the frame was split - * - * @var bool - */ - public $_splitted; - - static $_ws_state = self::WS_SPACE; - - const WS_TEXT = 1; - const WS_SPACE = 2; - - /** - * Class destructor - */ - function __destruct() { - clear_object($this); - } - - /** - * Class constructor - * - * @param DOMNode $node the DOMNode this frame represents - */ - function __construct(DOMNode $node) { - $this->_node = $node; - - $this->_parent = null; - $this->_first_child = null; - $this->_last_child = null; - $this->_prev_sibling = $this->_next_sibling = null; - - $this->_style = null; - $this->_original_style = null; - - $this->_containing_block = array( - "x" => null, - "y" => null, - "w" => null, - "h" => null, - ); - - $this->_containing_block[0] =& $this->_containing_block["x"]; - $this->_containing_block[1] =& $this->_containing_block["y"]; - $this->_containing_block[2] =& $this->_containing_block["w"]; - $this->_containing_block[3] =& $this->_containing_block["h"]; - - $this->_position = array( - "x" => null, - "y" => null, - ); - - $this->_position[0] =& $this->_position["x"]; - $this->_position[1] =& $this->_position["y"]; - - $this->_opacity = 1.0; - $this->_decorator = null; - - $this->set_id( self::$ID_COUNTER++ ); - } - - // WIP : preprocessing to remove all the unused whitespace - protected function ws_trim(){ - if ( $this->ws_keep() ) { - return; - } - - switch(self::$_ws_state) { - case self::WS_SPACE: - $node = $this->_node; - - if ( $node->nodeName === "#text" ) { - $node->nodeValue = preg_replace("/[ \t\r\n\f]+/u", " ", $node->nodeValue); - - // starts with a whitespace - if ( isset($node->nodeValue[0]) && $node->nodeValue[0] === " " ) { - $node->nodeValue = ltrim($node->nodeValue); - } - - // if not empty - if ( $node->nodeValue !== "" ) { - // change the current state (text) - self::$_ws_state = self::WS_TEXT; - - // ends with a whitespace - if ( preg_match("/[ \t\r\n\f]+$/u", $node->nodeValue) ) { - $node->nodeValue = ltrim($node->nodeValue); - } - } - } - break; - - case self::WS_TEXT: - } - } - - protected function ws_keep(){ - $whitespace = $this->get_style()->white_space; - return in_array($whitespace, array("pre", "pre-wrap", "pre-line")); - } - - protected function ws_is_text(){ - $node = $this->get_node(); - - if ($node->nodeName === "img") { - return true; - } - - if ( !$this->is_in_flow() ) { - return false; - } - - if ($this->is_text_node()) { - return trim($node->nodeValue) !== ""; - } - - return true; - } - - /** - * "Destructor": forcibly free all references held by this frame - * - * @param bool $recursive if true, call dispose on all children - */ - function dispose($recursive = false) { - - if ( $recursive ) { - while ( $child = $this->_first_child ) { - $child->dispose(true); - } - } - - // Remove this frame from the tree - if ( $this->_prev_sibling ) { - $this->_prev_sibling->_next_sibling = $this->_next_sibling; - } - - if ( $this->_next_sibling ) { - $this->_next_sibling->_prev_sibling = $this->_prev_sibling; - } - - if ( $this->_parent && $this->_parent->_first_child === $this ) { - $this->_parent->_first_child = $this->_next_sibling; - } - - if ( $this->_parent && $this->_parent->_last_child === $this ) { - $this->_parent->_last_child = $this->_prev_sibling; - } - - if ( $this->_parent ) { - $this->_parent->get_node()->removeChild($this->_node); - } - - $this->_style->dispose(); - $this->_style = null; - unset($this->_style); - - $this->_original_style->dispose(); - $this->_original_style = null; - unset($this->_original_style); - - } - - // Re-initialize the frame - function reset() { - $this->_position["x"] = null; - $this->_position["y"] = null; - - $this->_containing_block["x"] = null; - $this->_containing_block["y"] = null; - $this->_containing_block["w"] = null; - $this->_containing_block["h"] = null; - - $this->_style = null; - unset($this->_style); - $this->_style = clone $this->_original_style; - } - - //........................................................................ - - /** - * @return DOMElement|DOMText - */ - function get_node() { - return $this->_node; - } - - /** - * @return string - */ - function get_id() { - return $this->_id; - } - - /** - * @return Style - */ - function get_style() { - return $this->_style; - } - - /** - * @return Style - */ - function get_original_style() { - return $this->_original_style; - } - - /** - * @return Frame - */ - function get_parent() { - return $this->_parent; - } - - /** - * @return Frame_Decorator - */ - function get_decorator() { - return $this->_decorator; - } - - /** - * @return Frame - */ - function get_first_child() { - return $this->_first_child; - } - - /** - * @return Frame - */ - function get_last_child() { - return $this->_last_child; - } - - /** - * @return Frame - */ - function get_prev_sibling() { - return $this->_prev_sibling; - } - - /** - * @return Frame - */ - function get_next_sibling() { - return $this->_next_sibling; - } - - /** - * @return FrameList|Frame[] - */ - function get_children() { - if ( isset($this->_frame_list) ) { - return $this->_frame_list; - } - - $this->_frame_list = new FrameList($this); - return $this->_frame_list; - } - - // Layout property accessors - - /** - * Containing block dimensions - * - * @param $i string The key of the wanted containing block's dimension (x, y, x, h) - * - * @return float[]|float - */ - function get_containing_block($i = null) { - if ( isset($i) ) { - return $this->_containing_block[$i]; - } - return $this->_containing_block; - } - - /** - * Block position - * - * @param $i string The key of the wanted position value (x, y) - * - * @return array|float - */ - function get_position($i = null) { - if ( isset($i) ) { - return $this->_position[$i]; - } - return $this->_position; - } - - //........................................................................ - - /** - * Return the height of the margin box of the frame, in pt. Meaningless - * unless the height has been calculated properly. - * - * @return float - */ - function get_margin_height() { - $style = $this->_style; - - return $style->length_in_pt(array( - $style->height, - $style->margin_top, - $style->margin_bottom, - $style->border_top_width, - $style->border_bottom_width, - $style->padding_top, - $style->padding_bottom - ), $this->_containing_block["h"]); - } - - /** - * Return the width of the margin box of the frame, in pt. Meaningless - * unless the width has been calculated properly. - * - * @return float - */ - function get_margin_width() { - $style = $this->_style; - - return $style->length_in_pt(array( - $style->width, - $style->margin_left, - $style->margin_right, - $style->border_left_width, - $style->border_right_width, - $style->padding_left, - $style->padding_right - ), $this->_containing_block["w"]); - } - - function get_break_margins(){ - $style = $this->_style; - - return $style->length_in_pt(array( - //$style->height, - $style->margin_top, - $style->margin_bottom, - $style->border_top_width, - $style->border_bottom_width, - $style->padding_top, - $style->padding_bottom - ), $this->_containing_block["h"]); - } - - /** - * Return the padding box (x,y,w,h) of the frame - * - * @return array - */ - function get_padding_box() { - $style = $this->_style; - $cb = $this->_containing_block; - - $x = $this->_position["x"] + - $style->length_in_pt(array($style->margin_left, - $style->border_left_width), - $cb["w"]); - - $y = $this->_position["y"] + - $style->length_in_pt(array($style->margin_top, - $style->border_top_width), - $cb["h"]); - - $w = $style->length_in_pt(array($style->padding_left, - $style->width, - $style->padding_right), - $cb["w"]); - - $h = $style->length_in_pt(array($style->padding_top, - $style->height, - $style->padding_bottom), - $cb["h"]); - - return array(0 => $x, "x" => $x, - 1 => $y, "y" => $y, - 2 => $w, "w" => $w, - 3 => $h, "h" => $h); - } - - /** - * Return the border box of the frame - * - * @return array - */ - function get_border_box() { - $style = $this->_style; - $cb = $this->_containing_block; - - $x = $this->_position["x"] + $style->length_in_pt($style->margin_left, $cb["w"]); - - $y = $this->_position["y"] + $style->length_in_pt($style->margin_top, $cb["h"]); - - $w = $style->length_in_pt(array($style->border_left_width, - $style->padding_left, - $style->width, - $style->padding_right, - $style->border_right_width), - $cb["w"]); - - $h = $style->length_in_pt(array($style->border_top_width, - $style->padding_top, - $style->height, - $style->padding_bottom, - $style->border_bottom_width), - $cb["h"]); - - return array(0 => $x, "x" => $x, - 1 => $y, "y" => $y, - 2 => $w, "w" => $w, - 3 => $h, "h" => $h); - } - - function get_opacity($opacity = null) { - if ( $opacity !== null ) { - $this->set_opacity($opacity); - } - return $this->_opacity; - } - - /** - * @return Line_Box - */ - function &get_containing_line() { - return $this->_containing_line; - } - - //........................................................................ - - // Set methods - function set_id($id) { - $this->_id = $id; - - // We can only set attributes of DOMElement objects (nodeType == 1). - // Since these are the only objects that we can assign CSS rules to, - // this shortcoming is okay. - if ( $this->_node->nodeType == XML_ELEMENT_NODE ) { - $this->_node->setAttribute("frame_id", $id); - } - } - - function set_style(Style $style) { - if ( is_null($this->_style) ) { - $this->_original_style = clone $style; - } - - //$style->set_frame($this); - $this->_style = $style; - } - - function set_decorator(Frame_Decorator $decorator) { - $this->_decorator = $decorator; - } - - function set_containing_block($x = null, $y = null, $w = null, $h = null) { - if ( is_array($x) ){ - foreach($x as $key => $val){ - $$key = $val; - } - } - - if (is_numeric($x)) { - $this->_containing_block["x"] = $x; - } - - if (is_numeric($y)) { - $this->_containing_block["y"] = $y; - } - - if (is_numeric($w)) { - $this->_containing_block["w"] = $w; - } - - if (is_numeric($h)) { - $this->_containing_block["h"] = $h; - } - } - - function set_position($x = null, $y = null) { - if ( is_array($x) ) { - list($x, $y) = array($x["x"], $x["y"]); - } - - if ( is_numeric($x) ) { - $this->_position["x"] = $x; - } - - if ( is_numeric($y) ) { - $this->_position["y"] = $y; - } - } - - function set_opacity($opacity) { - $parent = $this->get_parent(); - $base_opacity = (($parent && $parent->_opacity !== null) ? $parent->_opacity : 1.0); - $this->_opacity = $base_opacity * $opacity; - } - - function set_containing_line(Line_Box $line) { - $this->_containing_line = $line; - } - - //........................................................................ - - /** - * Tells if the frame is a text node - * @return bool - */ - function is_text_node() { - if ( isset($this->_is_cache["text_node"]) ) { - return $this->_is_cache["text_node"]; - } - - return $this->_is_cache["text_node"] = ($this->get_node()->nodeName === "#text"); - } - - function is_positionned() { - if ( isset($this->_is_cache["positionned"]) ) { - return $this->_is_cache["positionned"]; - } - - $position = $this->get_style()->position; - - return $this->_is_cache["positionned"] = in_array($position, Style::$POSITIONNED_TYPES); - } - - function is_absolute() { - if ( isset($this->_is_cache["absolute"]) ) { - return $this->_is_cache["absolute"]; - } - - $position = $this->get_style()->position; - - return $this->_is_cache["absolute"] = ($position === "absolute" || $position === "fixed"); - } - - function is_block() { - if ( isset($this->_is_cache["block"]) ) { - return $this->_is_cache["block"]; - } - - return $this->_is_cache["block"] = in_array($this->get_style()->display, Style::$BLOCK_TYPES); - } - - function is_in_flow() { - if ( isset($this->_is_cache["in_flow"]) ) { - return $this->_is_cache["in_flow"]; - } - - $enable_css_float = $this->get_style()->get_stylesheet()->get_dompdf()->get_option("enable_css_float"); - return $this->_is_cache["in_flow"] = !($enable_css_float && $this->get_style()->float !== "none" || $this->is_absolute()); - } - - function is_pre(){ - if ( isset($this->_is_cache["pre"]) ) { - return $this->_is_cache["pre"]; - } - - $white_space = $this->get_style()->white_space; - - return $this->_is_cache["pre"] = in_array($white_space, array("pre", "pre-wrap")); - } - - function is_table(){ - if ( isset($this->_is_cache["table"]) ) { - return $this->_is_cache["table"]; - } - - $display = $this->get_style()->display; - - return $this->_is_cache["table"] = in_array($display, Style::$TABLE_TYPES); - } - - - /** - * Inserts a new child at the beginning of the Frame - * - * @param $child Frame The new Frame to insert - * @param $update_node boolean Whether or not to update the DOM - */ - function prepend_child(Frame $child, $update_node = true) { - if ( $update_node ) { - $this->_node->insertBefore($child->_node, $this->_first_child ? $this->_first_child->_node : null); - } - - // Remove the child from its parent - if ( $child->_parent ) { - $child->_parent->remove_child($child, false); - } - - $child->_parent = $this; - $child->_prev_sibling = null; - - // Handle the first child - if ( !$this->_first_child ) { - $this->_first_child = $child; - $this->_last_child = $child; - $child->_next_sibling = null; - } - else { - $this->_first_child->_prev_sibling = $child; - $child->_next_sibling = $this->_first_child; - $this->_first_child = $child; - } - } - - /** - * Inserts a new child at the end of the Frame - * - * @param $child Frame The new Frame to insert - * @param $update_node boolean Whether or not to update the DOM - */ - function append_child(Frame $child, $update_node = true) { - if ( $update_node ) { - $this->_node->appendChild($child->_node); - } - - // Remove the child from its parent - if ( $child->_parent ) { - $child->_parent->remove_child($child, false); - } - - $child->_parent = $this; - $child->_next_sibling = null; - - // Handle the first child - if ( !$this->_last_child ) { - $this->_first_child = $child; - $this->_last_child = $child; - $child->_prev_sibling = null; - } - else { - $this->_last_child->_next_sibling = $child; - $child->_prev_sibling = $this->_last_child; - $this->_last_child = $child; - } - } - - /** - * Inserts a new child immediately before the specified frame - * - * @param $new_child Frame The new Frame to insert - * @param $ref Frame The Frame after the new Frame - * @param $update_node boolean Whether or not to update the DOM - * - * @throws DOMPDF_Exception - */ - function insert_child_before(Frame $new_child, Frame $ref, $update_node = true) { - if ( $ref === $this->_first_child ) { - $this->prepend_child($new_child, $update_node); - return; - } - - if ( is_null($ref) ) { - $this->append_child($new_child, $update_node); - return; - } - - if ( $ref->_parent !== $this ) { - throw new DOMPDF_Exception("Reference child is not a child of this node."); - } - - // Update the node - if ( $update_node ) { - $this->_node->insertBefore($new_child->_node, $ref->_node); - } - - // Remove the child from its parent - if ( $new_child->_parent ) { - $new_child->_parent->remove_child($new_child, false); - } - - $new_child->_parent = $this; - $new_child->_next_sibling = $ref; - $new_child->_prev_sibling = $ref->_prev_sibling; - - if ( $ref->_prev_sibling ) { - $ref->_prev_sibling->_next_sibling = $new_child; - } - - $ref->_prev_sibling = $new_child; - } - - /** - * Inserts a new child immediately after the specified frame - * - * @param $new_child Frame The new Frame to insert - * @param $ref Frame The Frame before the new Frame - * @param $update_node boolean Whether or not to update the DOM - * - * @throws DOMPDF_Exception - */ - function insert_child_after(Frame $new_child, Frame $ref, $update_node = true) { - if ( $ref === $this->_last_child ) { - $this->append_child($new_child, $update_node); - return; - } - - if ( is_null($ref) ) { - $this->prepend_child($new_child, $update_node); - return; - } - - if ( $ref->_parent !== $this ) { - throw new DOMPDF_Exception("Reference child is not a child of this node."); - } - - // Update the node - if ( $update_node ) { - if ( $ref->_next_sibling ) { - $next_node = $ref->_next_sibling->_node; - $this->_node->insertBefore($new_child->_node, $next_node); - } - else { - $new_child->_node = $this->_node->appendChild($new_child->_node); - } - } - - // Remove the child from its parent - if ( $new_child->_parent ) { - $new_child->_parent->remove_child($new_child, false); - } - - $new_child->_parent = $this; - $new_child->_prev_sibling = $ref; - $new_child->_next_sibling = $ref->_next_sibling; - - if ( $ref->_next_sibling ) { - $ref->_next_sibling->_prev_sibling = $new_child; - } - - $ref->_next_sibling = $new_child; - } - - - /** - * Remove a child frame - * - * @param Frame $child - * @param boolean $update_node Whether or not to remove the DOM node - * - * @throws DOMPDF_Exception - * @return Frame The removed child frame - */ - function remove_child(Frame $child, $update_node = true) { - if ( $child->_parent !== $this ) { - throw new DOMPDF_Exception("Child not found in this frame"); - } - - if ( $update_node ) { - $this->_node->removeChild($child->_node); - } - - if ( $child === $this->_first_child ) { - $this->_first_child = $child->_next_sibling; - } - - if ( $child === $this->_last_child ) { - $this->_last_child = $child->_prev_sibling; - } - - if ( $child->_prev_sibling ) { - $child->_prev_sibling->_next_sibling = $child->_next_sibling; - } - - if ( $child->_next_sibling ) { - $child->_next_sibling->_prev_sibling = $child->_prev_sibling; - } - - $child->_next_sibling = null; - $child->_prev_sibling = null; - $child->_parent = null; - return $child; - } - - //........................................................................ - - // Debugging function: - function __toString() { - // Skip empty text frames -// if ( $this->is_text_node() && -// preg_replace("/\s/", "", $this->_node->data) === "" ) -// return ""; - - - $str = "" . $this->_node->nodeName . ":
"; - //$str .= spl_object_hash($this->_node) . "
"; - $str .= "Id: " .$this->get_id() . "
"; - $str .= "Class: " .get_class($this) . "
"; - - if ( $this->is_text_node() ) { - $tmp = htmlspecialchars($this->_node->nodeValue); - $str .= "
'" .  mb_substr($tmp,0,70) .
-        (mb_strlen($tmp) > 70 ? "..." : "") . "'
"; - } - elseif ( $css_class = $this->_node->getAttribute("class") ) { - $str .= "CSS class: '$css_class'
"; - } - - if ( $this->_parent ) { - $str .= "\nParent:" . $this->_parent->_node->nodeName . - " (" . spl_object_hash($this->_parent->_node) . ") " . - "
"; - } - - if ( $this->_prev_sibling ) { - $str .= "Prev: " . $this->_prev_sibling->_node->nodeName . - " (" . spl_object_hash($this->_prev_sibling->_node) . ") " . - "
"; - } - - if ( $this->_next_sibling ) { - $str .= "Next: " . $this->_next_sibling->_node->nodeName . - " (" . spl_object_hash($this->_next_sibling->_node) . ") " . - "
"; - } - - $d = $this->get_decorator(); - while ($d && $d != $d->get_decorator()) { - $str .= "Decorator: " . get_class($d) . "
"; - $d = $d->get_decorator(); - } - - $str .= "Position: " . pre_r($this->_position, true); - $str .= "\nContaining block: " . pre_r($this->_containing_block, true); - $str .= "\nMargin width: " . pre_r($this->get_margin_width(), true); - $str .= "\nMargin height: " . pre_r($this->get_margin_height(), true); - - $str .= "\nStyle:
". $this->_style->__toString() . "
"; - - if ( $this->_decorator instanceof Block_Frame_Decorator ) { - $str .= "Lines:
";
-      foreach ($this->_decorator->get_line_boxes() as $line) {
-        foreach ($line->get_frames() as $frame) {
-          if ($frame instanceof Text_Frame_Decorator) {
-            $str .= "\ntext: ";
-            $str .= "'". htmlspecialchars($frame->get_text()) ."'";
-          }
-          else {
-            $str .= "\nBlock: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")";
-          }
-        }
-
-        $str .=
-          "\ny => " . $line->y . "\n" .
-          "w => " . $line->w . "\n" .
-          "h => " . $line->h . "\n" .
-          "left => " . $line->left . "\n" .
-          "right => " . $line->right . "\n";
-      }
-      $str .= "
"; - } - - $str .= "\n"; - if ( php_sapi_name() === "cli" ) { - $str = strip_tags(str_replace(array("
","",""), - array("\n","",""), - $str)); - } - - return $str; - } -} - -//------------------------------------------------------------------------ - -/** - * Linked-list IteratorAggregate - * - * @access private - * @package dompdf - */ -class FrameList implements IteratorAggregate { - protected $_frame; - - function __construct($frame) { $this->_frame = $frame; } - function getIterator() { return new FrameListIterator($this->_frame); } -} - -/** - * Linked-list Iterator - * - * Returns children in order and allows for list to change during iteration, - * provided the changes occur to or after the current element - * - * @access private - * @package dompdf - */ -class FrameListIterator implements Iterator { - - /** - * @var Frame - */ - protected $_parent; - - /** - * @var Frame - */ - protected $_cur; - - /** - * @var int - */ - protected $_num; - - function __construct(Frame $frame) { - $this->_parent = $frame; - $this->_cur = $frame->get_first_child(); - $this->_num = 0; - } - - function rewind() { - $this->_cur = $this->_parent->get_first_child(); - $this->_num = 0; - } - - /** - * @return bool - */ - function valid() { - return isset($this->_cur);// && ($this->_cur->get_prev_sibling() === $this->_prev); - } - - function key() { return $this->_num; } - - /** - * @return Frame - */ - function current() { return $this->_cur; } - - /** - * @return Frame - */ - function next() { - - $ret = $this->_cur; - if ( !$ret ) { - return null; - } - - $this->_cur = $this->_cur->get_next_sibling(); - $this->_num++; - return $ret; - } -} - -//------------------------------------------------------------------------ - -/** - * Pre-order IteratorAggregate - * - * @access private - * @package dompdf - */ -class FrameTreeList implements IteratorAggregate { - /** - * @var Frame - */ - protected $_root; - - function __construct(Frame $root) { $this->_root = $root; } - - /** - * @return FrameTreeIterator - */ - function getIterator() { return new FrameTreeIterator($this->_root); } -} - -/** - * Pre-order Iterator - * - * Returns frames in preorder traversal order (parent then children) - * - * @access private - * @package dompdf - */ -class FrameTreeIterator implements Iterator { - /** - * @var Frame - */ - protected $_root; - protected $_stack = array(); - - /** - * @var int - */ - protected $_num; - - function __construct(Frame $root) { - $this->_stack[] = $this->_root = $root; - $this->_num = 0; - } - - function rewind() { - $this->_stack = array($this->_root); - $this->_num = 0; - } - - /** - * @return bool - */ - function valid() { - return count($this->_stack) > 0; - } - - /** - * @return int - */ - function key() { - return $this->_num; - } - - /** - * @return Frame - */ - function current() { - return end($this->_stack); - } - - /** - * @return Frame - */ - function next() { - $b = end($this->_stack); - - // Pop last element - unset($this->_stack[ key($this->_stack) ]); - $this->_num++; - - // Push all children onto the stack in reverse order - if ( $c = $b->get_last_child() ) { - $this->_stack[] = $c; - while ( $c = $c->get_prev_sibling() ) { - $this->_stack[] = $c; - } - } - - return $b; - } -} - diff --git a/application/helpers/dompdf/include/frame_decorator.cls.php b/application/helpers/dompdf/include/frame_decorator.cls.php deleted file mode 100755 index 987e32ee1..000000000 --- a/application/helpers/dompdf/include/frame_decorator.cls.php +++ /dev/null @@ -1,717 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Base Frame_Decorator class - * - * @access private - * @package dompdf - */ -abstract class Frame_Decorator extends Frame { - const DEFAULT_COUNTER = "-dompdf-default-counter"; - - public $_counters = array(); // array([id] => counter_value) (for generated content) - - /** - * The root node of the DOM tree - * - * @var Frame - */ - protected $_root; - - /** - * The decorated frame - * - * @var Frame - */ - protected $_frame; - - /** - * Positioner object used to position this frame (Strategy pattern) - * - * @var Positioner - */ - protected $_positioner; - - /** - * Reflower object used to calculate frame dimensions (Strategy pattern) - * - * @var Frame_Reflower - */ - protected $_reflower; - - /** - * Reference to the current dompdf instance - * - * @var DOMPDF - */ - protected $_dompdf; - - /** - * First block parent - * - * @var Block_Frame_Decorator - */ - private $_block_parent; - - /** - * First positionned parent (position: relative | absolute | fixed) - * - * @var Frame_Decorator - */ - private $_positionned_parent; - - /** - * Class constructor - * - * @param Frame $frame The decoration target - * @param DOMPDF $dompdf The DOMPDF object - */ - function __construct(Frame $frame, DOMPDF $dompdf) { - $this->_frame = $frame; - $this->_root = null; - $this->_dompdf = $dompdf; - $frame->set_decorator($this); - } - - /** - * "Destructor": foribly free all references held by this object - * - * @param bool $recursive if true, call dispose on all children - */ - function dispose($recursive = false) { - if ( $recursive ) { - while ( $child = $this->get_first_child() ) { - $child->dispose(true); - } - } - - $this->_root = null; - unset($this->_root); - - $this->_frame->dispose(true); - $this->_frame = null; - unset($this->_frame); - - $this->_positioner = null; - unset($this->_positioner); - - $this->_reflower = null; - unset($this->_reflower); - } - - /** - * Return a copy of this frame with $node as its node - * - * @param DOMNode $node - * - * @return Frame - */ - function copy(DOMNode $node) { - $frame = new Frame($node); - $frame->set_style(clone $this->_frame->get_original_style()); - - return Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root); - } - - /** - * Create a deep copy: copy this node and all children - * - * @return Frame - */ - function deep_copy() { - $frame = new Frame($this->get_node()->cloneNode()); - $frame->set_style(clone $this->_frame->get_original_style()); - - $deco = Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root); - - foreach ($this->get_children() as $child) { - $deco->append_child($child->deep_copy()); - } - - return $deco; - } - - /** - * Delegate calls to decorated frame object - */ - function reset() { - $this->_frame->reset(); - - $this->_counters = array(); - - // Reset all children - foreach ($this->get_children() as $child) { - $child->reset(); - } - } - - // Getters ----------- - function get_id() { - return $this->_frame->get_id(); - } - - /** - * @return Frame - */ - function get_frame() { - return $this->_frame; - } - - /** - * @return DOMElement|DOMText - */ - function get_node() { - return $this->_frame->get_node(); - } - - /** - * @return Style - */ - function get_style() { - return $this->_frame->get_style(); - } - - /** - * @return Style - */ - function get_original_style() { - return $this->_frame->get_original_style(); - } - - /** - * @param integer $i - * - * @return array|float - */ - function get_containing_block($i = null) { - return $this->_frame->get_containing_block($i); - } - - /** - * @param integer $i - * - * @return array|float - */ - function get_position($i = null) { - return $this->_frame->get_position($i); - } - - /** - * @return DOMPDF - */ - function get_dompdf() { - return $this->_dompdf; - } - - /** - * @return float - */ - function get_margin_height() { - return $this->_frame->get_margin_height(); - } - - /** - * @return float - */ - function get_margin_width() { - return $this->_frame->get_margin_width(); - } - - /** - * @return array - */ - function get_padding_box() { - return $this->_frame->get_padding_box(); - } - - /** - * @return array - */ - function get_border_box() { - return $this->_frame->get_border_box(); - } - - /** - * @param integer $id - */ - function set_id($id) { - $this->_frame->set_id($id); - } - - /** - * @param Style $style - */ - function set_style(Style $style) { - $this->_frame->set_style($style); - } - - /** - * @param float $x - * @param float $y - * @param float $w - * @param float $h - */ - function set_containing_block($x = null, $y = null, $w = null, $h = null) { - $this->_frame->set_containing_block($x, $y, $w, $h); - } - - /** - * @param float $x - * @param float $y - */ - function set_position($x = null, $y = null) { - $this->_frame->set_position($x, $y); - } - - /** - * @return string - */ - function __toString() { - return $this->_frame->__toString(); - } - - /** - * @param Frame $child - * @param bool $update_node - */ - function prepend_child(Frame $child, $update_node = true) { - while ( $child instanceof Frame_Decorator ) { - $child = $child->_frame; - } - - $this->_frame->prepend_child($child, $update_node); - } - - /** - * @param Frame $child - * @param bool $update_node - */ - function append_child(Frame $child, $update_node = true) { - while ( $child instanceof Frame_Decorator ) { - $child = $child->_frame; - } - - $this->_frame->append_child($child, $update_node); - } - - /** - * @param Frame $new_child - * @param Frame $ref - * @param bool $update_node - */ - function insert_child_before(Frame $new_child, Frame $ref, $update_node = true) { - while ( $new_child instanceof Frame_Decorator ) { - $new_child = $new_child->_frame; - } - - if ( $ref instanceof Frame_Decorator ) { - $ref = $ref->_frame; - } - - $this->_frame->insert_child_before($new_child, $ref, $update_node); - } - - /** - * @param Frame $new_child - * @param Frame $ref - * @param bool $update_node - */ - function insert_child_after(Frame $new_child, Frame $ref, $update_node = true) { - while ( $new_child instanceof Frame_Decorator ) { - $new_child = $new_child->_frame; - } - - while ( $ref instanceof Frame_Decorator ) { - $ref = $ref->_frame; - } - - $this->_frame->insert_child_after($new_child, $ref, $update_node); - } - - /** - * @param Frame $child - * @param bool $update_node - * - * @return Frame - */ - function remove_child(Frame $child, $update_node = true) { - while ( $child instanceof Frame_Decorator ) { - $child = $child->_frame; - } - - return $this->_frame->remove_child($child, $update_node); - } - - /** - * @return Frame_Decorator - */ - function get_parent() { - $p = $this->_frame->get_parent(); - if ( $p && $deco = $p->get_decorator() ) { - while ( $tmp = $deco->get_decorator() ) { - $deco = $tmp; - } - - return $deco; - } - else if ( $p ) { - return $p; - } - - return null; - } - - /** - * @return Frame_Decorator - */ - function get_first_child() { - $c = $this->_frame->get_first_child(); - if ( $c && $deco = $c->get_decorator() ) { - while ( $tmp = $deco->get_decorator() ) { - $deco = $tmp; - } - - return $deco; - } - else if ( $c ) { - return $c; - } - - return null; - } - - /** - * @return Frame_Decorator - */ - function get_last_child() { - $c = $this->_frame->get_last_child(); - if ( $c && $deco = $c->get_decorator() ) { - while ( $tmp = $deco->get_decorator() ) { - $deco = $tmp; - } - - return $deco; - } - else if ( $c ) { - return $c; - } - - return null; - } - - /** - * @return Frame_Decorator - */ - function get_prev_sibling() { - $s = $this->_frame->get_prev_sibling(); - if ( $s && $deco = $s->get_decorator() ) { - while ( $tmp = $deco->get_decorator() ) { - $deco = $tmp; - } - return $deco; - } - else if ( $s ) { - return $s; - } - - return null; - } - - /** - * @return Frame_Decorator - */ - function get_next_sibling() { - $s = $this->_frame->get_next_sibling(); - if ( $s && $deco = $s->get_decorator() ) { - while ( $tmp = $deco->get_decorator() ) { - $deco = $tmp; - } - - return $deco; - } - else if ( $s ) { - return $s; - } - - return null; - } - - /** - * @return FrameTreeList - */ - function get_subtree() { - return new FrameTreeList($this); - } - - function set_positioner(Positioner $posn) { - $this->_positioner = $posn; - if ( $this->_frame instanceof Frame_Decorator ) { - $this->_frame->set_positioner($posn); - } - } - - function set_reflower(Frame_Reflower $reflower) { - $this->_reflower = $reflower; - if ( $this->_frame instanceof Frame_Decorator ) { - $this->_frame->set_reflower( $reflower ); - } - } - - /** - * @return Frame_Reflower - */ - function get_reflower() { - return $this->_reflower; - } - - /** - * @param Frame $root - */ - function set_root(Frame $root) { - $this->_root = $root; - - if ( $this->_frame instanceof Frame_Decorator ) { - $this->_frame->set_root($root); - } - } - - /** - * @return Page_Frame_Decorator - */ - function get_root() { - return $this->_root; - } - - /** - * @return Block_Frame_Decorator - */ - function find_block_parent() { - // Find our nearest block level parent - $p = $this->get_parent(); - - while ( $p ) { - if ( $p->is_block() ) { - break; - } - - $p = $p->get_parent(); - } - - return $this->_block_parent = $p; - } - - /** - * @return Frame_Decorator - */ - function find_positionned_parent() { - // Find our nearest relative positionned parent - $p = $this->get_parent(); - while ( $p ) { - if ( $p->is_positionned() ) { - break; - } - - $p = $p->get_parent(); - } - - if ( !$p ) { - $p = $this->_root->get_first_child(); // - } - - return $this->_positionned_parent = $p; - } - - /** - * split this frame at $child. - * The current frame is cloned and $child and all children following - * $child are added to the clone. The clone is then passed to the - * current frame's parent->split() method. - * - * @param Frame $child - * @param boolean $force_pagebreak - * - * @throws DOMPDF_Exception - * @return void - */ - function split(Frame $child = null, $force_pagebreak = false) { - // decrement any counters that were incremented on the current node, unless that node is the body - $style = $this->_frame->get_style(); - if ( $this->_frame->get_node()->nodeName !== "body" && $style->counter_increment && ($decrement = $style->counter_increment) !== "none" ) { - $this->decrement_counters($decrement); - } - - if ( is_null( $child ) ) { - // check for counter increment on :before content (always a child of the selected element @link Frame_Reflower::_set_content) - // this can push the current node to the next page before counter rules have bubbled up (but only if - // it's been rendered, thus the position check) - if ( !$this->is_text_node() && $this->get_node()->hasAttribute("dompdf_before_frame_id") ) { - foreach($this->_frame->get_children() as $child) { - if ( $this->get_node()->getAttribute("dompdf_before_frame_id") == $child->get_id() && $child->get_position('x') !== NULL ) { - $style = $child->get_style(); - if ( $style->counter_increment && ($decrement = $style->counter_increment) !== "none" ) { - $this->decrement_counters($decrement); - } - } - } - } - $this->get_parent()->split($this, $force_pagebreak); - return; - } - - if ( $child->get_parent() !== $this ) { - throw new DOMPDF_Exception("Unable to split: frame is not a child of this one."); - } - - $node = $this->_frame->get_node(); - - $split = $this->copy( $node->cloneNode() ); - $split->reset(); - $split->get_original_style()->text_indent = 0; - $split->_splitted = true; - - // The body's properties must be kept - if ( $node->nodeName !== "body" ) { - // Style reset on the first and second parts - $style = $this->_frame->get_style(); - $style->margin_bottom = 0; - $style->padding_bottom = 0; - $style->border_bottom = 0; - - // second - $orig_style = $split->get_original_style(); - $orig_style->text_indent = 0; - $orig_style->margin_top = 0; - $orig_style->padding_top = 0; - $orig_style->border_top = 0; - } - - $this->get_parent()->insert_child_after($split, $this); - - // Add $frame and all following siblings to the new split node - $iter = $child; - while ($iter) { - $frame = $iter; - $iter = $iter->get_next_sibling(); - $frame->reset(); - $split->append_child($frame); - } - - $this->get_parent()->split($split, $force_pagebreak); - - // If this node resets a counter save the current value to use when rendering on the next page - if ( $style->counter_reset && ( $reset = $style->counter_reset ) !== "none" ) { - $vars = preg_split( '/\s+/' , trim( $reset ) , 2 ); - $split->_counters[ '__' . $vars[0] ] = $this->lookup_counter_frame( $vars[0] )->_counters[$vars[0]]; - } - } - - function reset_counter($id = self::DEFAULT_COUNTER, $value = 0) { - $this->get_parent()->_counters[$id] = intval($value); - } - - function decrement_counters($counters) { - foreach($counters as $id => $increment) { - $this->increment_counter($id, intval($increment) * -1); - } - } - - function increment_counters($counters) { - foreach($counters as $id => $increment) { - $this->increment_counter($id, intval($increment)); - } - } - - function increment_counter($id = self::DEFAULT_COUNTER, $increment = 1) { - $counter_frame = $this->lookup_counter_frame($id); - - if ( $counter_frame ) { - if ( !isset($counter_frame->_counters[$id]) ) { - $counter_frame->_counters[$id] = 0; - } - - $counter_frame->_counters[$id] += $increment; - } - } - - function lookup_counter_frame($id = self::DEFAULT_COUNTER) { - $f = $this->get_parent(); - - while( $f ) { - if( isset($f->_counters[$id]) ) { - return $f; - } - $fp = $f->get_parent(); - - if ( !$fp ) { - return $f; - } - - $f = $fp; - } - } - - // TODO: What version is the best : this one or the one in List_Bullet_Renderer ? - function counter_value($id = self::DEFAULT_COUNTER, $type = "decimal") { - $type = mb_strtolower($type); - - if ( !isset($this->_counters[$id]) ) { - $this->_counters[$id] = 0; - } - - $value = $this->_counters[$id]; - - switch ($type) { - default: - case "decimal": - return $value; - - case "decimal-leading-zero": - return str_pad($value, 2, "0"); - - case "lower-roman": - return dec2roman($value); - - case "upper-roman": - return mb_strtoupper(dec2roman($value)); - - case "lower-latin": - case "lower-alpha": - return chr( ($value % 26) + ord('a') - 1); - - case "upper-latin": - case "upper-alpha": - return chr( ($value % 26) + ord('A') - 1); - - case "lower-greek": - return unichr($value + 944); - - case "upper-greek": - return unichr($value + 912); - } - } - - final function position() { - $this->_positioner->position(); - } - - final function move($offset_x, $offset_y, $ignore_self = false) { - $this->_positioner->move($offset_x, $offset_y, $ignore_self); - } - - final function reflow(Block_Frame_Decorator $block = null) { - // Uncomment this to see the frames before they're laid out, instead of - // during rendering. - //echo $this->_frame; flush(); - $this->_reflower->reflow($block); - } - - final function get_min_max_width() { - return $this->_reflower->get_min_max_width(); - } -} diff --git a/application/helpers/dompdf/include/frame_factory.cls.php b/application/helpers/dompdf/include/frame_factory.cls.php deleted file mode 100755 index 70813d2e3..000000000 --- a/application/helpers/dompdf/include/frame_factory.cls.php +++ /dev/null @@ -1,252 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Contains frame decorating logic - * - * This class is responsible for assigning the correct {@link Frame_Decorator}, - * {@link Positioner}, and {@link Frame_Reflower} objects to {@link Frame} - * objects. This is determined primarily by the Frame's display type, but - * also by the Frame's node's type (e.g. DomElement vs. #text) - * - * @access private - * @package dompdf - */ -class Frame_Factory { - - /** - * Decorate the root Frame - * - * @param $root Frame The frame to decorate - * @param $dompdf DOMPDF The dompdf instance - * @return Page_Frame_Decorator - */ - static function decorate_root(Frame $root, DOMPDF $dompdf) { - $frame = new Page_Frame_Decorator($root, $dompdf); - $frame->set_reflower( new Page_Frame_Reflower($frame) ); - $root->set_decorator($frame); - return $frame; - } - - /** - * Decorate a Frame - * - * @param Frame $frame The frame to decorate - * @param DOMPDF $dompdf The dompdf instance - * @param Frame $root The frame to decorate - * - * @throws DOMPDF_Exception - * @return Frame_Decorator - * FIXME: this is admittedly a little smelly... - */ - static function decorate_frame(Frame $frame, DOMPDF $dompdf, Frame $root = null) { - if ( is_null($dompdf) ) { - throw new DOMPDF_Exception("The DOMPDF argument is required"); - } - - $style = $frame->get_style(); - - // Floating (and more generally out-of-flow) elements are blocks - // http://coding.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/ - if ( !$frame->is_in_flow() && in_array($style->display, Style::$INLINE_TYPES)) { - $style->display = "block"; - } - - $display = $style->display; - - switch ($display) { - - case "block": - $positioner = "Block"; - $decorator = "Block"; - $reflower = "Block"; - break; - - case "inline-block": - $positioner = "Inline"; - $decorator = "Block"; - $reflower = "Block"; - break; - - case "inline": - $positioner = "Inline"; - if ( $frame->is_text_node() ) { - $decorator = "Text"; - $reflower = "Text"; - } - else { - $enable_css_float = $dompdf->get_option("enable_css_float"); - if ( $enable_css_float && $style->float !== "none" ) { - $decorator = "Block"; - $reflower = "Block"; - } - else { - $decorator = "Inline"; - $reflower = "Inline"; - } - } - break; - - case "table": - $positioner = "Block"; - $decorator = "Table"; - $reflower = "Table"; - break; - - case "inline-table": - $positioner = "Inline"; - $decorator = "Table"; - $reflower = "Table"; - break; - - case "table-row-group": - case "table-header-group": - case "table-footer-group": - $positioner = "Null"; - $decorator = "Table_Row_Group"; - $reflower = "Table_Row_Group"; - break; - - case "table-row": - $positioner = "Null"; - $decorator = "Table_Row"; - $reflower = "Table_Row"; - break; - - case "table-cell": - $positioner = "Table_Cell"; - $decorator = "Table_Cell"; - $reflower = "Table_Cell"; - break; - - case "list-item": - $positioner = "Block"; - $decorator = "Block"; - $reflower = "Block"; - break; - - case "-dompdf-list-bullet": - if ( $style->list_style_position === "inside" ) { - $positioner = "Inline"; - } - else { - $positioner = "List_Bullet"; - } - - if ( $style->list_style_image !== "none" ) { - $decorator = "List_Bullet_Image"; - } - else { - $decorator = "List_Bullet"; - } - - $reflower = "List_Bullet"; - break; - - case "-dompdf-image": - $positioner = "Inline"; - $decorator = "Image"; - $reflower = "Image"; - break; - - case "-dompdf-br": - $positioner = "Inline"; - $decorator = "Inline"; - $reflower = "Inline"; - break; - - default: - // FIXME: should throw some sort of warning or something? - case "none": - if ( $style->_dompdf_keep !== "yes" ) { - // Remove the node and the frame - $frame->get_parent()->remove_child($frame); - return; - } - - $positioner = "Null"; - $decorator = "Null"; - $reflower = "Null"; - break; - } - - // Handle CSS position - $position = $style->position; - - if ( $position === "absolute" ) { - $positioner = "Absolute"; - } - else if ( $position === "fixed" ) { - $positioner = "Fixed"; - } - - $node = $frame->get_node(); - - // Handle nodeName - if ( $node->nodeName === "img" ) { - $style->display = "-dompdf-image"; - $decorator = "Image"; - $reflower = "Image"; - } - - $positioner .= "_Positioner"; - $decorator .= "_Frame_Decorator"; - $reflower .= "_Frame_Reflower"; - - $deco = new $decorator($frame, $dompdf); - - $deco->set_positioner( new $positioner($deco) ); - $deco->set_reflower( new $reflower($deco) ); - - if ( $root ) { - $deco->set_root($root); - } - - if ( $display === "list-item" ) { - // Insert a list-bullet frame - $xml = $dompdf->get_dom(); - $bullet_node = $xml->createElement("bullet"); // arbitrary choice - $b_f = new Frame($bullet_node); - - $node = $frame->get_node(); - $parent_node = $node->parentNode; - - if ( $parent_node ) { - if ( !$parent_node->hasAttribute("dompdf-children-count") ) { - $xpath = new DOMXPath($xml); - $count = $xpath->query("li", $parent_node)->length; - $parent_node->setAttribute("dompdf-children-count", $count); - } - - if ( is_numeric($node->getAttribute("value")) ) { - $index = intval($node->getAttribute("value")); - } - else { - if ( !$parent_node->hasAttribute("dompdf-counter") ) { - $index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1); - } - else { - $index = $parent_node->getAttribute("dompdf-counter")+1; - } - } - - $parent_node->setAttribute("dompdf-counter", $index); - $bullet_node->setAttribute("dompdf-counter", $index); - } - - $new_style = $dompdf->get_css()->create_style(); - $new_style->display = "-dompdf-list-bullet"; - $new_style->inherit($style); - $b_f->set_style($new_style); - - $deco->prepend_child( Frame_Factory::decorate_frame($b_f, $dompdf, $root) ); - } - - return $deco; - } -} diff --git a/application/helpers/dompdf/include/frame_reflower.cls.php b/application/helpers/dompdf/include/frame_reflower.cls.php deleted file mode 100755 index 576039e1f..000000000 --- a/application/helpers/dompdf/include/frame_reflower.cls.php +++ /dev/null @@ -1,458 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Base reflower class - * - * Reflower objects are responsible for determining the width and height of - * individual frames. They also create line and page breaks as necessary. - * - * @access private - * @package dompdf - */ -abstract class Frame_Reflower { - - /** - * Frame for this reflower - * - * @var Frame - */ - protected $_frame; - - /** - * Cached min/max size - * - * @var array - */ - protected $_min_max_cache; - - function __construct(Frame $frame) { - $this->_frame = $frame; - $this->_min_max_cache = null; - } - - function dispose() { - clear_object($this); - } - - /** - * @return DOMPDF - */ - function get_dompdf() { - return $this->_frame->get_dompdf(); - } - - /** - * Collapse frames margins - * http://www.w3.org/TR/CSS2/box.html#collapsing-margins - */ - protected function _collapse_margins() { - $frame = $this->_frame; - $cb = $frame->get_containing_block(); - $style = $frame->get_style(); - - if ( !$frame->is_in_flow() ) { - return; - } - - $t = $style->length_in_pt($style->margin_top, $cb["h"]); - $b = $style->length_in_pt($style->margin_bottom, $cb["h"]); - - // Handle 'auto' values - if ( $t === "auto" ) { - $style->margin_top = "0pt"; - $t = 0; - } - - if ( $b === "auto" ) { - $style->margin_bottom = "0pt"; - $b = 0; - } - - // Collapse vertical margins: - $n = $frame->get_next_sibling(); - if ( $n && !$n->is_block() ) { - while ( $n = $n->get_next_sibling() ) { - if ( $n->is_block() ) { - break; - } - - if ( !$n->get_first_child() ) { - $n = null; - break; - } - } - } - - if ( $n ) { - $n_style = $n->get_style(); - $b = max($b, $n_style->length_in_pt($n_style->margin_top, $cb["h"])); - $n_style->margin_top = "0pt"; - $style->margin_bottom = $b."pt"; - } - - // Collapse our first child's margin - /*$f = $this->_frame->get_first_child(); - if ( $f && !$f->is_block() ) { - while ( $f = $f->get_next_sibling() ) { - if ( $f->is_block() ) { - break; - } - - if ( !$f->get_first_child() ) { - $f = null; - break; - } - } - } - - // Margin are collapsed only between block elements - if ( $f ) { - $f_style = $f->get_style(); - $t = max($t, $f_style->length_in_pt($f_style->margin_top, $cb["h"])); - $style->margin_top = $t."pt"; - $f_style->margin_bottom = "0pt"; - }*/ - } - - //........................................................................ - - abstract function reflow(Block_Frame_Decorator $block = null); - - //........................................................................ - - // Required for table layout: Returns an array(0 => min, 1 => max, "min" - // => min, "max" => max) of the minimum and maximum widths of this frame. - // This provides a basic implementation. Child classes should override - // this if necessary. - function get_min_max_width() { - if ( !is_null($this->_min_max_cache) ) { - return $this->_min_max_cache; - } - - $style = $this->_frame->get_style(); - - // Account for margins & padding - $dims = array($style->padding_left, - $style->padding_right, - $style->border_left_width, - $style->border_right_width, - $style->margin_left, - $style->margin_right); - - $cb_w = $this->_frame->get_containing_block("w"); - $delta = $style->length_in_pt($dims, $cb_w); - - // Handle degenerate case - if ( !$this->_frame->get_first_child() ) { - return $this->_min_max_cache = array( - $delta, $delta, - "min" => $delta, - "max" => $delta, - ); - } - - $low = array(); - $high = array(); - - for ( $iter = $this->_frame->get_children()->getIterator(); - $iter->valid(); - $iter->next() ) { - - $inline_min = 0; - $inline_max = 0; - - // Add all adjacent inline widths together to calculate max width - while ( $iter->valid() && in_array( $iter->current()->get_style()->display, Style::$INLINE_TYPES ) ) { - - $child = $iter->current(); - - $minmax = $child->get_min_max_width(); - - if ( in_array( $iter->current()->get_style()->white_space, array("pre", "nowrap") ) ) { - $inline_min += $minmax["min"]; - } - else { - $low[] = $minmax["min"]; - } - - $inline_max += $minmax["max"]; - $iter->next(); - - } - - if ( $inline_max > 0 ) $high[] = $inline_max; - if ( $inline_min > 0 ) $low[] = $inline_min; - - if ( $iter->valid() ) { - list($low[], $high[]) = $iter->current()->get_min_max_width(); - continue; - } - - } - $min = count($low) ? max($low) : 0; - $max = count($high) ? max($high) : 0; - - // Use specified width if it is greater than the minimum defined by the - // content. If the width is a percentage ignore it for now. - $width = $style->width; - if ( $width !== "auto" && !is_percent($width) ) { - $width = $style->length_in_pt($width, $cb_w); - if ( $min < $width ) $min = $width; - if ( $max < $width ) $max = $width; - } - - $min += $delta; - $max += $delta; - return $this->_min_max_cache = array($min, $max, "min"=>$min, "max"=>$max); - } - - /** - * Parses a CSS string containing quotes and escaped hex characters - * - * @param $string string The CSS string to parse - * @param $single_trim - * @return string - */ - protected function _parse_string($string, $single_trim = false) { - if ( $single_trim ) { - $string = preg_replace('/^[\"\']/', "", $string); - $string = preg_replace('/[\"\']$/', "", $string); - } - else { - $string = trim($string, "'\""); - } - - $string = str_replace(array("\\\n",'\\"',"\\'"), - array("",'"',"'"), $string); - - // Convert escaped hex characters into ascii characters (e.g. \A => newline) - $string = preg_replace_callback("/\\\\([0-9a-fA-F]{0,6})/", - create_function('$matches', - 'return unichr(hexdec($matches[1]));'), - $string); - return $string; - } - - /** - * Parses a CSS "quotes" property - * - * @return array|null An array of pairs of quotes - */ - protected function _parse_quotes() { - - // Matches quote types - $re = '/(\'[^\']*\')|(\"[^\"]*\")/'; - - $quotes = $this->_frame->get_style()->quotes; - - // split on spaces, except within quotes - if ( !preg_match_all($re, "$quotes", $matches, PREG_SET_ORDER) ) { - return null; - } - - $quotes_array = array(); - foreach($matches as &$_quote){ - $quotes_array[] = $this->_parse_string($_quote[0], true); - } - - if ( empty($quotes_array) ) { - $quotes_array = array('"', '"'); - } - - return array_chunk($quotes_array, 2); - } - - /** - * Parses the CSS "content" property - * - * @return string|null The resulting string - */ - protected function _parse_content() { - - // Matches generated content - $re = "/\n". - "\s(counters?\\([^)]*\\))|\n". - "\A(counters?\\([^)]*\\))|\n". - "\s([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?_frame->get_style()->content; - - $quotes = $this->_parse_quotes(); - - // split on spaces, except within quotes - if ( !preg_match_all($re, $content, $matches, PREG_SET_ORDER) ) { - return null; - } - - $text = ""; - - foreach ($matches as $match) { - - if ( isset($match[2]) && $match[2] !== "" ) { - $match[1] = $match[2]; - } - - if ( isset($match[6]) && $match[6] !== "" ) { - $match[4] = $match[6]; - } - - if ( isset($match[8]) && $match[8] !== "" ) { - $match[7] = $match[8]; - } - - if ( isset($match[1]) && $match[1] !== "" ) { - - // counters?(...) - $match[1] = mb_strtolower(trim($match[1])); - - // Handle counter() references: - // http://www.w3.org/TR/CSS21/generate.html#content - - $i = mb_strpos($match[1], ")"); - if ( $i === false ) { - continue; - } - - preg_match( '/(counters?)(^\()*?\(\s*([^\s,]+)\s*(,\s*["\']?([^"\'\)]+)["\']?\s*(,\s*([^\s)]+)\s*)?)?\)/i' , $match[1] , $args ); - $counter_id = $args[3]; - if ( strtolower( $args[1] ) == 'counter' ) { - // counter(name [,style]) - if ( isset( $args[5] ) ) { - $type = trim( $args[5] ); - } - else { - $type = null; - } - $p = $this->_frame->lookup_counter_frame( $counter_id ); - - $text .= $p->counter_value($counter_id, $type); - - } - else if ( strtolower( $args[1] ) == 'counters' ) { - // counters(name, string [,style]) - if ( isset($args[5]) ) { - $string = $this->_parse_string( $args[5] ); - } - else { - $string = ""; - } - - if ( isset( $args[7] ) ) { - $type = trim( $args[7] ); - } - else { - $type = null; - } - - $p = $this->_frame->lookup_counter_frame($counter_id); - $tmp = array(); - while ($p) { - // We only want to use the counter values when they actually increment the counter - if ( array_key_exists( $counter_id , $p->_counters ) ) { - array_unshift( $tmp , $p->counter_value($counter_id, $type) ); - } - $p = $p->lookup_counter_frame($counter_id); - - } - $text .= implode( $string , $tmp ); - - } - else { - // countertops? - continue; - } - - } - else if ( isset($match[4]) && $match[4] !== "" ) { - // String match - $text .= $this->_parse_string($match[4]); - } - else if ( isset($match[7]) && $match[7] !== "" ) { - // Directive match - - if ( $match[7] === "open-quote" ) { - // FIXME: do something here - $text .= $quotes[0][0]; - } - else if ( $match[7] === "close-quote" ) { - // FIXME: do something else here - $text .= $quotes[0][1]; - } - else if ( $match[7] === "no-open-quote" ) { - // FIXME: - } - else if ( $match[7] === "no-close-quote" ) { - // FIXME: - } - else if ( mb_strpos($match[7],"attr(") === 0 ) { - - $i = mb_strpos($match[7],")"); - if ( $i === false ) { - continue; - } - - $attr = mb_substr($match[7], 5, $i - 5); - if ( $attr == "" ) { - continue; - } - - $text .= $this->_frame->get_parent()->get_node()->getAttribute($attr); - } - else { - continue; - } - } - } - - return $text; - } - - /** - * Sets the generated content of a generated frame - */ - protected function _set_content(){ - $frame = $this->_frame; - $style = $frame->get_style(); - - // if the element was pushed to a new page use the saved counter value, otherwise use the CSS reset value - if ( $style->counter_reset && ($reset = $style->counter_reset) !== "none" ) { - $vars = preg_split('/\s+/', trim($reset), 2); - $frame->reset_counter( $vars[0] , ( isset($frame->_counters['__'.$vars[0]]) ? $frame->_counters['__'.$vars[0]] : ( isset($vars[1]) ? $vars[1] : 0 ) ) ); - } - - if ( $style->counter_increment && ($increment = $style->counter_increment) !== "none" ) { - $frame->increment_counters($increment); - } - - if ( $style->content && !$frame->get_first_child() && $frame->get_node()->nodeName === "dompdf_generated" ) { - $content = $this->_parse_content(); - // add generated content to the font subset - // FIXME: This is currently too late because the font subset has already been generated. - // See notes in issue #750. - if ( $frame->get_dompdf()->get_option("enable_font_subsetting") && $frame->get_dompdf()->get_canvas() instanceof CPDF_Adapter ) { - $frame->get_dompdf()->get_canvas()->register_string_subset($style->font_family, $content); - } - - $node = $frame->get_node()->ownerDocument->createTextNode($content); - - $new_style = $style->get_stylesheet()->create_style(); - $new_style->inherit($style); - - $new_frame = new Frame($node); - $new_frame->set_style($new_style); - - Frame_Factory::decorate_frame($new_frame, $frame->get_dompdf(), $frame->get_root()); - $frame->append_child($new_frame); - } - } -} diff --git a/application/helpers/dompdf/include/frame_tree.cls.php b/application/helpers/dompdf/include/frame_tree.cls.php deleted file mode 100755 index 257ca097e..000000000 --- a/application/helpers/dompdf/include/frame_tree.cls.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Represents an entire document as a tree of frames - * - * The Frame_Tree consists of {@link Frame} objects each tied to specific - * DOMNode objects in a specific DomDocument. The Frame_Tree has the same - * structure as the DomDocument, but adds additional capabalities for - * styling and layout. - * - * @package dompdf - * @access protected - */ -class Frame_Tree { - - /** - * Tags to ignore while parsing the tree - * - * @var array - */ - static protected $_HIDDEN_TAGS = array("area", "base", "basefont", "head", "style", - "meta", "title", "colgroup", - "noembed", "noscript", "param", "#comment"); - /** - * The main DomDocument - * - * @see http://ca2.php.net/manual/en/ref.dom.php - * @var DomDocument - */ - protected $_dom; - - /** - * The root node of the FrameTree. - * - * @var Frame - */ - protected $_root; - - /** - * Subtrees of absolutely positioned elements - * - * @var array of Frames - */ - protected $_absolute_frames; - - /** - * A mapping of {@link Frame} objects to DOMNode objects - * - * @var array - */ - protected $_registry; - - - /** - * Class constructor - * - * @param DomDocument $dom the main DomDocument object representing the current html document - */ - function __construct(DomDocument $dom) { - $this->_dom = $dom; - $this->_root = null; - $this->_registry = array(); - } - - function __destruct() { - clear_object($this); - } - - /** - * Returns the DomDocument object representing the curent html document - * - * @return DOMDocument - */ - function get_dom() { - return $this->_dom; - } - - /** - * Returns the root frame of the tree - * - * @return Page_Frame_Decorator - */ - function get_root() { - return $this->_root; - } - - /** - * Returns a specific frame given its id - * - * @param string $id - * @return Frame - */ - function get_frame($id) { - return isset($this->_registry[$id]) ? $this->_registry[$id] : null; - } - - /** - * Returns a post-order iterator for all frames in the tree - * - * @return FrameTreeList|Frame[] - */ - function get_frames() { - return new FrameTreeList($this->_root); - } - - /** - * Builds the tree - */ - function build_tree() { - $html = $this->_dom->getElementsByTagName("html")->item(0); - if ( is_null($html) ) { - $html = $this->_dom->firstChild; - } - - if ( is_null($html) ) { - throw new DOMPDF_Exception("Requested HTML document contains no data."); - } - - $this->fix_tables(); - - $this->_root = $this->_build_tree_r($html); - } - - /** - * Adds missing TBODYs around TR - */ - protected function fix_tables(){ - $xp = new DOMXPath($this->_dom); - - // Move table caption before the table - // FIXME find a better way to deal with it... - $captions = $xp->query("//table/caption"); - foreach($captions as $caption) { - $table = $caption->parentNode; - $table->parentNode->insertBefore($caption, $table); - } - - $rows = $xp->query("//table/tr"); - foreach($rows as $row) { - $tbody = $this->_dom->createElement("tbody"); - $tbody = $row->parentNode->insertBefore($tbody, $row); - $tbody->appendChild($row); - } - } - - /** - * Recursively adds {@link Frame} objects to the tree - * - * Recursively build a tree of Frame objects based on a dom tree. - * No layout information is calculated at this time, although the - * tree may be adjusted (i.e. nodes and frames for generated content - * and images may be created). - * - * @param DOMNode $node the current DOMNode being considered - * @return Frame - */ - protected function _build_tree_r(DOMNode $node) { - - $frame = new Frame($node); - $id = $frame->get_id(); - $this->_registry[ $id ] = $frame; - - if ( !$node->hasChildNodes() ) { - return $frame; - } - - // Fixes 'cannot access undefined property for object with - // overloaded access', fix by Stefan radulian - // - //foreach ($node->childNodes as $child) { - - // Store the children in an array so that the tree can be modified - $children = array(); - for ($i = 0; $i < $node->childNodes->length; $i++) { - $children[] = $node->childNodes->item($i); - } - - foreach ($children as $child) { - $node_name = mb_strtolower($child->nodeName); - - // Skip non-displaying nodes - if ( in_array($node_name, self::$_HIDDEN_TAGS) ) { - if ( $node_name !== "head" && $node_name !== "style" ) { - $child->parentNode->removeChild($child); - } - - continue; - } - - // Skip empty text nodes - if ( $node_name === "#text" && $child->nodeValue == "" ) { - $child->parentNode->removeChild($child); - continue; - } - - // Skip empty image nodes - if ( $node_name === "img" && $child->getAttribute("src") == "" ) { - $child->parentNode->removeChild($child); - continue; - } - - $frame->append_child($this->_build_tree_r($child), false); - } - - return $frame; - } - - public function insert_node(DOMNode $node, DOMNode $new_node, $pos) { - if ( $pos === "after" || !$node->firstChild ) { - $node->appendChild($new_node); - } - else { - $node->insertBefore($new_node, $node->firstChild); - } - - $this->_build_tree_r($new_node); - - $frame_id = $new_node->getAttribute("frame_id"); - $frame = $this->get_frame($frame_id); - - $parent_id = $node->getAttribute("frame_id"); - $parent = $this->get_frame($parent_id); - - if ( $parent ) { - if ( $pos === "before" ) { - $parent->prepend_child($frame, false); - } - else { - $parent->append_child($frame, false); - } - } - - return $frame_id; - } -} diff --git a/application/helpers/dompdf/include/functions.inc.php b/application/helpers/dompdf/include/functions.inc.php deleted file mode 100755 index 8e0ab02c7..000000000 --- a/application/helpers/dompdf/include/functions.inc.php +++ /dev/null @@ -1,1054 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -if ( !defined('PHP_VERSION_ID') ) { - $version = explode('.', PHP_VERSION); - define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); -} - -/** - * Defined a constant if not already defined - * - * @param string $name The constant name - * @param mixed $value The value - */ -function def($name, $value = true) { - if ( !defined($name) ) { - define($name, $value); - } -} - -if ( !function_exists("pre_r") ) { -/** - * print_r wrapper for html/cli output - * - * Wraps print_r() output in < pre > tags if the current sapi is not 'cli'. - * Returns the output string instead of displaying it if $return is true. - * - * @param mixed $mixed variable or expression to display - * @param bool $return - * - * @return string - */ -function pre_r($mixed, $return = false) { - if ( $return ) { - return "
" . print_r($mixed, true) . "
"; - } - - if ( php_sapi_name() !== "cli" ) { - echo "
";
-  }
-  
-  print_r($mixed);
-
-  if ( php_sapi_name() !== "cli" ) {
-    echo "
"; - } - else { - echo "\n"; - } - - flush(); - -} -} - -if ( !function_exists("pre_var_dump") ) { -/** - * var_dump wrapper for html/cli output - * - * Wraps var_dump() output in < pre > tags if the current sapi is not 'cli'. - * - * @param mixed $mixed variable or expression to display. - */ -function pre_var_dump($mixed) { - if ( php_sapi_name() !== "cli" ) { - echo "
";
-  }
-    
-  var_dump($mixed);
-  
-  if ( php_sapi_name() !== "cli" ) {
-    echo "
"; - } -} -} - -if ( !function_exists("d") ) { -/** - * generic debug function - * - * Takes everything and does its best to give a good debug output - * - * @param mixed $mixed variable or expression to display. - */ -function d($mixed) { - if ( php_sapi_name() !== "cli" ) { - echo "
";
-  }
-    
-  // line
-  if ( $mixed instanceof Line_Box ) {
-    echo $mixed;
-  }
-  
-  // other
-  else {
-    var_export($mixed);
-  }
-  
-  if ( php_sapi_name() !== "cli" ) {
-    echo "
"; - } -} -} - -/** - * builds a full url given a protocol, hostname, base path and url - * - * @param string $protocol - * @param string $host - * @param string $base_path - * @param string $url - * @return string - * - * Initially the trailing slash of $base_path was optional, and conditionally appended. - * However on dynamically created sites, where the page is given as url parameter, - * the base path might not end with an url. - * Therefore do not append a slash, and **require** the $base_url to ending in a slash - * when needed. - * Vice versa, on using the local file system path of a file, make sure that the slash - * is appended (o.k. also for Windows) - */ -function build_url($protocol, $host, $base_path, $url) { - if ( strlen($url) == 0 ) { - //return $protocol . $host . rtrim($base_path, "/\\") . "/"; - return $protocol . $host . $base_path; - } - - // Is the url already fully qualified or a Data URI? - if ( mb_strpos($url, "://") !== false || mb_strpos($url, "data:") === 0 ) { - return $url; - } - - $ret = $protocol; - - if ( !in_array(mb_strtolower($protocol), array("http://", "https://", "ftp://", "ftps://")) ) { - //On Windows local file, an abs path can begin also with a '\' or a drive letter and colon - //drive: followed by a relative path would be a drive specific default folder. - //not known in php app code, treat as abs path - //($url[1] !== ':' || ($url[2]!=='\\' && $url[2]!=='/')) - if ( $url[0] !== '/' && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' || ($url[0] !== '\\' && $url[1] !== ':')) ) { - // For rel path and local acess we ignore the host, and run the path through realpath() - $ret .= realpath($base_path).'/'; - } - $ret .= $url; - $ret = preg_replace('/\?(.*)$/', "", $ret); - return $ret; - } - - //remote urls with backslash in html/css are not really correct, but lets be genereous - if ( $url[0] === '/' || $url[0] === '\\' ) { - // Absolute path - $ret .= $host . $url; - } - else { - // Relative path - //$base_path = $base_path !== "" ? rtrim($base_path, "/\\") . "/" : ""; - $ret .= $host . $base_path . $url; - } - - return $ret; - -} - -/** - * parse a full url or pathname and return an array(protocol, host, path, - * file + query + fragment) - * - * @param string $url - * @return array - */ -function explode_url($url) { - $protocol = ""; - $host = ""; - $path = ""; - $file = ""; - - $arr = parse_url($url); - - // Exclude windows drive letters... - if ( isset($arr["scheme"]) && $arr["scheme"] !== "file" && strlen($arr["scheme"]) > 1 ) { - $protocol = $arr["scheme"] . "://"; - - if ( isset($arr["user"]) ) { - $host .= $arr["user"]; - - if ( isset($arr["pass"]) ) { - $host .= ":" . $arr["pass"]; - } - - $host .= "@"; - } - - if ( isset($arr["host"]) ) { - $host .= $arr["host"]; - } - - if ( isset($arr["port"]) ) { - $host .= ":" . $arr["port"]; - } - - if ( isset($arr["path"]) && $arr["path"] !== "" ) { - // Do we have a trailing slash? - if ( $arr["path"][ mb_strlen($arr["path"]) - 1 ] === "/" ) { - $path = $arr["path"]; - $file = ""; - } - else { - $path = rtrim(dirname($arr["path"]), '/\\') . "/"; - $file = basename($arr["path"]); - } - } - - if ( isset($arr["query"]) ) { - $file .= "?" . $arr["query"]; - } - - if ( isset($arr["fragment"]) ) { - $file .= "#" . $arr["fragment"]; - } - - } - else { - - $i = mb_strpos($url, "file://"); - if ( $i !== false ) { - $url = mb_substr($url, $i + 7); - } - - $protocol = ""; // "file://"; ? why doesn't this work... It's because of - // network filenames like //COMPU/SHARENAME - - $host = ""; // localhost, really - $file = basename($url); - - $path = dirname($url); - - // Check that the path exists - if ( $path !== false ) { - $path .= '/'; - - } - else { - // generate a url to access the file if no real path found. - $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://'; - - $host = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : php_uname("n"); - - if ( substr($arr["path"], 0, 1) === '/' ) { - $path = dirname($arr["path"]); - } - else { - $path = '/' . rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/') . '/' . $arr["path"]; - } - } - } - - $ret = array($protocol, $host, $path, $file, - "protocol" => $protocol, - "host" => $host, - "path" => $path, - "file" => $file); - return $ret; -} - -/** - * Converts decimal numbers to roman numerals - * - * @param int $num - * - * @throws DOMPDF_Exception - * @return string - */ -function dec2roman($num) { - - static $ones = array("", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"); - static $tens = array("", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"); - static $hund = array("", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"); - static $thou = array("", "m", "mm", "mmm"); - - if ( !is_numeric($num) ) { - throw new DOMPDF_Exception("dec2roman() requires a numeric argument."); - } - - if ( $num > 4000 || $num < 0 ) { - return "(out of range)"; - } - - $num = strrev((string)$num); - - $ret = ""; - switch (mb_strlen($num)) { - case 4: $ret .= $thou[$num[3]]; - case 3: $ret .= $hund[$num[2]]; - case 2: $ret .= $tens[$num[1]]; - case 1: $ret .= $ones[$num[0]]; - default: break; - } - - return $ret; -} - -/** - * Determines whether $value is a percentage or not - * - * @param float $value - * - * @return bool - */ -function is_percent($value) { - return false !== mb_strpos($value, "%"); -} - -/** - * Parses a data URI scheme - * http://en.wikipedia.org/wiki/Data_URI_scheme - * - * @param string $data_uri The data URI to parse - * - * @return array The result with charset, mime type and decoded data - */ -function parse_data_uri($data_uri) { - if (!preg_match('/^data:(?P[a-z0-9\/+-.]+)(;charset=(?P[a-z0-9-])+)?(?P;base64)?\,(?P.*)?/i', $data_uri, $match)) { - return false; - } - - $match['data'] = rawurldecode($match['data']); - $result = array( - 'charset' => $match['charset'] ? $match['charset'] : 'US-ASCII', - 'mime' => $match['mime'] ? $match['mime'] : 'text/plain', - 'data' => $match['base64'] ? base64_decode($match['data']) : $match['data'], - ); - - return $result; -} - -/** - * mb_string compatibility - */ -if (!extension_loaded('mbstring')) { - def('MB_OVERLOAD_MAIL', 1); - def('MB_OVERLOAD_STRING', 2); - def('MB_OVERLOAD_REGEX', 4); - def('MB_CASE_UPPER', 0); - def('MB_CASE_LOWER', 1); - def('MB_CASE_TITLE', 2); - - if (!function_exists('mb_convert_encoding')) { - function mb_convert_encoding($data, $to_encoding, $from_encoding = 'UTF-8') { - if (str_replace('-', '', strtolower($to_encoding)) === 'utf8') { - return utf8_encode($data); - } - - return utf8_decode($data); - } - } - - if (!function_exists('mb_detect_encoding')) { - function mb_detect_encoding($data, $encoding_list = array('iso-8859-1'), $strict = false) { - return 'iso-8859-1'; - } - } - - if (!function_exists('mb_detect_order')) { - function mb_detect_order($encoding_list = array('iso-8859-1')) { - return 'iso-8859-1'; - } - } - - if (!function_exists('mb_internal_encoding')) { - function mb_internal_encoding($encoding = null) { - if (isset($encoding)) { - return true; - } - - return 'iso-8859-1'; - } - } - - if (!function_exists('mb_strlen')) { - function mb_strlen($str, $encoding = 'iso-8859-1') { - switch (str_replace('-', '', strtolower($encoding))) { - case "utf8": return strlen(utf8_encode($str)); - case "8bit": return strlen($str); - default: return strlen(utf8_decode($str)); - } - } - } - - if (!function_exists('mb_strpos')) { - function mb_strpos($haystack, $needle, $offset = 0) { - return strpos($haystack, $needle, $offset); - } - } - - if (!function_exists('mb_strrpos')) { - function mb_strrpos($haystack, $needle, $offset = 0) { - return strrpos($haystack, $needle, $offset); - } - } - - if (!function_exists('mb_strtolower')) { - function mb_strtolower( $str ) { - return strtolower($str); - } - } - - if (!function_exists('mb_strtoupper')) { - function mb_strtoupper( $str ) { - return strtoupper($str); - } - } - - if (!function_exists('mb_substr')) { - function mb_substr($string, $start, $length = null, $encoding = 'iso-8859-1') { - if ( is_null($length) ) { - return substr($string, $start); - } - - return substr($string, $start, $length); - } - } - - if (!function_exists('mb_substr_count')) { - function mb_substr_count($haystack, $needle, $encoding = 'iso-8859-1') { - return substr_count($haystack, $needle); - } - } - - if (!function_exists('mb_encode_numericentity')) { - function mb_encode_numericentity($str, $convmap, $encoding) { - return htmlspecialchars($str); - } - } - - if (!function_exists('mb_convert_case')) { - function mb_convert_case($str, $mode = MB_CASE_UPPER, $encoding = array()) { - switch($mode) { - case MB_CASE_UPPER: return mb_strtoupper($str); - case MB_CASE_LOWER: return mb_strtolower($str); - case MB_CASE_TITLE: return ucwords(mb_strtolower($str)); - default: return $str; - } - } - } - - if (!function_exists('mb_list_encodings')) { - function mb_list_encodings() { - return array( - "ISO-8859-1", - "UTF-8", - "8bit", - ); - } - } -} - -/** - * Decoder for RLE8 compression in windows bitmaps - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp - * - * @param string $str Data to decode - * @param integer $width Image width - * - * @return string - */ -function rle8_decode ($str, $width){ - $lineWidth = $width + (3 - ($width-1) % 4); - $out = ''; - $cnt = strlen($str); - - for ($i = 0; $i <$cnt; $i++) { - $o = ord($str[$i]); - switch ($o){ - case 0: # ESCAPE - $i++; - switch (ord($str[$i])){ - case 0: # NEW LINE - $padCnt = $lineWidth - strlen($out)%$lineWidth; - if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line - break; - case 1: # END OF FILE - $padCnt = $lineWidth - strlen($out)%$lineWidth; - if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line - break 3; - case 2: # DELTA - $i += 2; - break; - default: # ABSOLUTE MODE - $num = ord($str[$i]); - for ($j = 0; $j < $num; $j++) - $out .= $str[++$i]; - if ($num % 2) $i++; - } - break; - default: - $out .= str_repeat($str[++$i], $o); - } - } - return $out; -} - -/** - * Decoder for RLE4 compression in windows bitmaps - * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp - * - * @param string $str Data to decode - * @param integer $width Image width - * - * @return string - */ -function rle4_decode ($str, $width) { - $w = floor($width/2) + ($width % 2); - $lineWidth = $w + (3 - ( ($width-1) / 2) % 4); - $pixels = array(); - $cnt = strlen($str); - $c = 0; - - for ($i = 0; $i < $cnt; $i++) { - $o = ord($str[$i]); - switch ($o) { - case 0: # ESCAPE - $i++; - switch (ord($str[$i])){ - case 0: # NEW LINE - while (count($pixels)%$lineWidth != 0) { - $pixels[] = 0; - } - break; - case 1: # END OF FILE - while (count($pixels)%$lineWidth != 0) { - $pixels[] = 0; - } - break 3; - case 2: # DELTA - $i += 2; - break; - default: # ABSOLUTE MODE - $num = ord($str[$i]); - for ($j = 0; $j < $num; $j++) { - if ($j%2 == 0) { - $c = ord($str[++$i]); - $pixels[] = ($c & 240)>>4; - } - else { - $pixels[] = $c & 15; - } - } - - if ($num % 2 == 0) { - $i++; - } - } - break; - default: - $c = ord($str[++$i]); - for ($j = 0; $j < $o; $j++) { - $pixels[] = ($j%2==0 ? ($c & 240)>>4 : $c & 15); - } - } - } - - $out = ''; - if (count($pixels)%2) { - $pixels[] = 0; - } - - $cnt = count($pixels)/2; - - for ($i = 0; $i < $cnt; $i++) { - $out .= chr(16*$pixels[2*$i] + $pixels[2*$i+1]); - } - - return $out; -} - -if ( !function_exists("imagecreatefrombmp") ) { - -/** - * Credit goes to mgutt - * http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm - * Modified by Fabien Menager to support RGB555 BMP format - */ -function imagecreatefrombmp($filename) { - if (!function_exists("imagecreatetruecolor")) { - trigger_error("The PHP GD extension is required, but is not installed.", E_ERROR); - return false; - } - - // version 1.00 - if (!($fh = fopen($filename, 'rb'))) { - trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING); - return false; - } - - $bytes_read = 0; - - // read file header - $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14)); - - // check for bitmap - if ($meta['type'] != 19778) { - trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING); - return false; - } - - // read image header - $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40)); - $bytes_read += 40; - - // read additional bitfield header - if ($meta['compression'] == 3) { - $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12)); - $bytes_read += 12; - } - - // set bytes and padding - $meta['bytes'] = $meta['bits'] / 8; - $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4)- floor($meta['width'] * $meta['bytes'] / 4))); - if ($meta['decal'] == 4) { - $meta['decal'] = 0; - } - - // obtain imagesize - if ($meta['imagesize'] < 1) { - $meta['imagesize'] = $meta['filesize'] - $meta['offset']; - // in rare cases filesize is equal to offset so we need to read physical size - if ($meta['imagesize'] < 1) { - $meta['imagesize'] = @filesize($filename) - $meta['offset']; - if ($meta['imagesize'] < 1) { - trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING); - return false; - } - } - } - - // calculate colors - $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors']; - - // read color palette - $palette = array(); - if ($meta['bits'] < 16) { - $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4)); - // in rare cases the color value is signed - if ($palette[1] < 0) { - foreach ($palette as $i => $color) { - $palette[$i] = $color + 16777216; - } - } - } - - // ignore extra bitmap headers - if ($meta['headersize'] > $bytes_read) { - fread($fh, $meta['headersize'] - $bytes_read); - } - - // create gd image - $im = imagecreatetruecolor($meta['width'], $meta['height']); - $data = fread($fh, $meta['imagesize']); - - // uncompress data - switch ($meta['compression']) { - case 1: $data = rle8_decode($data, $meta['width']); break; - case 2: $data = rle4_decode($data, $meta['width']); break; - } - - $p = 0; - $vide = chr(0); - $y = $meta['height'] - 1; - $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!'; - - // loop through the image data beginning with the lower left corner - while ($y >= 0) { - $x = 0; - while ($x < $meta['width']) { - switch ($meta['bits']) { - case 32: - case 24: - if (!($part = substr($data, $p, 3 /*$meta['bytes']*/))) { - trigger_error($error, E_USER_WARNING); - return $im; - } - $color = unpack('V', $part . $vide); - break; - case 16: - if (!($part = substr($data, $p, 2 /*$meta['bytes']*/))) { - trigger_error($error, E_USER_WARNING); - return $im; - } - $color = unpack('v', $part); - - if (empty($meta['rMask']) || $meta['rMask'] != 0xf800) { - $color[1] = (($color[1] & 0x7c00) >> 7) * 65536 + (($color[1] & 0x03e0) >> 2) * 256 + (($color[1] & 0x001f) << 3); // 555 - } - else { - $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); // 565 - } - break; - case 8: - $color = unpack('n', $vide . substr($data, $p, 1)); - $color[1] = $palette[ $color[1] + 1 ]; - break; - case 4: - $color = unpack('n', $vide . substr($data, floor($p), 1)); - $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F; - $color[1] = $palette[ $color[1] + 1 ]; - break; - case 1: - $color = unpack('n', $vide . substr($data, floor($p), 1)); - switch (($p * 8) % 8) { - case 0: $color[1] = $color[1] >> 7; break; - case 1: $color[1] = ($color[1] & 0x40) >> 6; break; - case 2: $color[1] = ($color[1] & 0x20) >> 5; break; - case 3: $color[1] = ($color[1] & 0x10) >> 4; break; - case 4: $color[1] = ($color[1] & 0x8 ) >> 3; break; - case 5: $color[1] = ($color[1] & 0x4 ) >> 2; break; - case 6: $color[1] = ($color[1] & 0x2 ) >> 1; break; - case 7: $color[1] = ($color[1] & 0x1 ); break; - } - $color[1] = $palette[ $color[1] + 1 ]; - break; - default: - trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING); - return false; - } - imagesetpixel($im, $x, $y, $color[1]); - $x++; - $p += $meta['bytes']; - } - $y--; - $p += $meta['decal']; - } - fclose($fh); - return $im; -} -} - -/** - * getimagesize doesn't give a good size for 32bit BMP image v5 - * - * @param string $filename - * @return array The same format as getimagesize($filename) - */ -function dompdf_getimagesize($filename) { - static $cache = array(); - - if ( isset($cache[$filename]) ) { - return $cache[$filename]; - } - - list($width, $height, $type) = getimagesize($filename); - - if ( $width == null || $height == null ) { - $data = file_get_contents($filename, null, null, 0, 26); - - if ( substr($data, 0, 2) === "BM" ) { - $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data); - $width = (int)$meta['width']; - $height = (int)$meta['height']; - $type = IMAGETYPE_BMP; - } - } - - return $cache[$filename] = array($width, $height, $type); -} - -/** - * Converts a CMYK color to RGB - * - * @param float|float[] $c - * @param float $m - * @param float $y - * @param float $k - * - * @return float[] - */ -function cmyk_to_rgb($c, $m = null, $y = null, $k = null) { - if (is_array($c)) { - list($c, $m, $y, $k) = $c; - } - - $c *= 255; - $m *= 255; - $y *= 255; - $k *= 255; - - $r = (1 - round(2.55 * ($c+$k))) ; - $g = (1 - round(2.55 * ($m+$k))) ; - $b = (1 - round(2.55 * ($y+$k))) ; - - if ($r < 0) $r = 0; - if ($g < 0) $g = 0; - if ($b < 0) $b = 0; - - return array( - $r, $g, $b, - "r" => $r, "g" => $g, "b" => $b - ); -} - -function unichr($c) { - if ($c <= 0x7F) { - return chr($c); - } - else if ($c <= 0x7FF) { - return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F); - } - else if ($c <= 0xFFFF) { - return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F) - . chr(0x80 | $c & 0x3F); - } - else if ($c <= 0x10FFFF) { - return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) - . chr(0x80 | $c >> 6 & 0x3F) - . chr(0x80 | $c & 0x3F); - } - return false; -} - -if ( !function_exists("date_default_timezone_get") ) { - function date_default_timezone_get() { - return ""; - } - - function date_default_timezone_set($timezone_identifier) { - return true; - } -} - -/** - * Stores warnings in an array for display later - * This function allows warnings generated by the DomDocument parser - * and CSS loader ({@link Stylesheet}) to be captured and displayed - * later. Without this function, errors are displayed immediately and - * PDF streaming is impossible. - * @see http://www.php.net/manual/en/function.set-error_handler.php - * - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param string $errline - * - * @throws DOMPDF_Exception - */ -function record_warnings($errno, $errstr, $errfile, $errline) { - - // Not a warning or notice - if ( !($errno & (E_WARNING | E_NOTICE | E_USER_NOTICE | E_USER_WARNING )) ) { - throw new DOMPDF_Exception($errstr . " $errno"); - } - - global $_dompdf_warnings; - global $_dompdf_show_warnings; - - if ( $_dompdf_show_warnings ) { - echo $errstr . "\n"; - } - - $_dompdf_warnings[] = $errstr; -} - -/** - * Print a useful backtrace - */ -function bt() { - if ( php_sapi_name() !== "cli") { - echo "
";
-  }
-    
-  $bt = debug_backtrace();
-
-  array_shift($bt); // remove actual bt() call
-  echo "\n";
-
-  $i = 0;
-  foreach ($bt as $call) {
-    $file = basename($call["file"]) . " (" . $call["line"] . ")";
-    if ( isset($call["class"]) ) {
-      $func = $call["class"] . "->" . $call["function"] . "()";
-    }
-    else {
-      $func = $call["function"] . "()";
-    }
-
-    echo "#" . str_pad($i, 2, " ", STR_PAD_RIGHT) . ": " . str_pad($file.":", 42) . " $func\n";
-    $i++;
-  }
-  echo "\n";
-  
-  if ( php_sapi_name() !== "cli") {
-    echo "
"; - } -} - -/** - * Print debug messages - * - * @param string $type The type of debug messages to print - * @param string $msg The message to show - */ -function dompdf_debug($type, $msg) { - global $_DOMPDF_DEBUG_TYPES, $_dompdf_show_warnings, $_dompdf_debug; - if ( isset($_DOMPDF_DEBUG_TYPES[$type]) && ($_dompdf_show_warnings || $_dompdf_debug) ) { - $arr = debug_backtrace(); - - echo basename($arr[0]["file"]) . " (" . $arr[0]["line"] ."): " . $arr[1]["function"] . ": "; - pre_r($msg); - } -} - -if ( !function_exists("print_memusage") ) { -/** - * Dump memory usage - */ -function print_memusage() { - global $memusage; - echo "Memory Usage\n"; - $prev = 0; - $initial = reset($memusage); - echo str_pad("Initial:", 40) . $initial . "\n\n"; - - foreach ($memusage as $key=>$mem) { - $mem -= $initial; - echo str_pad("$key:" , 40); - echo str_pad("$mem", 12) . "(diff: " . ($mem - $prev) . ")\n"; - $prev = $mem; - } - - echo "\n" . str_pad("Total:", 40) . memory_get_usage() . "\n"; -} -} - -if ( !function_exists("enable_mem_profile") ) { -/** - * Initialize memory profiling code - */ -function enable_mem_profile() { - global $memusage; - $memusage = array("Startup" => memory_get_usage()); - register_shutdown_function("print_memusage"); -} -} - -if ( !function_exists("mark_memusage") ) { -/** - * Record the current memory usage - * - * @param string $location a meaningful location - */ -function mark_memusage($location) { - global $memusage; - if ( isset($memusage) ) { - $memusage[$location] = memory_get_usage(); - } -} -} - -if ( !function_exists('sys_get_temp_dir')) { -/** - * Find the current system temporary directory - * - * @link http://us.php.net/manual/en/function.sys-get-temp-dir.php#85261 - */ -function sys_get_temp_dir() { - if (!empty($_ENV['TMP'])) { - return realpath($_ENV['TMP']); - } - - if (!empty($_ENV['TMPDIR'])) { - return realpath( $_ENV['TMPDIR']); - } - - if (!empty($_ENV['TEMP'])) { - return realpath( $_ENV['TEMP']); - } - - $tempfile=tempnam(uniqid(rand(), true), ''); - if (file_exists($tempfile)) { - unlink($tempfile); - return realpath(dirname($tempfile)); - } -} -} - -if ( function_exists("memory_get_peak_usage") ) { - function DOMPDF_memory_usage(){ - return memory_get_peak_usage(true); - } -} -else if ( function_exists("memory_get_usage") ) { - function DOMPDF_memory_usage(){ - return memory_get_usage(true); - } -} -else { - function DOMPDF_memory_usage(){ - return "N/A"; - } -} - -if ( function_exists("curl_init") ) { - function DOMPDF_fetch_url($url, &$headers = null) { - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HEADER, true); - - $data = curl_exec($ch); - $raw_headers = substr($data, 0, curl_getinfo($ch, CURLINFO_HEADER_SIZE)); - $headers = preg_split("/[\n\r]+/", trim($raw_headers)); - $data = substr($data, curl_getinfo($ch, CURLINFO_HEADER_SIZE)); - curl_close($ch); - - return $data; - } -} -else { - function DOMPDF_fetch_url($url, &$headers = null) { - $data = file_get_contents($url); - $headers = $http_response_header; - - return $data; - } -} - -/** - * Affect null to the unused objects - * @param mixed $object - */ -if ( PHP_VERSION_ID < 50300 ) { - function clear_object(&$object) { - if ( is_object($object) ) { - foreach ($object as &$value) { - clear_object($value); - } - } - - $object = null; - unset($object); - } -} -else { - function clear_object(&$object) { - // void - } -} diff --git a/application/helpers/dompdf/include/gd_adapter.cls.php b/application/helpers/dompdf/include/gd_adapter.cls.php deleted file mode 100755 index de5c1e452..000000000 --- a/application/helpers/dompdf/include/gd_adapter.cls.php +++ /dev/null @@ -1,840 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Image rendering interface - * - * Renders to an image format supported by GD (jpeg, gif, png, xpm). - * Not super-useful day-to-day but handy nonetheless - * - * @package dompdf - */ -class GD_Adapter implements Canvas { - /** - * @var DOMPDF - */ - private $_dompdf; - - /** - * Resource handle for the image - * - * @var resource - */ - private $_img; - - /** - * Image width in pixels - * - * @var int - */ - private $_width; - - /** - * Image height in pixels - * - * @var int - */ - private $_height; - - /** - * Current page number - * - * @var int - */ - private $_page_number; - - /** - * Total number of pages - * - * @var int - */ - private $_page_count; - - /** - * Image antialias factor - * - * @var float - */ - private $_aa_factor; - - /** - * Allocated colors - * - * @var array - */ - private $_colors; - - /** - * Background color - * - * @var int - */ - private $_bg_color; - - /** - * Class constructor - * - * @param mixed $size The size of image to create: array(x1,y1,x2,y2) or "letter", "legal", etc. - * @param string $orientation The orientation of the document (either 'landscape' or 'portrait') - * @param DOMPDF $dompdf - * @param float $aa_factor Anti-aliasing factor, 1 for no AA - * @param array $bg_color Image background color: array(r,g,b,a), 0 <= r,g,b,a <= 1 - */ - function __construct($size, $orientation = "portrait", DOMPDF $dompdf, $aa_factor = 1.0, $bg_color = array(1,1,1,0) ) { - - if ( !is_array($size) ) { - $size = strtolower($size); - - if ( isset(CPDF_Adapter::$PAPER_SIZES[$size]) ) { - $size = CPDF_Adapter::$PAPER_SIZES[$size]; - } - else { - $size = CPDF_Adapter::$PAPER_SIZES["letter"]; - } - } - - if ( strtolower($orientation) === "landscape" ) { - list($size[2],$size[3]) = array($size[3],$size[2]); - } - - $this->_dompdf = $dompdf; - - if ( $aa_factor < 1 ) { - $aa_factor = 1; - } - - $this->_aa_factor = $aa_factor; - - $size[2] *= $aa_factor; - $size[3] *= $aa_factor; - - $this->_width = $size[2] - $size[0]; - $this->_height = $size[3] - $size[1]; - - $this->_img = imagecreatetruecolor($this->_width, $this->_height); - - if ( is_null($bg_color) || !is_array($bg_color) ) { - // Pure white bg - $bg_color = array(1,1,1,0); - } - - $this->_bg_color = $this->_allocate_color($bg_color); - imagealphablending($this->_img, true); - imagesavealpha($this->_img, true); - imagefill($this->_img, 0, 0, $this->_bg_color); - - } - - function get_dompdf(){ - return $this->_dompdf; - } - - /** - * Return the GF image resource - * - * @return resource - */ - function get_image() { return $this->_img; } - - /** - * Return the image's width in pixels - * - * @return float - */ - function get_width() { return $this->_width / $this->_aa_factor; } - - /** - * Return the image's height in pixels - * - * @return float - */ - function get_height() { return $this->_height / $this->_aa_factor; } - - /** - * Returns the current page number - * @return int - */ - function get_page_number() { return $this->_page_number; } - - /** - * Returns the total number of pages in the document - * @return int - */ - function get_page_count() { return $this->_page_count; } - - /** - * Sets the current page number - * - * @param int $num - */ - function set_page_number($num) { $this->_page_number = $num; } - - /** - * Sets the page count - * - * @param int $count - */ - function set_page_count($count) { $this->_page_count = $count; } - - /** - * Sets the opacity - * - * @param $opacity - * @param $mode - */ - function set_opacity($opacity, $mode = "Normal") { - // FIXME - } - - /** - * Allocate a new color. Allocate with GD as needed and store - * previously allocated colors in $this->_colors. - * - * @param array $color The new current color - * @return int The allocated color - */ - private function _allocate_color($color) { - - if ( isset($color["c"]) ) { - $color = cmyk_to_rgb($color); - } - - // Full opacity if no alpha set - if ( !isset($color[3]) ) - $color[3] = 0; - - list($r,$g,$b,$a) = $color; - - $r *= 255; - $g *= 255; - $b *= 255; - $a *= 127; - - // Clip values - $r = $r > 255 ? 255 : $r; - $g = $g > 255 ? 255 : $g; - $b = $b > 255 ? 255 : $b; - $a = $a > 127 ? 127 : $a; - - $r = $r < 0 ? 0 : $r; - $g = $g < 0 ? 0 : $g; - $b = $b < 0 ? 0 : $b; - $a = $a < 0 ? 0 : $a; - - $key = sprintf("#%02X%02X%02X%02X", $r, $g, $b, $a); - - if ( isset($this->_colors[$key]) ) - return $this->_colors[$key]; - - if ( $a != 0 ) - $this->_colors[$key] = imagecolorallocatealpha($this->_img, $r, $g, $b, $a); - else - $this->_colors[$key] = imagecolorallocate($this->_img, $r, $g, $b); - - return $this->_colors[$key]; - - } - - /** - * Draws a line from x1,y1 to x2,y2 - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the format of the - * $style parameter (aka dash). - * - * @param float $x1 - * @param float $y1 - * @param float $x2 - * @param float $y2 - * @param array $color - * @param float $width - * @param array $style - */ - function line($x1, $y1, $x2, $y2, $color, $width, $style = null) { - - // Scale by the AA factor - $x1 *= $this->_aa_factor; - $y1 *= $this->_aa_factor; - $x2 *= $this->_aa_factor; - $y2 *= $this->_aa_factor; - $width *= $this->_aa_factor; - - $c = $this->_allocate_color($color); - - // Convert the style array if required - if ( !is_null($style) ) { - $gd_style = array(); - - if ( count($style) == 1 ) { - for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) { - $gd_style[] = $c; - } - - for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) { - $gd_style[] = $this->_bg_color; - } - - } else { - - $i = 0; - foreach ($style as $length) { - - if ( $i % 2 == 0 ) { - // 'On' pattern - for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) - $gd_style[] = $c; - - } else { - // Off pattern - for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) - $gd_style[] = $this->_bg_color; - - } - $i++; - } - } - - imagesetstyle($this->_img, $gd_style); - $c = IMG_COLOR_STYLED; - } - - imagesetthickness($this->_img, $width); - - imageline($this->_img, $x1, $y1, $x2, $y2, $c); - - } - - function arc($x1, $y1, $r1, $r2, $astart, $aend, $color, $width, $style = array()) { - // @todo - } - - /** - * Draws a rectangle at x1,y1 with width w and height h - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the $style - * parameter (aka dash) - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - * @param array $color - * @param float $width - * @param array $style - */ - function rectangle($x1, $y1, $w, $h, $color, $width, $style = null) { - - // Scale by the AA factor - $x1 *= $this->_aa_factor; - $y1 *= $this->_aa_factor; - $w *= $this->_aa_factor; - $h *= $this->_aa_factor; - - $c = $this->_allocate_color($color); - - // Convert the style array if required - if ( !is_null($style) ) { - $gd_style = array(); - - foreach ($style as $length) { - for ($i = 0; $i < $length; $i++) { - $gd_style[] = $c; - } - } - - imagesetstyle($this->_img, $gd_style); - $c = IMG_COLOR_STYLED; - } - - imagesetthickness($this->_img, $width); - - imagerectangle($this->_img, $x1, $y1, $x1 + $w, $y1 + $h, $c); - - } - - /** - * Draws a filled rectangle at x1,y1 with width w and height h - * - * See {@link Style::munge_color()} for the format of the color array. - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - * @param array $color - */ - function filled_rectangle($x1, $y1, $w, $h, $color) { - - // Scale by the AA factor - $x1 *= $this->_aa_factor; - $y1 *= $this->_aa_factor; - $w *= $this->_aa_factor; - $h *= $this->_aa_factor; - - $c = $this->_allocate_color($color); - - imagefilledrectangle($this->_img, $x1, $y1, $x1 + $w, $y1 + $h, $c); - - } - - /** - * Starts a clipping rectangle at x1,y1 with width w and height h - * - * @param float $x1 - * @param float $y1 - * @param float $w - * @param float $h - */ - function clipping_rectangle($x1, $y1, $w, $h) { - // @todo - } - - function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) { - // @todo - } - - /** - * Ends the last clipping shape - */ - function clipping_end() { - // @todo - } - - function save() { - // @todo - } - - function restore() { - // @todo - } - - function rotate($angle, $x, $y) { - // @todo - } - - function skew($angle_x, $angle_y, $x, $y) { - // @todo - } - - function scale($s_x, $s_y, $x, $y) { - // @todo - } - - function translate($t_x, $t_y) { - // @todo - } - - function transform($a, $b, $c, $d, $e, $f) { - // @todo - } - - /** - * Draws a polygon - * - * The polygon is formed by joining all the points stored in the $points - * array. $points has the following structure: - * - * array(0 => x1, - * 1 => y1, - * 2 => x2, - * 3 => y2, - * ... - * ); - * - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the $style - * parameter (aka dash) - * - * @param array $points - * @param array $color - * @param float $width - * @param array $style - * @param bool $fill Fills the polygon if true - */ - function polygon($points, $color, $width = null, $style = null, $fill = false) { - - // Scale each point by the AA factor - foreach (array_keys($points) as $i) - $points[$i] *= $this->_aa_factor; - - $c = $this->_allocate_color($color); - - // Convert the style array if required - if ( !is_null($style) && !$fill ) { - $gd_style = array(); - - foreach ($style as $length) { - for ($i = 0; $i < $length; $i++) { - $gd_style[] = $c; - } - } - - imagesetstyle($this->_img, $gd_style); - $c = IMG_COLOR_STYLED; - } - - imagesetthickness($this->_img, $width); - - if ( $fill ) - imagefilledpolygon($this->_img, $points, count($points) / 2, $c); - else - imagepolygon($this->_img, $points, count($points) / 2, $c); - - } - - /** - * Draws a circle at $x,$y with radius $r - * - * See {@link Style::munge_color()} for the format of the color array. - * See {@link Cpdf::setLineStyle()} for a description of the $style - * parameter (aka dash) - * - * @param float $x - * @param float $y - * @param float $r - * @param array $color - * @param float $width - * @param array $style - * @param bool $fill Fills the circle if true - */ - function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false) { - - // Scale by the AA factor - $x *= $this->_aa_factor; - $y *= $this->_aa_factor; - $r *= $this->_aa_factor; - - $c = $this->_allocate_color($color); - - // Convert the style array if required - if ( !is_null($style) && !$fill ) { - $gd_style = array(); - - foreach ($style as $length) { - for ($i = 0; $i < $length; $i++) { - $gd_style[] = $c; - } - } - - imagesetstyle($this->_img, $gd_style); - $c = IMG_COLOR_STYLED; - } - - imagesetthickness($this->_img, $width); - - if ( $fill ) - imagefilledellipse($this->_img, $x, $y, $r, $r, $c); - else - imageellipse($this->_img, $x, $y, $r, $r, $c); - - } - - /** - * Add an image to the pdf. - * The image is placed at the specified x and y coordinates with the - * given width and height. - * - * @param string $img_url the path to the image - * @param float $x x position - * @param float $y y position - * @param int $w width (in pixels) - * @param int $h height (in pixels) - * @param string $resolution - * - * @return void - * @internal param string $img_type the type (e.g. extension) of the image - */ - function image($img_url, $x, $y, $w, $h, $resolution = "normal") { - $img_type = Image_Cache::detect_type($img_url); - $img_ext = Image_Cache::type_to_ext($img_type); - - if ( !$img_ext ) { - return; - } - - $func = "imagecreatefrom$img_ext"; - $src = @$func($img_url); - - if ( !$src ) { - return; // Probably should add to $_dompdf_errors or whatever here - } - - // Scale by the AA factor - $x *= $this->_aa_factor; - $y *= $this->_aa_factor; - - $w *= $this->_aa_factor; - $h *= $this->_aa_factor; - - $img_w = imagesx($src); - $img_h = imagesy($src); - - imagecopyresampled($this->_img, $src, $x, $y, 0, 0, $w, $h, $img_w, $img_h); - - } - - /** - * Writes text at the specified x and y coordinates - * See {@link Style::munge_color()} for the format of the color array. - * - * @param float $x - * @param float $y - * @param string $text the text to write - * @param string $font the font file to use - * @param float $size the font size, in points - * @param array $color - * @param float $word_spacing word spacing adjustment - * @param float $char_spacing - * @param float $angle Text angle - * - * @return void - */ - function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_spacing = 0.0, $char_spacing = 0.0, $angle = 0.0) { - - // Scale by the AA factor - $x *= $this->_aa_factor; - $y *= $this->_aa_factor; - $size *= $this->_aa_factor; - - $h = $this->get_font_height($font, $size); - $c = $this->_allocate_color($color); - - $text = mb_encode_numericentity($text, array(0x0080, 0xff, 0, 0xff), 'UTF-8'); - - $font = $this->get_ttf_file($font); - - // FIXME: word spacing - @imagettftext($this->_img, $size, $angle, $x, $y + $h, $c, $font, $text); - - } - - function javascript($code) { - // Not implemented - } - - /** - * Add a named destination (similar to ... in html) - * - * @param string $anchorname The name of the named destination - */ - function add_named_dest($anchorname) { - // Not implemented - } - - /** - * Add a link to the pdf - * - * @param string $url The url to link to - * @param float $x The x position of the link - * @param float $y The y position of the link - * @param float $width The width of the link - * @param float $height The height of the link - */ - function add_link($url, $x, $y, $width, $height) { - // Not implemented - } - - /** - * Add meta information to the PDF - * - * @param string $label label of the value (Creator, Producer, etc.) - * @param string $value the text to set - */ - function add_info($label, $value) { - // N/A - } - - function set_default_view($view, $options = array()) { - // N/A - } - - /** - * Calculates text size, in points - * - * @param string $text the text to be sized - * @param string $font the desired font - * @param float $size the desired font size - * @param float $word_spacing word spacing, if any - * @param float $char_spacing char spacing, if any - * - * @return float - */ - function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0) { - $font = $this->get_ttf_file($font); - - $text = mb_encode_numericentity($text, array(0x0080, 0xffff, 0, 0xffff), 'UTF-8'); - - // FIXME: word spacing - list($x1,,$x2) = @imagettfbbox($size, 0, $font, $text); - return $x2 - $x1; - } - - function get_ttf_file($font) { - if ( strpos($font, '.ttf') === false ) - $font .= ".ttf"; - - /*$filename = substr(strtolower(basename($font)), 0, -4); - - if ( in_array($filename, DOMPDF::$native_fonts) ) { - return "arial.ttf"; - }*/ - - return $font; - } - - /** - * Calculates font height, in points - * - * @param string $font - * @param float $size - * @return float - */ - function get_font_height($font, $size) { - $font = $this->get_ttf_file($font); - $ratio = $this->_dompdf->get_option("font_height_ratio"); - - // FIXME: word spacing - list(,$y2,,,,$y1) = imagettfbbox($size, 0, $font, "MXjpqytfhl"); // Test string with ascenders, descenders and caps - return ($y2 - $y1) * $ratio; - } - - function get_font_baseline($font, $size) { - $ratio = $this->_dompdf->get_option("font_height_ratio"); - return $this->get_font_height($font, $size) / $ratio; - } - - /** - * Starts a new page - * - * Subsequent drawing operations will appear on the new page. - */ - function new_page() { - $this->_page_number++; - $this->_page_count++; - } - - function open_object(){ - // N/A - } - - function close_object(){ - // N/A - } - - function add_object(){ - // N/A - } - - function page_text(){ - // N/A - } - - /** - * Streams the image directly to the browser - * - * @param string $filename the name of the image file (ignored) - * @param array $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only) - */ - function stream($filename, $options = null) { - - // Perform any antialiasing - if ( $this->_aa_factor != 1 ) { - $dst_w = $this->_width / $this->_aa_factor; - $dst_h = $this->_height / $this->_aa_factor; - $dst = imagecreatetruecolor($dst_w, $dst_h); - imagecopyresampled($dst, $this->_img, 0, 0, 0, 0, - $dst_w, $dst_h, - $this->_width, $this->_height); - } else { - $dst = $this->_img; - } - - if ( !isset($options["type"]) ) - $options["type"] = "png"; - - $type = strtolower($options["type"]); - - header("Cache-Control: private"); - - switch ($type) { - - case "jpg": - case "jpeg": - if ( !isset($options["quality"]) ) - $options["quality"] = 75; - - header("Content-type: image/jpeg"); - imagejpeg($dst, '', $options["quality"]); - break; - - case "png": - default: - header("Content-type: image/png"); - imagepng($dst); - break; - } - - if ( $this->_aa_factor != 1 ) - imagedestroy($dst); - } - - /** - * Returns the PNG as a string - * - * @param array $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only) - * @return string - */ - function output($options = null) { - - if ( $this->_aa_factor != 1 ) { - $dst_w = $this->_width / $this->_aa_factor; - $dst_h = $this->_height / $this->_aa_factor; - $dst = imagecreatetruecolor($dst_w, $dst_h); - imagecopyresampled($dst, $this->_img, 0, 0, 0, 0, - $dst_w, $dst_h, - $this->_width, $this->_height); - } else { - $dst = $this->_img; - } - - if ( !isset($options["type"]) ) - $options["type"] = "png"; - - $type = $options["type"]; - - ob_start(); - - switch ($type) { - - case "jpg": - case "jpeg": - if ( !isset($options["quality"]) ) - $options["quality"] = 75; - - imagejpeg($dst, '', $options["quality"]); - break; - - case "png": - default: - imagepng($dst); - break; - } - - $image = ob_get_clean(); - - if ( $this->_aa_factor != 1 ) - imagedestroy($dst); - - return $image; - } - - -} diff --git a/application/helpers/dompdf/include/image_cache.cls.php b/application/helpers/dompdf/include/image_cache.cls.php deleted file mode 100755 index 7d7e5603b..000000000 --- a/application/helpers/dompdf/include/image_cache.cls.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Static class that resolves image urls and downloads and caches - * remote images if required. - * - * @access private - * @package dompdf - */ -class Image_Cache { - - /** - * Array of downloaded images. Cached so that identical images are - * not needlessly downloaded. - * - * @var array - */ - static protected $_cache = array(); - - /** - * The url to the "broken image" used when images can't be loade - * - * @var string - */ - public static $broken_image; - - /** - * Resolve and fetch an image for use. - * - * @param string $url The url of the image - * @param string $protocol Default protocol if none specified in $url - * @param string $host Default host if none specified in $url - * @param string $base_path Default path if none specified in $url - * @param DOMPDF $dompdf The DOMPDF instance - * - * @throws DOMPDF_Image_Exception - * @return array An array with two elements: The local path to the image and the image extension - */ - static function resolve_url($url, $protocol, $host, $base_path, DOMPDF $dompdf) { - $parsed_url = explode_url($url); - $message = null; - - $remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != ""); - - $data_uri = strpos($parsed_url['protocol'], "data:") === 0; - $full_url = null; - $enable_remote = $dompdf->get_option("enable_remote"); - - try { - - // Remote not allowed and is not DataURI - if ( !$enable_remote && $remote && !$data_uri ) { - throw new DOMPDF_Image_Exception("DOMPDF_ENABLE_REMOTE is set to FALSE"); - } - - // Remote allowed or DataURI - else if ( $enable_remote && $remote || $data_uri ) { - // Download remote files to a temporary directory - $full_url = build_url($protocol, $host, $base_path, $url); - - // From cache - if ( isset(self::$_cache[$full_url]) ) { - $resolved_url = self::$_cache[$full_url]; - } - - // From remote - else { - $tmp_dir = $dompdf->get_option("temp_dir"); - $resolved_url = tempnam($tmp_dir, "ca_dompdf_img_"); - $image = ""; - - if ($data_uri) { - if ($parsed_data_uri = parse_data_uri($url)) { - $image = $parsed_data_uri['data']; - } - } - else { - set_error_handler("record_warnings"); - $image = file_get_contents($full_url); - restore_error_handler(); - } - - // Image not found or invalid - if ( strlen($image) == 0 ) { - $msg = ($data_uri ? "Data-URI could not be parsed" : "Image not found"); - throw new DOMPDF_Image_Exception($msg); - } - - // Image found, put in cache and process - else { - //e.g. fetch.php?media=url.jpg&cache=1 - //- Image file name might be one of the dynamic parts of the url, don't strip off! - //- a remote url does not need to have a file extension at all - //- local cached file does not have a matching file extension - //Therefore get image type from the content - file_put_contents($resolved_url, $image); - } - } - } - - // Not remote, local image - else { - $resolved_url = build_url($protocol, $host, $base_path, $url); - } - - // Check if the local file is readable - if ( !is_readable($resolved_url) || !filesize($resolved_url) ) { - throw new DOMPDF_Image_Exception("Image not readable or empty"); - } - - // Check is the file is an image - else { - list($width, $height, $type) = dompdf_getimagesize($resolved_url); - - // Known image type - if ( $width && $height && in_array($type, array(IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP)) ) { - //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup. - //Only execute on successful caching of remote image. - if ( $enable_remote && $remote || $data_uri ) { - self::$_cache[$full_url] = $resolved_url; - } - } - - // Unknown image type - else { - throw new DOMPDF_Image_Exception("Image type unknown"); - } - } - } - catch(DOMPDF_Image_Exception $e) { - $resolved_url = self::$broken_image; - $type = IMAGETYPE_PNG; - $message = $e->getMessage()." \n $url"; - } - - return array($resolved_url, $type, $message); - } - - /** - * Unlink all cached images (i.e. temporary images either downloaded - * or converted) - */ - static function clear() { - if ( empty(self::$_cache) || DEBUGKEEPTEMP ) return; - - foreach ( self::$_cache as $file ) { - if (DEBUGPNG) print "[clear unlink $file]"; - unlink($file); - } - - self::$_cache = array(); - } - - static function detect_type($file) { - list(, , $type) = dompdf_getimagesize($file); - return $type; - } - - static function type_to_ext($type) { - $image_types = array( - IMAGETYPE_GIF => "gif", - IMAGETYPE_PNG => "png", - IMAGETYPE_JPEG => "jpeg", - IMAGETYPE_BMP => "bmp", - ); - - return (isset($image_types[$type]) ? $image_types[$type] : null); - } - - static function is_broken($url) { - return $url === self::$broken_image; - } -} - -Image_Cache::$broken_image = DOMPDF_LIB_DIR . "/res/broken_image.png"; diff --git a/application/helpers/dompdf/include/image_frame_decorator.cls.php b/application/helpers/dompdf/include/image_frame_decorator.cls.php deleted file mode 100755 index b5a7983aa..000000000 --- a/application/helpers/dompdf/include/image_frame_decorator.cls.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Decorates frames for image layout and rendering - * - * @access private - * @package dompdf - */ -class Image_Frame_Decorator extends Frame_Decorator { - - /** - * The path to the image file (note that remote images are - * downloaded locally to DOMPDF_TEMP_DIR). - * - * @var string - */ - protected $_image_url; - - /** - * The image's file error message - * - * @var string - */ - protected $_image_msg; - - /** - * Class constructor - * - * @param Frame $frame the frame to decorate - * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) - */ - function __construct(Frame $frame, DOMPDF $dompdf) { - parent::__construct($frame, $dompdf); - $url = $frame->get_node()->getAttribute("src"); - - $debug_png = $dompdf->get_option("debug_png"); - if ($debug_png) print '[__construct '.$url.']'; - - list($this->_image_url, /*$type*/, $this->_image_msg) = Image_Cache::resolve_url( - $url, - $dompdf->get_protocol(), - $dompdf->get_host(), - $dompdf->get_base_path(), - $dompdf - ); - - if ( Image_Cache::is_broken($this->_image_url) && - $alt = $frame->get_node()->getAttribute("alt") ) { - $style = $frame->get_style(); - $style->width = (4/3)*Font_Metrics::get_text_width($alt, $style->font_family, $style->font_size, $style->word_spacing); - $style->height = Font_Metrics::get_font_height($style->font_family, $style->font_size); - } - } - - /** - * Return the image's url - * - * @return string The url of this image - */ - function get_image_url() { - return $this->_image_url; - } - - /** - * Return the image's error message - * - * @return string The image's error message - */ - function get_image_msg() { - return $this->_image_msg; - } - -} diff --git a/application/helpers/dompdf/include/image_frame_reflower.cls.php b/application/helpers/dompdf/include/image_frame_reflower.cls.php deleted file mode 100755 index 5797b8243..000000000 --- a/application/helpers/dompdf/include/image_frame_reflower.cls.php +++ /dev/null @@ -1,186 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Image reflower class - * - * @access private - * @package dompdf - */ -class Image_Frame_Reflower extends Frame_Reflower { - - function __construct(Image_Frame_Decorator $frame) { - parent::__construct($frame); - } - - function reflow(Block_Frame_Decorator $block = null) { - $this->_frame->position(); - - //FLOAT - //$frame = $this->_frame; - //$page = $frame->get_root(); - - //$enable_css_float = $this->get_dompdf()->get_option("enable_css_float"); - //if ($enable_css_float && $frame->get_style()->float !== "none" ) { - // $page->add_floating_frame($this); - //} - // Set the frame's width - $this->get_min_max_width(); - - if ( $block ) { - $block->add_frame_to_line($this->_frame); - } - } - - function get_min_max_width() { - if (DEBUGPNG) { - // Determine the image's size. Time consuming. Only when really needed? - list($img_width, $img_height) = dompdf_getimagesize($this->_frame->get_image_url()); - print "get_min_max_width() ". - $this->_frame->get_style()->width.' '. - $this->_frame->get_style()->height.';'. - $this->_frame->get_parent()->get_style()->width." ". - $this->_frame->get_parent()->get_style()->height.";". - $this->_frame->get_parent()->get_parent()->get_style()->width.' '. - $this->_frame->get_parent()->get_parent()->get_style()->height.';'. - $img_width. ' '. - $img_height.'|' ; - } - - $style = $this->_frame->get_style(); - - $width_forced = true; - $height_forced = true; - - //own style auto or invalid value: use natural size in px - //own style value: ignore suffix text including unit, use given number as px - //own style %: walk up parent chain until found available space in pt; fill available space - // - //special ignored unit: e.g. 10ex: e treated as exponent; x ignored; 10e completely invalid ->like auto - - $width = ($style->width > 0 ? $style->width : 0); - if ( is_percent($width) ) { - $t = 0.0; - for ($f = $this->_frame->get_parent(); $f; $f = $f->get_parent()) { - $f_style = $f->get_style(); - $t = $f_style->length_in_pt($f_style->width); - if ($t != 0) { - break; - } - } - $width = ((float)rtrim($width,"%") * $t)/100; //maybe 0 - } elseif ( !mb_strpos($width, 'pt') ) { - // Don't set image original size if "%" branch was 0 or size not given. - // Otherwise aspect changed on %/auto combination for width/height - // Resample according to px per inch - // See also List_Bullet_Image_Frame_Decorator::__construct - $width = $style->length_in_pt($width); - } - - $height = ($style->height > 0 ? $style->height : 0); - if ( is_percent($height) ) { - $t = 0.0; - for ($f = $this->_frame->get_parent(); $f; $f = $f->get_parent()) { - $f_style = $f->get_style(); - $t = $f_style->length_in_pt($f_style->height); - if ($t != 0) { - break; - } - } - $height = ((float)rtrim($height,"%") * $t)/100; //maybe 0 - } elseif ( !mb_strpos($height, 'pt') ) { - // Don't set image original size if "%" branch was 0 or size not given. - // Otherwise aspect changed on %/auto combination for width/height - // Resample according to px per inch - // See also List_Bullet_Image_Frame_Decorator::__construct - $height = $style->length_in_pt($height); - } - - if ($width == 0 || $height == 0) { - // Determine the image's size. Time consuming. Only when really needed! - list($img_width, $img_height) = dompdf_getimagesize($this->_frame->get_image_url()); - - // don't treat 0 as error. Can be downscaled or can be catched elsewhere if image not readable. - // Resample according to px per inch - // See also List_Bullet_Image_Frame_Decorator::__construct - if ($width == 0 && $height == 0) { - $dpi = $this->_frame->get_dompdf()->get_option("dpi"); - $width = (float)($img_width * 72) / $dpi; - $height = (float)($img_height * 72) / $dpi; - $width_forced = false; - $height_forced = false; - } elseif ($height == 0 && $width != 0) { - $height_forced = false; - $height = ($width / $img_width) * $img_height; //keep aspect ratio - } elseif ($width == 0 && $height != 0) { - $width_forced = false; - $width = ($height / $img_height) * $img_width; //keep aspect ratio - } - } - - // Handle min/max width/height - if ( $style->min_width !== "none" || - $style->max_width !== "none" || - $style->min_height !== "none" || - $style->max_height !== "none" ) { - - list(/*$x*/, /*$y*/, $w, $h) = $this->_frame->get_containing_block(); - - $min_width = $style->length_in_pt($style->min_width, $w); - $max_width = $style->length_in_pt($style->max_width, $w); - $min_height = $style->length_in_pt($style->min_height, $h); - $max_height = $style->length_in_pt($style->max_height, $h); - - if ( $max_width !== "none" && $width > $max_width ) { - if ( !$height_forced ) { - $height *= $max_width / $width; - } - - $width = $max_width; - } - - if ( $min_width !== "none" && $width < $min_width ) { - if ( !$height_forced ) { - $height *= $min_width / $width; - } - - $width = $min_width; - } - - if ( $max_height !== "none" && $height > $max_height ) { - if ( !$width_forced ) { - $width *= $max_height / $height; - } - - $height = $max_height; - } - - if ( $min_height !== "none" && $height < $min_height ) { - if ( !$width_forced ) { - $width *= $min_height / $height; - } - - $height = $min_height; - } - } - - if (DEBUGPNG) print $width.' '.$height.';'; - - $style->width = $width . "pt"; - $style->height = $height . "pt"; - - $style->min_width = "none"; - $style->max_width = "none"; - $style->min_height = "none"; - $style->max_height = "none"; - - return array( $width, $width, "min" => $width, "max" => $width); - - } -} diff --git a/application/helpers/dompdf/include/image_renderer.cls.php b/application/helpers/dompdf/include/image_renderer.cls.php deleted file mode 100755 index 561b70153..000000000 --- a/application/helpers/dompdf/include/image_renderer.cls.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Image renderer - * - * @access private - * @package dompdf - */ -class Image_Renderer extends Block_Renderer { - - function render(Frame $frame) { - // Render background & borders - $style = $frame->get_style(); - $cb = $frame->get_containing_block(); - list($x, $y, $w, $h) = $frame->get_border_box(); - - $this->_set_opacity( $frame->get_opacity( $style->opacity ) ); - - list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); - - $has_border_radius = $tl + $tr + $br + $bl > 0; - - if ( $has_border_radius ) { - $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl ); - } - - if ( ($bg = $style->background_color) !== "transparent" ) { - $this->_canvas->filled_rectangle($x, $y, $w, $h, $bg); - } - - if ( ($url = $style->background_image) && $url !== "none" ) { - $this->_background_image($url, $x, $y, $w, $h, $style); - } - - if ( $has_border_radius ) { - $this->_canvas->clipping_end(); - } - - $this->_render_border($frame); - $this->_render_outline($frame); - - list($x, $y) = $frame->get_padding_box(); - - $x += $style->length_in_pt($style->padding_left, $cb["w"]); - $y += $style->length_in_pt($style->padding_top, $cb["h"]); - - $w = $style->length_in_pt($style->width, $cb["w"]); - $h = $style->length_in_pt($style->height, $cb["h"]); - - if ( $has_border_radius ) { - list($wt, $wr, $wb, $wl) = array( - $style->border_top_width, - $style->border_right_width, - $style->border_bottom_width, - $style->border_left_width, - ); - - // we have to get the "inner" radius - if ( $tl > 0 ) { - $tl -= ($wt + $wl) / 2; - } - if ( $tr > 0 ) { - $tr -= ($wt + $wr) / 2; - } - if ( $br > 0 ) { - $br -= ($wb + $wr) / 2; - } - if ( $bl > 0 ) { - $bl -= ($wb + $wl) / 2; - } - - $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl ); - } - - $src = $frame->get_image_url(); - $alt = null; - - if ( Image_Cache::is_broken($src) && - $alt = $frame->get_node()->getAttribute("alt") ) { - $font = $style->font_family; - $size = $style->font_size; - $spacing = $style->word_spacing; - $this->_canvas->text($x, $y, $alt, - $font, $size, - $style->color, $spacing); - } - else { - $this->_canvas->image( $src, $x, $y, $w, $h, $style->image_resolution); - } - - if ( $has_border_radius ) { - $this->_canvas->clipping_end(); - } - - if ( $msg = $frame->get_image_msg() ) { - $parts = preg_split("/\s*\n\s*/", $msg); - $height = 10; - $_y = $alt ? $y+$h-count($parts)*$height : $y; - - foreach($parts as $i => $_part) { - $this->_canvas->text($x, $_y + $i*$height, $_part, "times", $height*0.8, array(0.5, 0.5, 0.5)); - } - } - - if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) { - $this->_debug_layout($frame->get_border_box(), "blue"); - if (DEBUG_LAYOUT_PADDINGBOX) { - $this->_debug_layout($frame->get_padding_box(), "blue", array(0.5, 0.5)); - } - } - } -} diff --git a/application/helpers/dompdf/include/inline_frame_decorator.cls.php b/application/helpers/dompdf/include/inline_frame_decorator.cls.php deleted file mode 100755 index ce79bab08..000000000 --- a/application/helpers/dompdf/include/inline_frame_decorator.cls.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @author Helmut Tischer - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Decorates frames for inline layout - * - * @access private - * @package dompdf - */ -class Inline_Frame_Decorator extends Frame_Decorator { - - function __construct(Frame $frame, DOMPDF $dompdf) { parent::__construct($frame, $dompdf); } - - function split(Frame $frame = null, $force_pagebreak = false) { - - if ( is_null($frame) ) { - $this->get_parent()->split($this, $force_pagebreak); - return; - } - - if ( $frame->get_parent() !== $this ) - throw new DOMPDF_Exception("Unable to split: frame is not a child of this one."); - - $split = $this->copy( $this->_frame->get_node()->cloneNode() ); - $this->get_parent()->insert_child_after($split, $this); - - // Unset the current node's right style properties - $style = $this->_frame->get_style(); - $style->margin_right = 0; - $style->padding_right = 0; - $style->border_right_width = 0; - - // Unset the split node's left style properties since we don't want them - // to propagate - $style = $split->get_style(); - $style->margin_left = 0; - $style->padding_left = 0; - $style->border_left_width = 0; - - //On continuation of inline element on next line, - //don't repeat non-vertically repeatble background images - //See e.g. in testcase image_variants, long desriptions - if ( ($url = $style->background_image) && $url !== "none" - && ($repeat = $style->background_repeat) && $repeat !== "repeat" && $repeat !== "repeat-y" - ) { - $style->background_image = "none"; - } - - // Add $frame and all following siblings to the new split node - $iter = $frame; - while ($iter) { - $frame = $iter; - $iter = $iter->get_next_sibling(); - $frame->reset(); - $split->append_child($frame); - } - - $page_breaks = array("always", "left", "right"); - $frame_style = $frame->get_style(); - if( $force_pagebreak || - in_array($frame_style->page_break_before, $page_breaks) || - in_array($frame_style->page_break_after, $page_breaks) ) { - - $this->get_parent()->split($split, true); - } - } - -} diff --git a/application/helpers/dompdf/include/inline_frame_reflower.cls.php b/application/helpers/dompdf/include/inline_frame_reflower.cls.php deleted file mode 100755 index 049b8e586..000000000 --- a/application/helpers/dompdf/include/inline_frame_reflower.cls.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Reflows inline frames - * - * @access private - * @package dompdf - */ -class Inline_Frame_Reflower extends Frame_Reflower { - - function __construct(Frame $frame) { parent::__construct($frame); } - - //........................................................................ - - function reflow(Block_Frame_Decorator $block = null) { - $frame = $this->_frame; - - // Check if a page break is forced - $page = $frame->get_root(); - $page->check_forced_page_break($frame); - - if ( $page->is_full() ) - return; - - $style = $frame->get_style(); - - // Generated content - $this->_set_content(); - - $frame->position(); - - $cb = $frame->get_containing_block(); - - // Add our margin, padding & border to the first and last children - if ( ($f = $frame->get_first_child()) && $f instanceof Text_Frame_Decorator ) { - $f_style = $f->get_style(); - $f_style->margin_left = $style->margin_left; - $f_style->padding_left = $style->padding_left; - $f_style->border_left = $style->border_left; - } - - if ( ($l = $frame->get_last_child()) && $l instanceof Text_Frame_Decorator ) { - $l_style = $l->get_style(); - $l_style->margin_right = $style->margin_right; - $l_style->padding_right = $style->padding_right; - $l_style->border_right = $style->border_right; - } - - if ( $block ) { - $block->add_frame_to_line($this->_frame); - } - - // Set the containing blocks and reflow each child. The containing - // block is not changed by line boxes. - foreach ( $frame->get_children() as $child ) { - $child->set_containing_block($cb); - $child->reflow($block); - } - } -} diff --git a/application/helpers/dompdf/include/inline_positioner.cls.php b/application/helpers/dompdf/include/inline_positioner.cls.php deleted file mode 100755 index 1694ce8e2..000000000 --- a/application/helpers/dompdf/include/inline_positioner.cls.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Positions inline frames - * - * @access private - * @package dompdf - */ -class Inline_Positioner extends Positioner { - - function __construct(Frame_Decorator $frame) { parent::__construct($frame); } - - //........................................................................ - - function position() { - /** - * Find our nearest block level parent and access its lines property. - * @var Block_Frame_Decorator - */ - $p = $this->_frame->find_block_parent(); - - // Debugging code: - -// pre_r("\nPositioning:"); -// pre_r("Me: " . $this->_frame->get_node()->nodeName . " (" . spl_object_hash($this->_frame->get_node()) . ")"); -// pre_r("Parent: " . $p->get_node()->nodeName . " (" . spl_object_hash($p->get_node()) . ")"); - - // End debugging - - if ( !$p ) - throw new DOMPDF_Exception("No block-level parent found. Not good."); - - $f = $this->_frame; - - $cb = $f->get_containing_block(); - $line = $p->get_current_line_box(); - - // Skip the page break if in a fixed position element - $is_fixed = false; - while($f = $f->get_parent()) { - if($f->get_style()->position === "fixed") { - $is_fixed = true; - break; - } - } - - $f = $this->_frame; - - if ( !$is_fixed && $f->get_parent() && - $f->get_parent() instanceof Inline_Frame_Decorator && - $f->is_text_node() ) { - - $min_max = $f->get_reflower()->get_min_max_width(); - - // If the frame doesn't fit in the current line, a line break occurs - if ( $min_max["min"] > ($cb["w"] - $line->left - $line->w - $line->right) ) { - $p->add_line(); - } - } - - $f->set_position($cb["x"] + $line->w, $line->y); - - } -} diff --git a/application/helpers/dompdf/include/inline_renderer.cls.php b/application/helpers/dompdf/include/inline_renderer.cls.php deleted file mode 100755 index 7a8ff51c3..000000000 --- a/application/helpers/dompdf/include/inline_renderer.cls.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Renders inline frames - * - * @access private - * @package dompdf - */ -class Inline_Renderer extends Abstract_Renderer { - - //........................................................................ - - function render(Frame $frame) { - $style = $frame->get_style(); - - if ( !$frame->get_first_child() ) - return; // No children, no service - - // Draw the left border if applicable - $bp = $style->get_border_properties(); - $widths = array($style->length_in_pt($bp["top"]["width"]), - $style->length_in_pt($bp["right"]["width"]), - $style->length_in_pt($bp["bottom"]["width"]), - $style->length_in_pt($bp["left"]["width"])); - - // Draw the background & border behind each child. To do this we need - // to figure out just how much space each child takes: - list($x, $y) = $frame->get_first_child()->get_position(); - $w = null; - $h = 0; -// $x += $widths[3]; -// $y += $widths[0]; - - $this->_set_opacity( $frame->get_opacity( $style->opacity ) ); - - $first_row = true; - - foreach ($frame->get_children() as $child) { - list($child_x, $child_y, $child_w, $child_h) = $child->get_padding_box(); - - if ( !is_null($w) && $child_x < $x + $w ) { - //This branch seems to be supposed to being called on the first part - //of an inline html element, and the part after the if clause for the - //parts after a line break. - //But because $w initially mostly is 0, and gets updated only on the next - //round, this seem to be never executed and the common close always. - - // The next child is on another line. Draw the background & - // borders on this line. - - // Background: - if ( ($bg = $style->background_color) !== "transparent" ) - $this->_canvas->filled_rectangle( $x, $y, $w, $h, $bg); - - if ( ($url = $style->background_image) && $url !== "none" ) { - $this->_background_image($url, $x, $y, $w, $h, $style); - } - - // If this is the first row, draw the left border - if ( $first_row ) { - - if ( $bp["left"]["style"] !== "none" && $bp["left"]["color"] !== "transparent" && $bp["left"]["width"] > 0 ) { - $method = "_border_" . $bp["left"]["style"]; - $this->$method($x, $y, $h + $widths[0] + $widths[2], $bp["left"]["color"], $widths, "left"); - } - $first_row = false; - } - - // Draw the top & bottom borders - if ( $bp["top"]["style"] !== "none" && $bp["top"]["color"] !== "transparent" && $bp["top"]["width"] > 0 ) { - $method = "_border_" . $bp["top"]["style"]; - $this->$method($x, $y, $w + $widths[1] + $widths[3], $bp["top"]["color"], $widths, "top"); - } - - if ( $bp["bottom"]["style"] !== "none" && $bp["bottom"]["color"] !== "transparent" && $bp["bottom"]["width"] > 0 ) { - $method = "_border_" . $bp["bottom"]["style"]; - $this->$method($x, $y + $h + $widths[0] + $widths[2], $w + $widths[1] + $widths[3], $bp["bottom"]["color"], $widths, "bottom"); - } - - // Handle anchors & links - $link_node = null; - if ( $frame->get_node()->nodeName === "a" ) { - $link_node = $frame->get_node(); - } - else if ( $frame->get_parent()->get_node()->nodeName === "a" ){ - $link_node = $frame->get_parent()->get_node(); - } - - if ( $link_node && $href = $link_node->getAttribute("href") ) { - $this->_canvas->add_link($href, $x, $y, $w, $h); - } - - $x = $child_x; - $y = $child_y; - $w = $child_w; - $h = $child_h; - continue; - } - - if ( is_null($w) ) - $w = $child_w; - else - $w += $child_w; - - $h = max($h, $child_h); - - if (DEBUG_LAYOUT && DEBUG_LAYOUT_INLINE) { - $this->_debug_layout($child->get_border_box(), "blue"); - if (DEBUG_LAYOUT_PADDINGBOX) { - $this->_debug_layout($child->get_padding_box(), "blue", array(0.5, 0.5)); - } - } - } - - - // Handle the last child - if ( ($bg = $style->background_color) !== "transparent" ) - $this->_canvas->filled_rectangle( $x + $widths[3], $y + $widths[0], $w, $h, $bg); - - //On continuation lines (after line break) of inline elements, the style got copied. - //But a non repeatable background image should not be repeated on the next line. - //But removing the background image above has never an effect, and removing it below - //removes it always, even on the initial line. - //Need to handle it elsewhere, e.g. on certain ...clone()... usages. - // Repeat not given: default is Style::__construct - // ... && (!($repeat = $style->background_repeat) || $repeat === "repeat" ... - //different position? $this->_background_image($url, $x, $y, $w, $h, $style); - if ( ($url = $style->background_image) && $url !== "none" ) - $this->_background_image($url, $x + $widths[3], $y + $widths[0], $w, $h, $style); - - // Add the border widths - $w += $widths[1] + $widths[3]; - $h += $widths[0] + $widths[2]; - - // make sure the border and background start inside the left margin - $left_margin = $style->length_in_pt($style->margin_left); - $x += $left_margin; - - // If this is the first row, draw the left border too - if ( $first_row && $bp["left"]["style"] !== "none" && $bp["left"]["color"] !== "transparent" && $widths[3] > 0 ) { - $method = "_border_" . $bp["left"]["style"]; - $this->$method($x, $y, $h, $bp["left"]["color"], $widths, "left"); - } - - // Draw the top & bottom borders - if ( $bp["top"]["style"] !== "none" && $bp["top"]["color"] !== "transparent" && $widths[0] > 0 ) { - $method = "_border_" . $bp["top"]["style"]; - $this->$method($x, $y, $w, $bp["top"]["color"], $widths, "top"); - } - - if ( $bp["bottom"]["style"] !== "none" && $bp["bottom"]["color"] !== "transparent" && $widths[2] > 0 ) { - $method = "_border_" . $bp["bottom"]["style"]; - $this->$method($x, $y + $h, $w, $bp["bottom"]["color"], $widths, "bottom"); - } - - // pre_var_dump(get_class($frame->get_next_sibling())); - // $last_row = get_class($frame->get_next_sibling()) !== 'Inline_Frame_Decorator'; - // Draw the right border if this is the last row - if ( $bp["right"]["style"] !== "none" && $bp["right"]["color"] !== "transparent" && $widths[1] > 0 ) { - $method = "_border_" . $bp["right"]["style"]; - $this->$method($x + $w, $y, $h, $bp["right"]["color"], $widths, "right"); - } - - // Only two levels of links frames - $link_node = null; - if ( $frame->get_node()->nodeName === "a" ) { - $link_node = $frame->get_node(); - - if ( ($name = $link_node->getAttribute("name")) || ($name = $link_node->getAttribute("id")) ) { - $this->_canvas->add_named_dest($name); - } - } - - if ( $frame->get_parent() && $frame->get_parent()->get_node()->nodeName === "a" ){ - $link_node = $frame->get_parent()->get_node(); - } - - // Handle anchors & links - if ( $link_node ) { - if ( $href = $link_node->getAttribute("href") ) - $this->_canvas->add_link($href, $x, $y, $w, $h); - } - } -} diff --git a/application/helpers/dompdf/include/javascript_embedder.cls.php b/application/helpers/dompdf/include/javascript_embedder.cls.php deleted file mode 100755 index 92c244b2d..000000000 --- a/application/helpers/dompdf/include/javascript_embedder.cls.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Embeds Javascript into the PDF document - * - * @access private - * @package dompdf - */ -class Javascript_Embedder { - - /** - * @var DOMPDF - */ - protected $_dompdf; - - function __construct(DOMPDF $dompdf) { - $this->_dompdf = $dompdf; - } - - function insert($script) { - $this->_dompdf->get_canvas()->javascript($script); - } - - function render(Frame $frame) { - if ( !$this->_dompdf->get_option("enable_javascript") ) { - return; - } - - $this->insert($frame->get_node()->nodeValue); - } -} diff --git a/application/helpers/dompdf/include/line_box.cls.php b/application/helpers/dompdf/include/line_box.cls.php deleted file mode 100755 index 352359729..000000000 --- a/application/helpers/dompdf/include/line_box.cls.php +++ /dev/null @@ -1,252 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * The line box class - * - * This class represents a line box - * http://www.w3.org/TR/CSS2/visuren.html#line-box - * - * @access protected - * @package dompdf - */ -class Line_Box { - - /** - * @var Block_Frame_Decorator - */ - protected $_block_frame; - - /** - * @var Frame[] - */ - protected $_frames = array(); - - /** - * @var integer - */ - public $wc = 0; - - /** - * @var float - */ - public $y = null; - - /** - * @var float - */ - public $w = 0.0; - - /** - * @var float - */ - public $h = 0.0; - - /** - * @var float - */ - public $left = 0.0; - - /** - * @var float - */ - public $right = 0.0; - - /** - * @var Frame - */ - public $tallest_frame = null; - - /** - * @var bool[] - */ - public $floating_blocks = array(); - - /** - * @var bool - */ - public $br = false; - - /** - * Class constructor - * - * @param Block_Frame_Decorator $frame the Block_Frame_Decorator containing this line - */ - function __construct(Block_Frame_Decorator $frame, $y = 0) { - $this->_block_frame = $frame; - $this->_frames = array(); - $this->y = $y; - - $this->get_float_offsets(); - } - - /** - * Returns the floating elements inside the first floating parent - * - * @param Page_Frame_Decorator $root - * - * @return Frame[] - */ - function get_floats_inside(Page_Frame_Decorator $root) { - $floating_frames = $root->get_floating_frames(); - - if ( count($floating_frames) == 0 ) { - return $floating_frames; - } - - // Find nearest floating element - $p = $this->_block_frame; - while( $p->get_style()->float === "none" ) { - $parent = $p->get_parent(); - - if ( !$parent ) { - break; - } - - $p = $parent; - } - - if ( $p == $root ) { - return $floating_frames; - } - - $parent = $p; - - $childs = array(); - - foreach ($floating_frames as $_floating) { - $p = $_floating->get_parent(); - - while (($p = $p->get_parent()) && $p !== $parent); - - if ( $p ) { - $childs[] = $p; - } - } - - return $childs; - } - - function get_float_offsets() { - $enable_css_float = $this->_block_frame->get_dompdf()->get_option("enable_css_float"); - if ( !$enable_css_float ) { - return; - } - - static $anti_infinite_loop = 500; // FIXME smelly hack - - $reflower = $this->_block_frame->get_reflower(); - - if ( !$reflower ) { - return; - } - - $cb_w = null; - - $block = $this->_block_frame; - $root = $block->get_root(); - - if ( !$root ) { - return; - } - - $floating_frames = $this->get_floats_inside($root); - - foreach ( $floating_frames as $child_key => $floating_frame ) { - $id = $floating_frame->get_id(); - - if ( isset($this->floating_blocks[$id]) ) { - continue; - } - - $floating_style = $floating_frame->get_style(); - $float = $floating_style->float; - - $floating_width = $floating_frame->get_margin_width(); - - if (!$cb_w) { - $cb_w = $floating_frame->get_containing_block("w"); - } - - $line_w = $this->get_width(); - - if ( !$floating_frame->_float_next_line && ($cb_w <= $line_w + $floating_width) && ($cb_w > $line_w) ) { - $floating_frame->_float_next_line = true; - continue; - } - - // If the child is still shifted by the floating element - if ( $anti_infinite_loop-- > 0 && - $floating_frame->get_position("y") + $floating_frame->get_margin_height() > $this->y && - $block->get_position("x") + $block->get_margin_width() > $floating_frame->get_position("x") - ) { - if ( $float === "left" ) - $this->left += $floating_width; - else - $this->right += $floating_width; - - $this->floating_blocks[$id] = true; - } - - // else, the floating element won't shift anymore - else { - $root->remove_floating_frame($child_key); - } - } - } - - /** - * @return float - */ - function get_width(){ - return $this->left + $this->w + $this->right; - } - - /** - * @return Block_Frame_Decorator - */ - function get_block_frame() { - return $this->_block_frame; - } - - /** - * @return Frame[] - */ - function &get_frames() { - return $this->_frames; - } - - /** - * @param Frame $frame - */ - function add_frame(Frame $frame) { - $this->_frames[] = $frame; - } - - function __toString(){ - $props = array("wc", "y", "w", "h", "left", "right", "br"); - $s = ""; - foreach($props as $prop) { - $s .= "$prop: ".$this->$prop."\n"; - } - $s .= count($this->_frames)." frames\n"; - return $s; - } - /*function __get($prop) { - if (!isset($this->{"_$prop"})) return; - return $this->{"_$prop"}; - }*/ -} - -/* -class LineBoxList implements Iterator { - private $_p = 0; - private $_lines = array(); - -} -*/ diff --git a/application/helpers/dompdf/include/list_bullet_frame_decorator.cls.php b/application/helpers/dompdf/include/list_bullet_frame_decorator.cls.php deleted file mode 100755 index a661dc050..000000000 --- a/application/helpers/dompdf/include/list_bullet_frame_decorator.cls.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @author Helmut Tischer - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Decorates frames for list bullet rendering - * - * @access private - * @package dompdf - */ -class List_Bullet_Frame_Decorator extends Frame_Decorator { - - const BULLET_PADDING = 1; // Distance from bullet to text in pt - // As fraction of font size (including descent). See also DECO_THICKNESS. - const BULLET_THICKNESS = 0.04; // Thickness of bullet outline. Screen: 0.08, print: better less, e.g. 0.04 - const BULLET_DESCENT = 0.3; //descent of font below baseline. Todo: Guessed for now. - const BULLET_SIZE = 0.35; // bullet diameter. For now 0.5 of font_size without descent. - - static $BULLET_TYPES = array("disc", "circle", "square"); - - //........................................................................ - - function __construct(Frame $frame, DOMPDF $dompdf) { - parent::__construct($frame, $dompdf); - } - - function get_margin_width() { - $style = $this->_frame->get_style(); - - // Small hack to prevent extra indenting of list text on list_style_position === "inside" - // and on suppressed bullet - if ( $style->list_style_position === "outside" || - $style->list_style_type === "none" ) { - return 0; - } - - return $style->get_font_size() * self::BULLET_SIZE + 2 * self::BULLET_PADDING; - } - - //hits only on "inset" lists items, to increase height of box - function get_margin_height() { - $style = $this->_frame->get_style(); - - if ( $style->list_style_type === "none" ) { - return 0; - } - - return $style->get_font_size() * self::BULLET_SIZE + 2 * self::BULLET_PADDING; - } - - function get_width() { - return $this->get_margin_height(); - } - - function get_height() { - return $this->get_margin_height(); - } - - //........................................................................ -} diff --git a/application/helpers/dompdf/include/list_bullet_frame_reflower.cls.php b/application/helpers/dompdf/include/list_bullet_frame_reflower.cls.php deleted file mode 100755 index 283056f00..000000000 --- a/application/helpers/dompdf/include/list_bullet_frame_reflower.cls.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Reflows list bullets - * - * @access private - * @package dompdf - */ -class List_Bullet_Frame_Reflower extends Frame_Reflower { - - function __construct(Frame_Decorator $frame) { parent::__construct($frame); } - - //........................................................................ - - function reflow(Block_Frame_Decorator $block = null) { - $style = $this->_frame->get_style(); - - $style->width = $this->_frame->get_width(); - $this->_frame->position(); - - if ( $style->list_style_position === "inside" ) { - $p = $this->_frame->find_block_parent(); - $p->add_frame_to_line($this->_frame); - } - - } -} diff --git a/application/helpers/dompdf/include/list_bullet_image_frame_decorator.cls.php b/application/helpers/dompdf/include/list_bullet_image_frame_decorator.cls.php deleted file mode 100755 index f27ca3d68..000000000 --- a/application/helpers/dompdf/include/list_bullet_image_frame_decorator.cls.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @author Helmut Tischer - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Decorates frames for list bullets with custom images - * - * @access private - * @package dompdf - */ -class List_Bullet_Image_Frame_Decorator extends Frame_Decorator { - - /** - * The underlying image frame - * - * @var Image_Frame_Decorator - */ - protected $_img; - - /** - * The image's width in pixels - * - * @var int - */ - protected $_width; - - /** - * The image's height in pixels - * - * @var int - */ - protected $_height; - - /** - * Class constructor - * - * @param Frame $frame the bullet frame to decorate - * @param DOMPDF $dompdf the document's dompdf object - */ - function __construct(Frame $frame, DOMPDF $dompdf) { - $style = $frame->get_style(); - $url = $style->list_style_image; - $frame->get_node()->setAttribute("src", $url); - $this->_img = new Image_Frame_Decorator($frame, $dompdf); - parent::__construct($this->_img, $dompdf); - list($width, $height) = dompdf_getimagesize($this->_img->get_image_url()); - - // Resample the bullet image to be consistent with 'auto' sized images - // See also Image_Frame_Reflower::get_min_max_width - // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary. - $dpi = $this->_dompdf->get_option("dpi"); - $this->_width = ((float)rtrim($width, "px") * 72) / $dpi; - $this->_height = ((float)rtrim($height, "px") * 72) / $dpi; - - //If an image is taller as the containing block/box, the box should be extended. - //Neighbour elements are overwriting the overlapping image areas. - //Todo: Where can the box size be extended? - //Code below has no effect. - //See block_frame_reflower _calculate_restricted_height - //See generated_frame_reflower, Dompdf:render() "list-item", "-dompdf-list-bullet"S. - //Leave for now - //if ($style->min_height < $this->_height ) { - // $style->min_height = $this->_height; - //} - //$style->height = "auto"; - } - - /** - * Return the bullet's width - * - * @return int - */ - function get_width() { - //ignore image width, use same width as on predefined bullet List_Bullet_Frame_Decorator - //for proper alignment of bullet image and text. Allow image to not fitting on left border. - //This controls the distance between bullet image and text - //return $this->_width; - return $this->_frame->get_style()->get_font_size()*List_Bullet_Frame_Decorator::BULLET_SIZE + - 2 * List_Bullet_Frame_Decorator::BULLET_PADDING; - } - - /** - * Return the bullet's height - * - * @return int - */ - function get_height() { - //based on image height - return $this->_height; - } - - /** - * Override get_margin_width - * - * @return int - */ - function get_margin_width() { - //ignore image width, use same width as on predefined bullet List_Bullet_Frame_Decorator - //for proper alignment of bullet image and text. Allow image to not fitting on left border. - //This controls the extra indentation of text to make room for the bullet image. - //Here use actual image size, not predefined bullet size - //return $this->_frame->get_style()->get_font_size()*List_Bullet_Frame_Decorator::BULLET_SIZE + - // 2 * List_Bullet_Frame_Decorator::BULLET_PADDING; - - // Small hack to prevent indenting of list text - // Image Might not exist, then position like on list_bullet_frame_decorator fallback to none. - if ( $this->_frame->get_style()->list_style_position === "outside" || - $this->_width == 0) - return 0; - //This aligns the "inside" image position with the text. - //The text starts to the right of the image. - //Between the image and the text there is an added margin of image width. - //Where this comes from is unknown. - //The corresponding List_Bullet_Frame_Decorator sets a smaller margin. bullet size? - return $this->_width + 2 * List_Bullet_Frame_Decorator::BULLET_PADDING; - } - - /** - * Override get_margin_height() - * - * @return int - */ - function get_margin_height() { - //Hits only on "inset" lists items, to increase height of box - //based on image height - return $this->_height + 2 * List_Bullet_Frame_Decorator::BULLET_PADDING; - } - - /** - * Return image url - * - * @return string - */ - function get_image_url() { - return $this->_img->get_image_url(); - } - -} diff --git a/application/helpers/dompdf/include/list_bullet_positioner.cls.php b/application/helpers/dompdf/include/list_bullet_positioner.cls.php deleted file mode 100755 index 7e89ae471..000000000 --- a/application/helpers/dompdf/include/list_bullet_positioner.cls.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @author Helmut Tischer - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Positions list bullets - * - * @access private - * @package dompdf - */ -class List_Bullet_Positioner extends Positioner { - - function __construct(Frame_Decorator $frame) { parent::__construct($frame); } - - //........................................................................ - - function position() { - - // Bullets & friends are positioned an absolute distance to the left of - // the content edge of their parent element - $cb = $this->_frame->get_containing_block(); - - // Note: this differs from most frames in that we must position - // ourselves after determining our width - $x = $cb["x"] - $this->_frame->get_width(); - - $p = $this->_frame->find_block_parent(); - - $y = $p->get_current_line_box()->y; - - // This is a bit of a hack... - $n = $this->_frame->get_next_sibling(); - if ( $n ) { - $style = $n->get_style(); - $line_height = $style->length_in_pt($style->line_height, $style->get_font_size()); - $offset = $style->length_in_pt($line_height, $n->get_containing_block("h")) - $this->_frame->get_height(); - $y += $offset / 2; - } - - // Now the position is the left top of the block which should be marked with the bullet. - // We tried to find out the y of the start of the first text character within the block. - // But the top margin/padding does not fit, neither from this nor from the next sibling - // The "bit of a hack" above does not work also. - - // Instead let's position the bullet vertically centered to the block which should be marked. - // But for get_next_sibling() the get_containing_block is all zero, and for find_block_parent() - // the get_containing_block is paper width and the entire list as height. - - // if ($p) { - // //$cb = $n->get_containing_block(); - // $cb = $p->get_containing_block(); - // $y += $cb["h"]/2; - // print 'cb:'.$cb["x"].':'.$cb["y"].':'.$cb["w"].':'.$cb["h"].':'; - // } - - // Todo: - // For now give up on the above. Use Guesswork with font y-pos in the middle of the line spacing - - /*$style = $p->get_style(); - $font_size = $style->get_font_size(); - $line_height = $style->length_in_pt($style->line_height, $font_size); - $y += ($line_height - $font_size) / 2; */ - - //Position is x-end y-top of character position of the bullet. - $this->_frame->set_position($x, $y); - - } -} diff --git a/application/helpers/dompdf/include/list_bullet_renderer.cls.php b/application/helpers/dompdf/include/list_bullet_renderer.cls.php deleted file mode 100755 index 6b984764f..000000000 --- a/application/helpers/dompdf/include/list_bullet_renderer.cls.php +++ /dev/null @@ -1,236 +0,0 @@ - - * @author Helmut Tischer - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Renders list bullets - * - * @access private - * @package dompdf - */ -class List_Bullet_Renderer extends Abstract_Renderer { - static function get_counter_chars($type) { - static $cache = array(); - - if ( isset($cache[$type]) ) { - return $cache[$type]; - } - - $uppercase = false; - $text = ""; - - switch ($type) { - case "decimal-leading-zero": - case "decimal": - case "1": - return "0123456789"; - - case "upper-alpha": - case "upper-latin": - case "A": - $uppercase = true; - case "lower-alpha": - case "lower-latin": - case "a": - $text = "abcdefghijklmnopqrstuvwxyz"; - break; - - case "upper-roman": - case "I": - $uppercase = true; - case "lower-roman": - case "i": - $text = "ivxlcdm"; - break; - - case "lower-greek": - for($i = 0; $i < 24; $i++) { - $text .= unichr($i+944); - } - break; - } - - if ( $uppercase ) { - $text = strtoupper($text); - } - - return $cache[$type] = "$text."; - } - - /** - * @param integer $n - * @param string $type - * @param integer $pad - * - * @return string - */ - private function make_counter($n, $type, $pad = null){ - $n = intval($n); - $text = ""; - $uppercase = false; - - switch ($type) { - case "decimal-leading-zero": - case "decimal": - case "1": - if ($pad) - $text = str_pad($n, $pad, "0", STR_PAD_LEFT); - else - $text = $n; - break; - - case "upper-alpha": - case "upper-latin": - case "A": - $uppercase = true; - case "lower-alpha": - case "lower-latin": - case "a": - $text = chr( ($n % 26) + ord('a') - 1); - break; - - case "upper-roman": - case "I": - $uppercase = true; - case "lower-roman": - case "i": - $text = dec2roman($n); - break; - - case "lower-greek": - $text = unichr($n + 944); - break; - } - - if ( $uppercase ) { - $text = strtoupper($text); - } - - return "$text."; - } - - function render(Frame $frame) { - $style = $frame->get_style(); - $font_size = $style->get_font_size(); - $line_height = $style->length_in_pt($style->line_height, $frame->get_containing_block("w")); - - $this->_set_opacity( $frame->get_opacity( $style->opacity ) ); - - $li = $frame->get_parent(); - - // Don't render bullets twice if if was split - if ($li->_splitted) { - return; - } - - // Handle list-style-image - // If list style image is requested but missing, fall back to predefined types - if ( $style->list_style_image !== "none" && - !Image_Cache::is_broken($img = $frame->get_image_url())) { - - list($x,$y) = $frame->get_position(); - - //For expected size and aspect, instead of box size, use image natural size scaled to DPI. - // Resample the bullet image to be consistent with 'auto' sized images - // See also Image_Frame_Reflower::get_min_max_width - // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary. - //$w = $frame->get_width(); - //$h = $frame->get_height(); - list($width, $height) = dompdf_getimagesize($img); - $dpi = $this->_dompdf->get_option("dpi"); - $w = ((float)rtrim($width, "px") * 72) / $dpi; - $h = ((float)rtrim($height, "px") * 72) / $dpi; - - $x -= $w; - $y -= ($line_height - $font_size)/2; //Reverse hinting of list_bullet_positioner - - $this->_canvas->image( $img, $x, $y, $w, $h); - - } else { - - $bullet_style = $style->list_style_type; - - $fill = false; - - switch ($bullet_style) { - - default: - case "disc": - $fill = true; - - case "circle": - list($x,$y) = $frame->get_position(); - $r = ($font_size*(List_Bullet_Frame_Decorator::BULLET_SIZE /*-List_Bullet_Frame_Decorator::BULLET_THICKNESS*/ ))/2; - $x -= $font_size*(List_Bullet_Frame_Decorator::BULLET_SIZE/2); - $y += ($font_size*(1-List_Bullet_Frame_Decorator::BULLET_DESCENT))/2; - $o = $font_size*List_Bullet_Frame_Decorator::BULLET_THICKNESS; - $this->_canvas->circle($x, $y, $r, $style->color, $o, null, $fill); - break; - - case "square": - list($x, $y) = $frame->get_position(); - $w = $font_size*List_Bullet_Frame_Decorator::BULLET_SIZE; - $x -= $w; - $y += ($font_size*(1-List_Bullet_Frame_Decorator::BULLET_DESCENT-List_Bullet_Frame_Decorator::BULLET_SIZE))/2; - $this->_canvas->filled_rectangle($x, $y, $w, $w, $style->color); - break; - - case "decimal-leading-zero": - case "decimal": - case "lower-alpha": - case "lower-latin": - case "lower-roman": - case "lower-greek": - case "upper-alpha": - case "upper-latin": - case "upper-roman": - case "1": // HTML 4.0 compatibility - case "a": - case "i": - case "A": - case "I": - $pad = null; - if ( $bullet_style === "decimal-leading-zero" ) { - $pad = strlen($li->get_parent()->get_node()->getAttribute("dompdf-children-count")); - } - - $node = $frame->get_node(); - - if ( !$node->hasAttribute("dompdf-counter") ) { - return; - } - - $index = $node->getAttribute("dompdf-counter"); - $text = $this->make_counter($index, $bullet_style, $pad); - - if ( trim($text) == "" ) { - return; - } - - $spacing = 0; - $font_family = $style->font_family; - - $line = $li->get_containing_line(); - list($x, $y) = array($frame->get_position("x"), $line->y); - - $x -= Font_Metrics::get_text_width($text, $font_family, $font_size, $spacing); - - // Take line-height into account - $line_height = $style->line_height; - $y += ($line_height - $font_size) / 4; // FIXME I thought it should be 2, but 4 gives better results - - $this->_canvas->text($x, $y, $text, - $font_family, $font_size, - $style->color, $spacing); - - case "none": - break; - } - } - } -} diff --git a/application/helpers/dompdf/include/null_frame_decorator.cls.php b/application/helpers/dompdf/include/null_frame_decorator.cls.php deleted file mode 100755 index 15f806d0d..000000000 --- a/application/helpers/dompdf/include/null_frame_decorator.cls.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Dummy decorator - * - * @access private - * @package dompdf - */ -class Null_Frame_Decorator extends Frame_Decorator { - - function __construct(Frame $frame, DOMPDF $dompdf) { - parent::__construct($frame, $dompdf); - $style = $this->_frame->get_style(); - $style->width = 0; - $style->height = 0; - $style->margin = 0; - $style->padding = 0; - } - -} diff --git a/application/helpers/dompdf/include/null_frame_reflower.cls.php b/application/helpers/dompdf/include/null_frame_reflower.cls.php deleted file mode 100755 index 389f1479d..000000000 --- a/application/helpers/dompdf/include/null_frame_reflower.cls.php +++ /dev/null @@ -1,21 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Dummy reflower - * - * @access private - * @package dompdf - */ -class Null_Frame_Reflower extends Frame_Reflower { - - function __construct(Frame $frame) { parent::__construct($frame); } - - function reflow(Block_Frame_Decorator $block = null) { return; } - -} diff --git a/application/helpers/dompdf/include/null_positioner.cls.php b/application/helpers/dompdf/include/null_positioner.cls.php deleted file mode 100755 index 97d4986dc..000000000 --- a/application/helpers/dompdf/include/null_positioner.cls.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Dummy positioner - * - * @access private - * @package dompdf - */ -class Null_Positioner extends Positioner { - - function __construct(Frame_Decorator $frame) { - parent::__construct($frame); - } - - function position() { return; } - -} diff --git a/application/helpers/dompdf/include/page_cache.cls.php b/application/helpers/dompdf/include/page_cache.cls.php deleted file mode 100755 index 652da160a..000000000 --- a/application/helpers/dompdf/include/page_cache.cls.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Caches individual rendered PDF pages - * - * Not totally implemented yet. Use at your own risk ;) - * - * @access private - * @package dompdf - * @static - */ -class Page_Cache { - - const DB_USER = "dompdf_page_cache"; - const DB_PASS = "some meaningful password"; - const DB_NAME = "dompdf_page_cache"; - - static private $__connection = null; - - static function init() { - if ( is_null(self::$__connection) ) { - $con_str = "host=" . DB_HOST . - " dbname=" . self::DB_NAME . - " user=" . self::DB_USER . - " password=" . self::DB_PASS; - - if ( !self::$__connection = pg_connect($con_str) ) - throw new Exception("Database connection failed."); - } - } - - function __construct() { throw new Exception("Can not create instance of Page_Class. Class is static."); } - - private static function __query($sql) { - if ( !($res = pg_query(self::$__connection, $sql)) ) - throw new Exception(pg_last_error(self::$__connection)); - return $res; - } - - static function store_page($id, $page_num, $data) { - $where = "WHERE id='" . pg_escape_string($id) . "' AND ". - "page_num=". pg_escape_string($page_num); - - $res = self::__query("SELECT timestamp FROM page_cache ". $where); - - $row = pg_fetch_assoc($res); - - if ( $row ) - self::__query("UPDATE page_cache SET data='" . pg_escape_string($data) . "' " . $where); - else - self::__query("INSERT INTO page_cache (id, page_num, data) VALUES ('" . pg_escape_string($id) . "', ". - pg_escape_string($page_num) . ", ". - "'". pg_escape_string($data) . "')"); - - } - - static function store_fonts($id, $fonts) { - self::__query("BEGIN"); - // Update the font information - self::__query("DELETE FROM page_fonts WHERE id='" . pg_escape_string($id) . "'"); - - foreach (array_keys($fonts) as $font) - self::__query("INSERT INTO page_fonts (id, font_name) VALUES ('" . - pg_escape_string($id) . "', '" . pg_escape_string($font) . "')"); - self::__query("COMMIT"); - } - -// static function retrieve_page($id, $page_num) { - -// $res = self::__query("SELECT data FROM page_cache WHERE id='" . pg_escape_string($id) . "' AND ". -// "page_num=". pg_escape_string($page_num)); - -// $row = pg_fetch_assoc($res); - -// return pg_unescape_bytea($row["data"]); - -// } - - static function get_page_timestamp($id, $page_num) { - $res = self::__query("SELECT timestamp FROM page_cache WHERE id='" . pg_escape_string($id) . "' AND ". - "page_num=". pg_escape_string($page_num)); - - $row = pg_fetch_assoc($res); - - return $row["timestamp"]; - - } - - // Adds the cached document referenced by $id to the provided pdf - static function insert_cached_document(CPDF_Adapter $pdf, $id, $new_page = true) { - $res = self::__query("SELECT font_name FROM page_fonts WHERE id='" . pg_escape_string($id) . "'"); - - // Ensure that the fonts needed by the cached document are loaded into - // the pdf - while ($row = pg_fetch_assoc($res)) - $pdf->get_cpdf()->selectFont($row["font_name"]); - - $res = self::__query("SELECT data FROM page_cache WHERE id='" . pg_escape_string($id) . "'"); - - if ( $new_page ) - $pdf->new_page(); - - $first = true; - while ($row = pg_fetch_assoc($res)) { - - if ( !$first ) - $pdf->new_page(); - else - $first = false; - - $page = $pdf->reopen_serialized_object($row["data"]); - //$pdf->close_object(); - $pdf->add_object($page, "add"); - - } - - } -} - -Page_Cache::init(); diff --git a/application/helpers/dompdf/include/page_frame_decorator.cls.php b/application/helpers/dompdf/include/page_frame_decorator.cls.php deleted file mode 100755 index f089d0075..000000000 --- a/application/helpers/dompdf/include/page_frame_decorator.cls.php +++ /dev/null @@ -1,592 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Decorates frames for page layout - * - * @access private - * @package dompdf - */ -class Page_Frame_Decorator extends Frame_Decorator { - - /** - * y value of bottom page margin - * - * @var float - */ - protected $_bottom_page_margin; - - /** - * Flag indicating page is full. - * - * @var bool - */ - protected $_page_full; - - /** - * Number of tables currently being reflowed - * - * @var int - */ - protected $_in_table; - - /** - * The pdf renderer - * - * @var Renderer - */ - protected $_renderer; - - /** - * This page's floating frames - * - * @var array - */ - protected $_floating_frames = array(); - - //........................................................................ - - /** - * Class constructor - * - * @param Frame $frame the frame to decorate - * @param DOMPDF $dompdf - */ - function __construct(Frame $frame, DOMPDF $dompdf) { - parent::__construct($frame, $dompdf); - $this->_page_full = false; - $this->_in_table = 0; - $this->_bottom_page_margin = null; - } - - /** - * Set the renderer used for this pdf - * - * @param Renderer $renderer the renderer to use - */ - function set_renderer($renderer) { - $this->_renderer = $renderer; - } - - /** - * Return the renderer used for this pdf - * - * @return Renderer - */ - function get_renderer() { - return $this->_renderer; - } - - /** - * Set the frame's containing block. Overridden to set $this->_bottom_page_margin. - * - * @param float $x - * @param float $y - * @param float $w - * @param float $h - */ - function set_containing_block($x = null, $y = null, $w = null, $h = null) { - parent::set_containing_block($x,$y,$w,$h); - //$w = $this->get_containing_block("w"); - if ( isset($h) ) - $this->_bottom_page_margin = $h; // - $this->_frame->get_style()->length_in_pt($this->_frame->get_style()->margin_bottom, $w); - } - - /** - * Returns true if the page is full and is no longer accepting frames. - * - * @return bool - */ - function is_full() { - return $this->_page_full; - } - - /** - * Start a new page by resetting the full flag. - */ - function next_page() { - $this->_floating_frames = array(); - $this->_renderer->new_page(); - $this->_page_full = false; - } - - /** - * Indicate to the page that a table is currently being reflowed. - */ - function table_reflow_start() { - $this->_in_table++; - } - - /** - * Indicate to the page that table reflow is finished. - */ - function table_reflow_end() { - $this->_in_table--; - } - - /** - * Return whether we are currently in a nested table or not - * - * @return bool - */ - function in_nested_table() { - return $this->_in_table > 1; - } - - /** - * Check if a forced page break is required before $frame. This uses the - * frame's page_break_before property as well as the preceeding frame's - * page_break_after property. - * - * @link http://www.w3.org/TR/CSS21/page.html#forced - * - * @param Frame $frame the frame to check - * @return bool true if a page break occured - */ - function check_forced_page_break(Frame $frame) { - - // Skip check if page is already split - if ( $this->_page_full ) - return null; - - $block_types = array("block", "list-item", "table", "inline"); - $page_breaks = array("always", "left", "right"); - - $style = $frame->get_style(); - - if ( !in_array($style->display, $block_types) ) - return false; - - // Find the previous block-level sibling - $prev = $frame->get_prev_sibling(); - - while ( $prev && !in_array($prev->get_style()->display, $block_types) ) - $prev = $prev->get_prev_sibling(); - - - if ( in_array($style->page_break_before, $page_breaks) ) { - - // Prevent cascading splits - $frame->split(null, true); - // We have to grab the style again here because split() resets - // $frame->style to the frame's orignal style. - $frame->get_style()->page_break_before = "auto"; - $this->_page_full = true; - - return true; - } - - if ( $prev && in_array($prev->get_style()->page_break_after, $page_breaks) ) { - // Prevent cascading splits - $frame->split(null, true); - $prev->get_style()->page_break_after = "auto"; - $this->_page_full = true; - return true; - } - - if( $prev && $prev->get_last_child() && $frame->get_node()->nodeName != "body" ) { - $prev_last_child = $prev->get_last_child(); - if ( in_array($prev_last_child->get_style()->page_break_after, $page_breaks) ) { - $frame->split(null, true); - $prev_last_child->get_style()->page_break_after = "auto"; - $this->_page_full = true; - return true; - } - } - - - return false; - } - - /** - * Determine if a page break is allowed before $frame - * http://www.w3.org/TR/CSS21/page.html#allowed-page-breaks - * - * In the normal flow, page breaks can occur at the following places: - * - * 1. In the vertical margin between block boxes. When a page - * break occurs here, the used values of the relevant - * 'margin-top' and 'margin-bottom' properties are set to '0'. - * 2. Between line boxes inside a block box. - * - * These breaks are subject to the following rules: - * - * * Rule A: Breaking at (1) is allowed only if the - * 'page-break-after' and 'page-break-before' properties of - * all the elements generating boxes that meet at this margin - * allow it, which is when at least one of them has the value - * 'always', 'left', or 'right', or when all of them are - * 'auto'. - * - * * Rule B: However, if all of them are 'auto' and the - * nearest common ancestor of all the elements has a - * 'page-break-inside' value of 'avoid', then breaking here is - * not allowed. - * - * * Rule C: Breaking at (2) is allowed only if the number of - * line boxes between the break and the start of the enclosing - * block box is the value of 'orphans' or more, and the number - * of line boxes between the break and the end of the box is - * the value of 'widows' or more. - * - * * Rule D: In addition, breaking at (2) is allowed only if - * the 'page-break-inside' property is 'auto'. - * - * If the above doesn't provide enough break points to keep - * content from overflowing the page boxes, then rules B and D are - * dropped in order to find additional breakpoints. - * - * If that still does not lead to sufficient break points, rules A - * and C are dropped as well, to find still more break points. - * - * We will also allow breaks between table rows. However, when - * splitting a table, the table headers should carry over to the - * next page (but they don't yet). - * - * @param Frame $frame the frame to check - * @return bool true if a break is allowed, false otherwise - */ - protected function _page_break_allowed(Frame $frame) { - - $block_types = array("block", "list-item", "table", "-dompdf-image"); - dompdf_debug("page-break", "_page_break_allowed(" . $frame->get_node()->nodeName. ")"); - $display = $frame->get_style()->display; - - // Block Frames (1): - if ( in_array($display, $block_types) ) { - - // Avoid breaks within table-cells - if ( $this->_in_table ) { - dompdf_debug("page-break", "In table: " . $this->_in_table); - return false; - } - - // Rules A & B - - if ( $frame->get_style()->page_break_before === "avoid" ) { - dompdf_debug("page-break", "before: avoid"); - return false; - } - - // Find the preceeding block-level sibling - $prev = $frame->get_prev_sibling(); - while ( $prev && !in_array($prev->get_style()->display, $block_types) ) - $prev = $prev->get_prev_sibling(); - - // Does the previous element allow a page break after? - if ( $prev && $prev->get_style()->page_break_after === "avoid" ) { - dompdf_debug("page-break", "after: avoid"); - return false; - } - - // If both $prev & $frame have the same parent, check the parent's - // page_break_inside property. - $parent = $frame->get_parent(); - if ( $prev && $parent && $parent->get_style()->page_break_inside === "avoid" ) { - dompdf_debug("page-break", "parent inside: avoid"); - return false; - } - - // To prevent cascading page breaks when a top-level element has - // page-break-inside: avoid, ensure that at least one frame is - // on the page before splitting. - if ( $parent->get_node()->nodeName === "body" && !$prev ) { - // We are the body's first child - dompdf_debug("page-break", "Body's first child."); - return false; - } - - // If the frame is the first block-level frame, use the value from - // $frame's parent instead. - if ( !$prev && $parent ) - return $this->_page_break_allowed( $parent ); - - dompdf_debug("page-break", "block: break allowed"); - return true; - - } - - // Inline frames (2): - else if ( in_array($display, Style::$INLINE_TYPES) ) { - - // Avoid breaks within table-cells - if ( $this->_in_table ) { - dompdf_debug("page-break", "In table: " . $this->_in_table); - return false; - } - - // Rule C - $block_parent = $frame->find_block_parent(); - if ( count($block_parent->get_line_boxes() ) < $frame->get_style()->orphans ) { - dompdf_debug("page-break", "orphans"); - return false; - } - - // FIXME: Checking widows is tricky without having laid out the - // remaining line boxes. Just ignore it for now... - - // Rule D - $p = $block_parent; - while ($p) { - if ( $p->get_style()->page_break_inside === "avoid" ) { - dompdf_debug("page-break", "parent->inside: avoid"); - return false; - } - $p = $p->find_block_parent(); - } - - // To prevent cascading page breaks when a top-level element has - // page-break-inside: avoid, ensure that at least one frame with - // some content is on the page before splitting. - $prev = $frame->get_prev_sibling(); - while ( $prev && ($prev->is_text_node() && trim($prev->get_node()->nodeValue) == "") ) - $prev = $prev->get_prev_sibling(); - - if ( $block_parent->get_node()->nodeName === "body" && !$prev ) { - // We are the body's first child - dompdf_debug("page-break", "Body's first child."); - return false; - } - - // Skip breaks on empty text nodes - if ( $frame->is_text_node() && - $frame->get_node()->nodeValue == "" ) - return false; - - dompdf_debug("page-break", "inline: break allowed"); - return true; - - // Table-rows - } else if ( $display === "table-row" ) { - - // Simply check if the parent table's page_break_inside property is - // not 'avoid' - $p = Table_Frame_Decorator::find_parent_table($frame); - - while ($p) { - if ( $p->get_style()->page_break_inside === "avoid" ) { - dompdf_debug("page-break", "parent->inside: avoid"); - return false; - } - $p = $p->find_block_parent(); - } - - // Avoid breaking after the first row of a table - if ( $p && $p->get_first_child() === $frame) { - dompdf_debug("page-break", "table: first-row"); - return false; - } - - // If this is a nested table, prevent the page from breaking - if ( $this->_in_table > 1 ) { - dompdf_debug("page-break", "table: nested table"); - return false; - } - - dompdf_debug("page-break","table-row/row-groups: break allowed"); - return true; - - } else if ( in_array($display, Table_Frame_Decorator::$ROW_GROUPS) ) { - - // Disallow breaks at row-groups: only split at row boundaries - return false; - - } else { - - dompdf_debug("page-break", "? " . $frame->get_style()->display . ""); - return false; - } - - } - - /** - * Check if $frame will fit on the page. If the frame does not fit, - * the frame tree is modified so that a page break occurs in the - * correct location. - * - * @param Frame $frame the frame to check - * @return Frame the frame following the page break - */ - function check_page_break(Frame $frame) { - // Do not split if we have already or if the frame was already - // pushed to the next page (prevents infinite loops) - if ( $this->_page_full || $frame->_already_pushed ) { - return false; - } - - // If the frame is absolute of fixed it shouldn't break - $p = $frame; - do { - if ( $p->is_absolute() ) - return false; - } while ( $p = $p->get_parent() ); - - $margin_height = $frame->get_margin_height(); - - // FIXME If the row is taller than the page and - // if it the first of the page, we don't break - if ( $frame->get_style()->display === "table-row" && - !$frame->get_prev_sibling() && - $margin_height > $this->get_margin_height() ) - return false; - - // Determine the frame's maximum y value - $max_y = $frame->get_position("y") + $margin_height; - - // If a split is to occur here, then the bottom margins & paddings of all - // parents of $frame must fit on the page as well: - $p = $frame->get_parent(); - while ( $p ) { - $style = $p->get_style(); - $max_y += $style->length_in_pt(array($style->margin_bottom, - $style->padding_bottom, - $style->border_bottom_width)); - $p = $p->get_parent(); - } - - - // Check if $frame flows off the page - if ( $max_y <= $this->_bottom_page_margin ) - // no: do nothing - return false; - - dompdf_debug("page-break", "check_page_break"); - dompdf_debug("page-break", "in_table: " . $this->_in_table); - - // yes: determine page break location - $iter = $frame; - $flg = false; - - $in_table = $this->_in_table; - - dompdf_debug("page-break","Starting search"); - while ( $iter ) { - // echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). ""; - if ( $iter === $this ) { - dompdf_debug("page-break", "reached root."); - // We've reached the root in our search. Just split at $frame. - break; - } - - if ( $this->_page_break_allowed($iter) ) { - dompdf_debug("page-break","break allowed, splitting."); - $iter->split(null, true); - $this->_page_full = true; - $this->_in_table = $in_table; - $frame->_already_pushed = true; - return true; - } - - if ( !$flg && $next = $iter->get_last_child() ) { - dompdf_debug("page-break", "following last child."); - - if ( $next->is_table() ) - $this->_in_table++; - - $iter = $next; - continue; - } - - if ( $next = $iter->get_prev_sibling() ) { - dompdf_debug("page-break", "following prev sibling."); - - if ( $next->is_table() && !$iter->is_table() ) - $this->_in_table++; - - else if ( !$next->is_table() && $iter->is_table() ) - $this->_in_table--; - - $iter = $next; - $flg = false; - continue; - } - - if ( $next = $iter->get_parent() ) { - dompdf_debug("page-break", "following parent."); - - if ( $iter->is_table() ) - $this->_in_table--; - - $iter = $next; - $flg = true; - continue; - } - - break; - } - - $this->_in_table = $in_table; - - // No valid page break found. Just break at $frame. - dompdf_debug("page-break", "no valid break found, just splitting."); - - // If we are in a table, backtrack to the nearest top-level table row - if ( $this->_in_table ) { - $iter = $frame; - while ($iter && $iter->get_style()->display !== "table-row") - $iter = $iter->get_parent(); - - $iter->split(null, true); - } else { - $frame->split(null, true); - } - - $this->_page_full = true; - $frame->_already_pushed = true; - return true; - } - - //........................................................................ - - function split(Frame $frame = null, $force_pagebreak = false) { - // Do nothing - } - - /** - * Add a floating frame - * - * @param Frame $frame - * - * @return void - */ - function add_floating_frame(Frame $frame) { - array_unshift($this->_floating_frames, $frame); - } - - /** - * @return Frame[] - */ - function get_floating_frames() { - return $this->_floating_frames; - } - - public function remove_floating_frame($key) { - unset($this->_floating_frames[$key]); - } - - public function get_lowest_float_offset(Frame $child) { - $style = $child->get_style(); - $side = $style->clear; - $float = $style->float; - - $y = 0; - - foreach($this->_floating_frames as $key => $frame) { - if ( $side === "both" || $frame->get_style()->float === $side ) { - $y = max($y, $frame->get_position("y") + $frame->get_margin_height()); - - if ( $float !== "none" ) { - $this->remove_floating_frame($key); - } - } - } - - return $y; - } - -} diff --git a/application/helpers/dompdf/include/page_frame_reflower.cls.php b/application/helpers/dompdf/include/page_frame_reflower.cls.php deleted file mode 100755 index 4223f4e85..000000000 --- a/application/helpers/dompdf/include/page_frame_reflower.cls.php +++ /dev/null @@ -1,186 +0,0 @@ - - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Reflows pages - * - * @access private - * @package dompdf - */ -class Page_Frame_Reflower extends Frame_Reflower { - - /** - * Cache of the callbacks array - * - * @var array - */ - private $_callbacks; - - /** - * Cache of the canvas - * - * @var Canvas - */ - private $_canvas; - - function __construct(Page_Frame_Decorator $frame) { parent::__construct($frame); } - - function apply_page_style(Frame $frame, $page_number){ - $style = $frame->get_style(); - $page_styles = $style->get_stylesheet()->get_page_styles(); - - // http://www.w3.org/TR/CSS21/page.html#page-selectors - if ( count($page_styles) > 1 ) { - $odd = $page_number % 2 == 1; - $first = $page_number == 1; - - $style = clone $page_styles["base"]; - - // FIXME RTL - if ( $odd && isset($page_styles[":right"]) ) { - $style->merge($page_styles[":right"]); - } - - if ( $odd && isset($page_styles[":odd"]) ) { - $style->merge($page_styles[":odd"]); - } - - // FIXME RTL - if ( !$odd && isset($page_styles[":left"]) ) { - $style->merge($page_styles[":left"]); - } - - if ( !$odd && isset($page_styles[":even"]) ) { - $style->merge($page_styles[":even"]); - } - - if ( $first && isset($page_styles[":first"]) ) { - $style->merge($page_styles[":first"]); - } - - $frame->set_style($style); - } - } - - //........................................................................ - - /** - * Paged layout: - * http://www.w3.org/TR/CSS21/page.html - */ - function reflow(Block_Frame_Decorator $block = null) { - $fixed_children = array(); - $prev_child = null; - $child = $this->_frame->get_first_child(); - $current_page = 0; - - while ($child) { - $this->apply_page_style($this->_frame, $current_page + 1); - - $style = $this->_frame->get_style(); - - // Pages are only concerned with margins - $cb = $this->_frame->get_containing_block(); - $left = $style->length_in_pt($style->margin_left, $cb["w"]); - $right = $style->length_in_pt($style->margin_right, $cb["w"]); - $top = $style->length_in_pt($style->margin_top, $cb["h"]); - $bottom = $style->length_in_pt($style->margin_bottom, $cb["h"]); - - $content_x = $cb["x"] + $left; - $content_y = $cb["y"] + $top; - $content_width = $cb["w"] - $left - $right; - $content_height = $cb["h"] - $top - $bottom; - - // Only if it's the first page, we save the nodes with a fixed position - if ($current_page == 0) { - $children = $child->get_children(); - foreach ($children as $onechild) { - if ($onechild->get_style()->position === "fixed") { - $fixed_children[] = $onechild->deep_copy(); - } - } - $fixed_children = array_reverse($fixed_children); - } - - $child->set_containing_block($content_x, $content_y, $content_width, $content_height); - - // Check for begin reflow callback - $this->_check_callbacks("begin_page_reflow", $child); - - //Insert a copy of each node which have a fixed position - if ($current_page >= 1) { - foreach ($fixed_children as $fixed_child) { - $child->insert_child_before($fixed_child->deep_copy(), $child->get_first_child()); - } - } - - $child->reflow(); - $next_child = $child->get_next_sibling(); - - // Check for begin render callback - $this->_check_callbacks("begin_page_render", $child); - - // Render the page - $this->_frame->get_renderer()->render($child); - - // Check for end render callback - $this->_check_callbacks("end_page_render", $child); - - if ( $next_child ) { - $this->_frame->next_page(); - } - - // Wait to dispose of all frames on the previous page - // so callback will have access to them - if ( $prev_child ) { - $prev_child->dispose(true); - } - $prev_child = $child; - $child = $next_child; - $current_page++; - } - - // Dispose of previous page if it still exists - if ( $prev_child ) { - $prev_child->dispose(true); - } - } - - //........................................................................ - - /** - * Check for callbacks that need to be performed when a given event - * gets triggered on a page - * - * @param string $event the type of event - * @param Frame $frame the frame that event is triggered on - */ - protected function _check_callbacks($event, $frame) { - if (!isset($this->_callbacks)) { - $dompdf = $this->_frame->get_dompdf(); - $this->_callbacks = $dompdf->get_callbacks(); - $this->_canvas = $dompdf->get_canvas(); - } - - if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) { - $info = array(0 => $this->_canvas, "canvas" => $this->_canvas, - 1 => $frame, "frame" => $frame); - $fs = $this->_callbacks[$event]; - foreach ($fs as $f) { - if (is_callable($f)) { - if (is_array($f)) { - $f[0]->$f[1]($info); - } else { - $f($info); - } - } - } - } - } -} diff --git a/application/helpers/dompdf/include/pdflib_adapter.cls.php b/application/helpers/dompdf/include/pdflib_adapter.cls.php deleted file mode 100755 index 4bfe1913e..000000000 --- a/application/helpers/dompdf/include/pdflib_adapter.cls.php +++ /dev/null @@ -1,1085 +0,0 @@ - - * @author Helmut Tischer - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * PDF rendering interface - * - * PDFLib_Adapter provides a simple, stateless interface to the one - * provided by PDFLib. - * - * Unless otherwise mentioned, all dimensions are in points (1/72 in). - * The coordinate origin is in the top left corner and y values - * increase downwards. - * - * See {@link http://www.pdflib.com/} for more complete documentation - * on the underlying PDFlib functions. - * - * @package dompdf - */ -class PDFLib_Adapter implements Canvas { - - /** - * Dimensions of paper sizes in points - * - * @var array; - */ - static public $PAPER_SIZES = array(); // Set to CPDF_Adapter::$PAPER_SIZES below. - - /** - * Whether to create PDFs in memory or on disk - * - * @var bool - */ - static $IN_MEMORY = true; - - /** - * @var DOMPDF - */ - private $_dompdf; - - /** - * Instance of PDFLib class - * - * @var PDFlib - */ - private $_pdf; - - /** - * Name of temporary file used for PDFs created on disk - * - * @var string - */ - private $_file; - - /** - * PDF width, in points - * - * @var float - */ - private $_width; - - /** - * PDF height, in points - * - * @var float - */ - private $_height; - - /** - * Last fill color used - * - * @var array - */ - private $_last_fill_color; - - /** - * Last stroke color used - * - * @var array - */ - private $_last_stroke_color; - - /** - * Cache of image handles - * - * @var array - */ - private $_imgs; - - /** - * Cache of font handles - * - * @var array - */ - private $_fonts; - - /** - * List of objects (templates) to add to multiple pages - * - * @var array - */ - private $_objs; - - /** - * Current page number - * - * @var int - */ - private $_page_number; - - /** - * Total number of pages - * - * @var int - */ - private $_page_count; - - /** - * Text to display on every page - * - * @var array - */ - private $_page_text; - - /** - * Array of pages for accesing after rendering is initially complete - * - * @var array - */ - private $_pages; - - /** - * Class constructor - * - * @param mixed $paper The size of paper to use either a string (see {@link CPDF_Adapter::$PAPER_SIZES}) or - * an array(xmin,ymin,xmax,ymax) - * @param string $orientation The orientation of the document (either 'landscape' or 'portrait') - * @param DOMPDF $dompdf - */ - function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf) { - if ( is_array($paper) ) { - $size = $paper; - } - else if ( isset(self::$PAPER_SIZES[mb_strtolower($paper)]) ) { - $size = self::$PAPER_SIZES[mb_strtolower($paper)]; - } - else { - $size = self::$PAPER_SIZES["letter"]; - } - - if ( mb_strtolower($orientation) === "landscape" ) { - list($size[2], $size[3]) = array($size[3], $size[2]); - } - - $this->_width = $size[2] - $size[0]; - $this->_height= $size[3] - $size[1]; - - $this->_dompdf = $dompdf; - - $this->_pdf = new PDFLib(); - - if ( defined("DOMPDF_PDFLIB_LICENSE") ) - $this->_pdf->set_parameter( "license", DOMPDF_PDFLIB_LICENSE); - - $this->_pdf->set_parameter("textformat", "utf8"); - $this->_pdf->set_parameter("fontwarning", "false"); - - $this->_pdf->set_info("Creator", "DOMPDF"); - - // Silence pedantic warnings about missing TZ settings - $tz = @date_default_timezone_get(); - date_default_timezone_set("UTC"); - $this->_pdf->set_info("Date", date("Y-m-d")); - date_default_timezone_set($tz); - - if ( self::$IN_MEMORY ) - $this->_pdf->begin_document("",""); - else { - $tmp_dir = $this->_dompdf->get_options("temp_dir"); - $tmp_name = tempnam($tmp_dir, "libdompdf_pdf_"); - @unlink($tmp_name); - $this->_file = "$tmp_name.pdf"; - $this->_pdf->begin_document($this->_file,""); - } - - $this->_pdf->begin_page_ext($this->_width, $this->_height, ""); - - $this->_page_number = $this->_page_count = 1; - $this->_page_text = array(); - - $this->_imgs = array(); - $this->_fonts = array(); - $this->_objs = array(); - - // Set up font paths - $families = Font_Metrics::get_font_families(); - foreach ($families as $files) { - foreach ($files as $file) { - $face = basename($file); - $afm = null; - - // Prefer ttfs to afms - if ( file_exists("$file.ttf") ) { - $outline = "$file.ttf"; - - } else if ( file_exists("$file.TTF") ) { - $outline = "$file.TTF"; - - } else if ( file_exists("$file.pfb") ) { - $outline = "$file.pfb"; - - if ( file_exists("$file.afm") ) { - $afm = "$file.afm"; - } - - } else if ( file_exists("$file.PFB") ) { - $outline = "$file.PFB"; - if ( file_exists("$file.AFM") ) { - $afm = "$file.AFM"; - } - } else { - continue; - } - - $this->_pdf->set_parameter("FontOutline", "\{$face\}=\{$outline\}"); - - if ( !is_null($afm) ) { - $this->_pdf->set_parameter("FontAFM", "\{$face\}=\{$afm\}"); - } - } - } - } - - function get_dompdf(){ - return $this->_dompdf; - } - - /** - * Close the pdf - */ - protected function _close() { - $this->_place_objects(); - - // Close all pages - $this->_pdf->suspend_page(""); - for ($p = 1; $p <= $this->_page_count; $p++) { - $this->_pdf->resume_page("pagenumber=$p"); - $this->_pdf->end_page_ext(""); - } - - $this->_pdf->end_document(""); - } - - - /** - * Returns the PDFLib instance - * - * @return PDFLib - */ - function get_pdflib() { - return $this->_pdf; - } - - /** - * Add meta information to the PDF - * - * @param string $label label of the value (Creator, Producter, etc.) - * @param string $value the text to set - */ - function add_info($label, $value) { - $this->_pdf->set_info($label, $value); - } - - /** - * Opens a new 'object' (template in PDFLib-speak) - * - * While an object is open, all drawing actions are recorded to the - * object instead of being drawn on the current page. Objects can - * be added later to a specific page or to several pages. - * - * The return value is an integer ID for the new object. - * - * @see PDFLib_Adapter::close_object() - * @see PDFLib_Adapter::add_object() - * - * @return int - */ - function open_object() { - $this->_pdf->suspend_page(""); - $ret = $this->_pdf->begin_template($this->_width, $this->_height); - $this->_pdf->save(); - $this->_objs[$ret] = array("start_page" => $this->_page_number); - return $ret; - } - - /** - * Reopen an existing object (NOT IMPLEMENTED) - * PDFLib does not seem to support reopening templates. - * - * @param int $object the ID of a previously opened object - * - * @throws DOMPDF_Exception - * @return void - */ - function reopen_object($object) { - throw new DOMPDF_Exception("PDFLib does not support reopening objects."); - } - - /** - * Close the current template - * - * @see PDFLib_Adapter::open_object() - */ - function close_object() { - $this->_pdf->restore(); - $this->_pdf->end_template(); - $this->_pdf->resume_page("pagenumber=".$this->_page_number); - } - - /** - * Adds the specified object to the document - * - * $where can be one of: - * - 'add' add to current page only - * - 'all' add to every page from the current one onwards - * - 'odd' add to all odd numbered pages from now on - * - 'even' add to all even numbered pages from now on - * - 'next' add the object to the next page only - * - 'nextodd' add to all odd numbered pages from the next one - * - 'nexteven' add to all even numbered pages from the next one - * - * @param int $object the object handle returned by open_object() - * @param string $where - */ - function add_object($object, $where = 'all') { - - if ( mb_strpos($where, "next") !== false ) { - $this->_objs[$object]["start_page"]++; - $where = str_replace("next", "", $where); - if ( $where == "" ) - $where = "add"; - } - - $this->_objs[$object]["where"] = $where; - } - - /** - * Stops the specified template from appearing in the document. - * - * The object will stop being displayed on the page following the - * current one. - * - * @param int $object - */ - function stop_object($object) { - - if ( !isset($this->_objs[$object]) ) - return; - - $start = $this->_objs[$object]["start_page"]; - $where = $this->_objs[$object]["where"]; - - // Place the object on this page if required - if ( $this->_page_number >= $start && - (($this->_page_number % 2 == 0 && $where === "even") || - ($this->_page_number % 2 == 1 && $where === "odd") || - ($where === "all")) ) { - $this->_pdf->fit_image($object, 0, 0, ""); - } - - $this->_objs[$object] = null; - unset($this->_objs[$object]); - } - - /** - * Add all active objects to the current page - */ - protected function _place_objects() { - - foreach ( $this->_objs as $obj => $props ) { - $start = $props["start_page"]; - $where = $props["where"]; - - // Place the object on this page if required - if ( $this->_page_number >= $start && - (($this->_page_number % 2 == 0 && $where === "even") || - ($this->_page_number % 2 == 1 && $where === "odd") || - ($where === "all")) ) { - $this->_pdf->fit_image($obj,0,0,""); - } - } - - } - - function get_width() { return $this->_width; } - - function get_height() { return $this->_height; } - - function get_page_number() { return $this->_page_number; } - - function get_page_count() { return $this->_page_count; } - - function set_page_number($num) { $this->_page_number = (int)$num; } - - function set_page_count($count) { $this->_page_count = (int)$count; } - - - /** - * Sets the line style - * - * @param float $width - * @param $cap - * @param string $join - * @param array $dash - * - * @return void - */ - protected function _set_line_style($width, $cap, $join, $dash) { - - if ( count($dash) == 1 ) - $dash[] = $dash[0]; - - if ( count($dash) > 1 ) - $this->_pdf->setdashpattern("dasharray={" . implode(" ", $dash) . "}"); - else - $this->_pdf->setdash(0,0); - - switch ( $join ) { - case "miter": - $this->_pdf->setlinejoin(0); - break; - - case "round": - $this->_pdf->setlinejoin(1); - break; - - case "bevel": - $this->_pdf->setlinejoin(2); - break; - - default: - break; - } - - switch ( $cap ) { - case "butt": - $this->_pdf->setlinecap(0); - break; - - case "round": - $this->_pdf->setlinecap(1); - break; - - case "square": - $this->_pdf->setlinecap(2); - break; - - default: - break; - } - - $this->_pdf->setlinewidth($width); - - } - - /** - * Sets the line color - * - * @param array $color array(r,g,b) - */ - protected function _set_stroke_color($color) { - if($this->_last_stroke_color == $color) - return; - - $this->_last_stroke_color = $color; - - if (isset($color[3])) { - $type = "cmyk"; - list($c1, $c2, $c3, $c4) = array($color[0], $color[1], $color[2], $color[3]); - } - elseif (isset($color[2])) { - $type = "rgb"; - list($c1, $c2, $c3, $c4) = array($color[0], $color[1], $color[2], null); - } - else { - $type = "gray"; - list($c1, $c2, $c3, $c4) = array($color[0], $color[1], null, null); - } - - $this->_pdf->setcolor("stroke", $type, $c1, $c2, $c3, $c4); - } - - /** - * Sets the fill color - * - * @param array $color array(r,g,b) - */ - protected function _set_fill_color($color) { - if($this->_last_fill_color == $color) - return; - - $this->_last_fill_color = $color; - - if (isset($color[3])) { - $type = "cmyk"; - list($c1, $c2, $c3, $c4) = array($color[0], $color[1], $color[2], $color[3]); - } - elseif (isset($color[2])) { - $type = "rgb"; - list($c1, $c2, $c3, $c4) = array($color[0], $color[1], $color[2], null); - } - else { - $type = "gray"; - list($c1, $c2, $c3, $c4) = array($color[0], $color[1], null, null); - } - - $this->_pdf->setcolor("fill", $type, $c1, $c2, $c3, $c4); - } - - /** - * Sets the opacity - * - * @param $opacity - * @param $mode - */ - function set_opacity($opacity, $mode = "Normal") { - if ( $mode === "Normal" ) { - $gstate = $this->_pdf->create_gstate("opacityfill=$opacity opacitystroke=$opacity"); - $this->_pdf->set_gstate($gstate); - } - } - - function set_default_view($view, $options = array()) { - // TODO - // http://www.pdflib.com/fileadmin/pdflib/pdf/manuals/PDFlib-8.0.2-API-reference.pdf - /** - * fitheight Fit the page height to the window, with the x coordinate left at the left edge of the window. - * fitrect Fit the rectangle specified by left, bottom, right, and top to the window. - * fitvisible Fit the visible contents of the page (the ArtBox) to the window. - * fitvisibleheight Fit the visible contents of the page to the window with the x coordinate left at the left edge of the window. - * fitvisiblewidth Fit the visible contents of the page to the window with the y coordinate top at the top edge of the window. - * fitwidth Fit the page width to the window, with the y coordinate top at the top edge of the window. - * fitwindow Fit the complete page to the window. - * fixed - */ - //$this->_pdf->set_parameter("openaction", $view); - } - - /** - * Loads a specific font and stores the corresponding descriptor. - * - * @param string $font - * @param string $encoding - * @param string $options - * - * @return int the font descriptor for the font - */ - protected function _load_font($font, $encoding = null, $options = "") { - - // Check if the font is a native PDF font - // Embed non-native fonts - $test = strtolower(basename($font)); - if ( in_array($test, DOMPDF::$native_fonts) ) { - $font = basename($font); - - } else { - // Embed non-native fonts - $options .= " embedding=true"; - } - - if ( is_null($encoding) ) { - - // Unicode encoding is only available for the commerical - // version of PDFlib and not PDFlib-Lite - if ( defined("DOMPDF_PDFLIB_LICENSE") ) - $encoding = "unicode"; - else - $encoding = "auto"; - - } - - $key = "$font:$encoding:$options"; - - if ( isset($this->_fonts[$key]) ) - return $this->_fonts[$key]; - - else { - - $this->_fonts[$key] = $this->_pdf->load_font($font, $encoding, $options); - return $this->_fonts[$key]; - - } - - } - - /** - * Remaps y coords from 4th to 1st quadrant - * - * @param float $y - * @return float - */ - protected function y($y) { return $this->_height - $y; } - - //........................................................................ - - /** - * @param float $x1 - * @param float $y1 - * @param float $x2 - * @param float $y2 - * @param array $color - * @param float $width - * @param array $style - */ - function line($x1, $y1, $x2, $y2, $color, $width, $style = null) { - $this->_set_line_style($width, "butt", "", $style); - $this->_set_stroke_color($color); - - $y1 = $this->y($y1); - $y2 = $this->y($y2); - - $this->_pdf->moveto($x1, $y1); - $this->_pdf->lineto($x2, $y2); - $this->_pdf->stroke(); - } - - function arc($x1, $y1, $r1, $r2, $astart, $aend, $color, $width, $style = array()) { - $this->_set_line_style($width, "butt", "", $style); - $this->_set_stroke_color($color); - - $y1 = $this->y($y1); - - $this->_pdf->arc($x1, $y1, $r1, $astart, $aend); - $this->_pdf->stroke(); - } - - //........................................................................ - - function rectangle($x1, $y1, $w, $h, $color, $width, $style = null) { - $this->_set_stroke_color($color); - $this->_set_line_style($width, "butt", "", $style); - - $y1 = $this->y($y1) - $h; - - $this->_pdf->rect($x1, $y1, $w, $h); - $this->_pdf->stroke(); - } - - //........................................................................ - - function filled_rectangle($x1, $y1, $w, $h, $color) { - $this->_set_fill_color($color); - - $y1 = $this->y($y1) - $h; - - $this->_pdf->rect(floatval($x1), floatval($y1), floatval($w), floatval($h)); - $this->_pdf->fill(); - } - - function clipping_rectangle($x1, $y1, $w, $h) { - $this->_pdf->save(); - - $y1 = $this->y($y1) - $h; - - $this->_pdf->rect(floatval($x1), floatval($y1), floatval($w), floatval($h)); - $this->_pdf->clip(); - } - - function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) { - // @todo - $this->clipping_rectangle($x1, $y1, $w, $h); - } - - function clipping_end() { - $this->_pdf->restore(); - } - - function save() { - $this->_pdf->save(); - } - - function restore() { - $this->_pdf->restore(); - } - - function rotate($angle, $x, $y) { - $pdf = $this->_pdf; - $pdf->translate($x, $this->_height-$y); - $pdf->rotate(-$angle); - $pdf->translate(-$x, -$this->_height+$y); - } - - function skew($angle_x, $angle_y, $x, $y) { - $pdf = $this->_pdf; - $pdf->translate($x, $this->_height-$y); - $pdf->skew($angle_y, $angle_x); // Needs to be inverted - $pdf->translate(-$x, -$this->_height+$y); - } - - function scale($s_x, $s_y, $x, $y) { - $pdf = $this->_pdf; - $pdf->translate($x, $this->_height-$y); - $pdf->scale($s_x, $s_y); - $pdf->translate(-$x, -$this->_height+$y); - } - - function translate($t_x, $t_y) { - $this->_pdf->translate($t_x, -$t_y); - } - - function transform($a, $b, $c, $d, $e, $f) { - $this->_pdf->concat($a, $b, $c, $d, $e, $f); - } - - //........................................................................ - - function polygon($points, $color, $width = null, $style = null, $fill = false) { - - $this->_set_fill_color($color); - $this->_set_stroke_color($color); - - if ( !$fill && isset($width) ) - $this->_set_line_style($width, "square", "miter", $style); - - $y = $this->y(array_pop($points)); - $x = array_pop($points); - $this->_pdf->moveto($x,$y); - - while (count($points) > 1) { - $y = $this->y(array_pop($points)); - $x = array_pop($points); - $this->_pdf->lineto($x,$y); - } - - if ( $fill ) - $this->_pdf->fill(); - else - $this->_pdf->closepath_stroke(); - } - - //........................................................................ - - function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false) { - - $this->_set_fill_color($color); - $this->_set_stroke_color($color); - - if ( !$fill && isset($width) ) - $this->_set_line_style($width, "round", "round", $style); - - $y = $this->y($y); - - $this->_pdf->circle($x, $y, $r); - - if ( $fill ) - $this->_pdf->fill(); - else - $this->_pdf->stroke(); - - } - - //........................................................................ - - function image($img_url, $x, $y, $w, $h, $resolution = "normal") { - $w = (int)$w; - $h = (int)$h; - - $img_type = Image_Cache::detect_type($img_url); - $img_ext = Image_Cache::type_to_ext($img_type); - - if ( !isset($this->_imgs[$img_url]) ) { - $this->_imgs[$img_url] = $this->_pdf->load_image($img_ext, $img_url, ""); - } - - $img = $this->_imgs[$img_url]; - - $y = $this->y($y) - $h; - $this->_pdf->fit_image($img, $x, $y, 'boxsize={'."$w $h".'} fitmethod=entire'); - } - - //........................................................................ - - function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_spacing = 0, $char_spacing = 0, $angle = 0) { - $fh = $this->_load_font($font); - - $this->_pdf->setfont($fh, $size); - $this->_set_fill_color($color); - - $y = $this->y($y) - Font_Metrics::get_font_height($font, $size); - - $word_spacing = (float)$word_spacing; - $char_spacing = (float)$char_spacing; - $angle = -(float)$angle; - - $this->_pdf->fit_textline($text, $x, $y, "rotate=$angle wordspacing=$word_spacing charspacing=$char_spacing "); - - } - - //........................................................................ - - function javascript($code) { - if ( defined("DOMPDF_PDFLIB_LICENSE") ) { - $this->_pdf->create_action("JavaScript", $code); - } - } - - //........................................................................ - - /** - * Add a named destination (similar to ... in html) - * - * @param string $anchorname The name of the named destination - */ - function add_named_dest($anchorname) { - $this->_pdf->add_nameddest($anchorname,""); - } - - //........................................................................ - - /** - * Add a link to the pdf - * - * @param string $url The url to link to - * @param float $x The x position of the link - * @param float $y The y position of the link - * @param float $width The width of the link - * @param float $height The height of the link - */ - function add_link($url, $x, $y, $width, $height) { - - $y = $this->y($y) - $height; - if ( strpos($url, '#') === 0 ) { - // Local link - $name = substr($url,1); - if ( $name ) - $this->_pdf->create_annotation($x, $y, $x + $width, $y + $height, 'Link', "contents={$url} destname=". substr($url,1) . " linewidth=0"); - } else { - - list($proto, $host, $path, $file) = explode_url($url); - - if ( $proto == "" || $proto === "file://" ) - return; // Local links are not allowed - $url = build_url($proto, $host, $path, $file); - $url = '{' . rawurldecode($url) . '}'; - - $action = $this->_pdf->create_action("URI", "url=" . $url); - $this->_pdf->create_annotation($x, $y, $x + $width, $y + $height, 'Link', "contents={$url} action={activate=$action} linewidth=0"); - } - } - - //........................................................................ - - function get_text_width($text, $font, $size, $word_spacing = 0, $letter_spacing = 0) { - $fh = $this->_load_font($font); - - // Determine the additional width due to extra spacing - $num_spaces = mb_substr_count($text," "); - $delta = $word_spacing * $num_spaces; - - if ( $letter_spacing ) { - $num_chars = mb_strlen($text); - $delta += ($num_chars - $num_spaces) * $letter_spacing; - } - - return $this->_pdf->stringwidth($text, $fh, $size) + $delta; - } - - //........................................................................ - - function get_font_height($font, $size) { - - $fh = $this->_load_font($font); - - $this->_pdf->setfont($fh, $size); - - $asc = $this->_pdf->get_value("ascender", $fh); - $desc = $this->_pdf->get_value("descender", $fh); - - // $desc is usually < 0, - $ratio = $this->_dompdf->get_option("font_height_ratio"); - return $size * ($asc - $desc) * $ratio; - } - - function get_font_baseline($font, $size) { - $ratio = $this->_dompdf->get_option("font_height_ratio"); - return $this->get_font_height($font, $size) / $ratio * 1.1; - } - - //........................................................................ - - /** - * Writes text at the specified x and y coordinates on every page - * - * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced - * with their current values. - * - * See {@link Style::munge_color()} for the format of the color array. - * - * @param float $x - * @param float $y - * @param string $text the text to write - * @param string $font the font file to use - * @param float $size the font size, in points - * @param array $color - * @param float $word_space word spacing adjustment - * @param float $char_space char spacing adjustment - * @param float $angle angle to write the text at, measured CW starting from the x-axis - */ - function page_text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) { - $_t = "text"; - $this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle"); - } - - //........................................................................ - - /** - * Processes a script on every page - * - * The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available. - * - * This function can be used to add page numbers to all pages - * after the first one, for example. - * - * @param string $code the script code - * @param string $type the language type for script - */ - function page_script($code, $type = "text/php") { - $_t = "script"; - $this->_page_text[] = compact("_t", "code", "type"); - } - - //........................................................................ - - function new_page() { - - // Add objects to the current page - $this->_place_objects(); - - $this->_pdf->suspend_page(""); - $this->_pdf->begin_page_ext($this->_width, $this->_height, ""); - $this->_page_number = ++$this->_page_count; - - } - - //........................................................................ - - /** - * Add text to each page after rendering is complete - */ - protected function _add_page_text() { - - if ( !count($this->_page_text) ) - return; - - $this->_pdf->suspend_page(""); - - for ($p = 1; $p <= $this->_page_count; $p++) { - $this->_pdf->resume_page("pagenumber=$p"); - - foreach ($this->_page_text as $pt) { - extract($pt); - - switch ($_t) { - - case "text": - $text = str_replace(array("{PAGE_NUM}","{PAGE_COUNT}"), - array($p, $this->_page_count), $text); - $this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle); - break; - - case "script": - if (!$eval) { - $eval = new PHP_Evaluator($this); - } - $eval->evaluate($code, array('PAGE_NUM' => $p, 'PAGE_COUNT' => $this->_page_count)); - break; - } - } - - $this->_pdf->suspend_page(""); - } - - $this->_pdf->resume_page("pagenumber=".$this->_page_number); - } - - //........................................................................ - - function stream($filename, $options = null) { - - // Add page text - $this->_add_page_text(); - - if ( isset($options["compress"]) && $options["compress"] != 1 ) - $this->_pdf->set_value("compress", 0); - else - $this->_pdf->set_value("compress", 6); - - $this->_close(); - - $data = ""; - - if ( self::$IN_MEMORY ) { - $data = $this->_pdf->get_buffer(); - //$size = strlen($data); - } else { - //$size = filesize($this->_file); - } - - - $filename = str_replace(array("\n","'"),"", $filename); - $attach = (isset($options["Attachment"]) && $options["Attachment"]) ? "attachment" : "inline"; - - header("Cache-Control: private"); - header("Content-type: application/pdf"); - header("Content-Disposition: $attach; filename=\"$filename\""); - - //header("Content-length: " . $size); - - if ( self::$IN_MEMORY ) - echo $data; - - else { - - // Chunked readfile() - $chunk = (1 << 21); // 2 MB - $fh = fopen($this->_file, "rb"); - if ( !$fh ) - throw new DOMPDF_Exception("Unable to load temporary PDF file: " . $this->_file); - - while ( !feof($fh) ) - echo fread($fh,$chunk); - fclose($fh); - - //debugpng - if (DEBUGPNG) print '[pdflib stream unlink '.$this->_file.']'; - if (!DEBUGKEEPTEMP) - - unlink($this->_file); - $this->_file = null; - unset($this->_file); - } - - flush(); - } - - //........................................................................ - - function output($options = null) { - - // Add page text - $this->_add_page_text(); - - if ( isset($options["compress"]) && $options["compress"] != 1 ) - $this->_pdf->set_value("compress", 0); - else - $this->_pdf->set_value("compress", 6); - - $this->_close(); - - if ( self::$IN_MEMORY ) - $data = $this->_pdf->get_buffer(); - - else { - $data = file_get_contents($this->_file); - - //debugpng - if (DEBUGPNG) print '[pdflib output unlink '.$this->_file.']'; - if (!DEBUGKEEPTEMP) - - unlink($this->_file); - $this->_file = null; - unset($this->_file); - } - - return $data; - } -} - -// Workaround for idiotic limitation on statics... -PDFLib_Adapter::$PAPER_SIZES = CPDF_Adapter::$PAPER_SIZES; diff --git a/application/helpers/dompdf/include/php_evaluator.cls.php b/application/helpers/dompdf/include/php_evaluator.cls.php deleted file mode 100755 index 38896675d..000000000 --- a/application/helpers/dompdf/include/php_evaluator.cls.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Executes inline PHP code during the rendering process - * - * @access private - * @package dompdf - */ -class PHP_Evaluator { - - /** - * @var Canvas - */ - protected $_canvas; - - function __construct(Canvas $canvas) { - $this->_canvas = $canvas; - } - - function evaluate($code, $vars = array()) { - if ( !$this->_canvas->get_dompdf()->get_option("enable_php") ) { - return; - } - - // Set up some variables for the inline code - $pdf = $this->_canvas; - $PAGE_NUM = $pdf->get_page_number(); - $PAGE_COUNT = $pdf->get_page_count(); - - // Override those variables if passed in - foreach ($vars as $k => $v) { - $$k = $v; - } - - //$code = html_entity_decode($code); // @todo uncomment this when tested - eval($code); - } - - function render(Frame $frame) { - $this->evaluate($frame->get_node()->nodeValue); - } -} diff --git a/application/helpers/dompdf/include/positioner.cls.php b/application/helpers/dompdf/include/positioner.cls.php deleted file mode 100755 index 6a8b9edc1..000000000 --- a/application/helpers/dompdf/include/positioner.cls.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Base Positioner class - * - * Defines postioner interface - * - * @access private - * @package dompdf - */ -abstract class Positioner { - - /** - * @var Frame_Decorator - */ - protected $_frame; - - //........................................................................ - - function __construct(Frame_Decorator $frame) { - $this->_frame = $frame; - } - - /** - * Class destructor - */ - function __destruct() { - clear_object($this); - } - //........................................................................ - - abstract function position(); - - function move($offset_x, $offset_y, $ignore_self = false) { - list($x, $y) = $this->_frame->get_position(); - - if ( !$ignore_self ) { - $this->_frame->set_position($x + $offset_x, $y + $offset_y); - } - - foreach($this->_frame->get_children() as $child) { - $child->move($offset_x, $offset_y); - } - } -} diff --git a/application/helpers/dompdf/include/renderer.cls.php b/application/helpers/dompdf/include/renderer.cls.php deleted file mode 100755 index ceff4775c..000000000 --- a/application/helpers/dompdf/include/renderer.cls.php +++ /dev/null @@ -1,290 +0,0 @@ - - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Concrete renderer - * - * Instantiates several specific renderers in order to render any given - * frame. - * - * @access private - * @package dompdf - */ -class Renderer extends Abstract_Renderer { - - /** - * Array of renderers for specific frame types - * - * @var Abstract_Renderer[] - */ - protected $_renderers; - - /** - * Cache of the callbacks array - * - * @var array - */ - private $_callbacks; - - /** - * Class destructor - */ - function __destruct() { - clear_object($this); - } - - /** - * Advance the canvas to the next page - */ - function new_page() { - $this->_canvas->new_page(); - } - - /** - * Render frames recursively - * - * @param Frame $frame the frame to render - */ - function render(Frame $frame) { - global $_dompdf_debug; - - if ( $_dompdf_debug ) { - echo $frame; - flush(); - } - - $style = $frame->get_style(); - - if ( in_array($style->visibility, array("hidden", "collapse")) ) { - return; - } - - $display = $style->display; - - // Starts the CSS transformation - if ( $style->transform && is_array($style->transform) ) { - $this->_canvas->save(); - list($x, $y) = $frame->get_padding_box(); - $origin = $style->transform_origin; - - foreach($style->transform as $transform) { - list($function, $values) = $transform; - if ( $function === "matrix" ) { - $function = "transform"; - } - - $values = array_map("floatval", $values); - $values[] = $x + $style->length_in_pt($origin[0], $style->width); - $values[] = $y + $style->length_in_pt($origin[1], $style->height); - - call_user_func_array(array($this->_canvas, $function), $values); - } - } - - switch ($display) { - - case "block": - case "list-item": - case "inline-block": - case "table": - case "inline-table": - $this->_render_frame("block", $frame); - break; - - case "inline": - if ( $frame->is_text_node() ) - $this->_render_frame("text", $frame); - else - $this->_render_frame("inline", $frame); - break; - - case "table-cell": - $this->_render_frame("table-cell", $frame); - break; - - case "table-row-group": - case "table-header-group": - case "table-footer-group": - $this->_render_frame("table-row-group", $frame); - break; - - case "-dompdf-list-bullet": - $this->_render_frame("list-bullet", $frame); - break; - - case "-dompdf-image": - $this->_render_frame("image", $frame); - break; - - case "none": - $node = $frame->get_node(); - - if ( $node->nodeName === "script" ) { - if ( $node->getAttribute("type") === "text/php" || - $node->getAttribute("language") === "php" ) { - // Evaluate embedded php scripts - $this->_render_frame("php", $frame); - } - - elseif ( $node->getAttribute("type") === "text/javascript" || - $node->getAttribute("language") === "javascript" ) { - // Insert JavaScript - $this->_render_frame("javascript", $frame); - } - } - - // Don't render children, so skip to next iter - return; - - default: - break; - - } - - // Starts the overflow: hidden box - if ( $style->overflow === "hidden" ) { - list($x, $y, $w, $h) = $frame->get_padding_box(); - - // get border radii - $style = $frame->get_style(); - list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); - - if ( $tl + $tr + $br + $bl > 0 ) { - $this->_canvas->clipping_roundrectangle($x, $y, $w, $h, $tl, $tr, $br, $bl); - } - else { - $this->_canvas->clipping_rectangle($x, $y, $w, $h); - } - } - - $stack = array(); - - foreach ($frame->get_children() as $child) { - // < 0 : nagative z-index - // = 0 : no z-index, no stacking context - // = 1 : stacking context without z-index - // > 1 : z-index - $child_style = $child->get_style(); - $child_z_index = $child_style->z_index; - $z_index = 0; - - if ( $child_z_index !== "auto" ) { - $z_index = intval($child_z_index) + 1; - } - elseif ( $child_style->float !== "none" || $child->is_positionned()) { - $z_index = 1; - } - - $stack[$z_index][] = $child; - } - - ksort($stack); - - foreach ($stack as $by_index) { - foreach($by_index as $child) { - $this->render($child); - } - } - - // Ends the overflow: hidden box - if ( $style->overflow === "hidden" ) { - $this->_canvas->clipping_end(); - } - - if ( $style->transform && is_array($style->transform) ) { - $this->_canvas->restore(); - } - - // Check for end frame callback - $this->_check_callbacks("end_frame", $frame); - } - - /** - * Check for callbacks that need to be performed when a given event - * gets triggered on a frame - * - * @param string $event the type of event - * @param Frame $frame the frame that event is triggered on - */ - protected function _check_callbacks($event, $frame) { - if (!isset($this->_callbacks)) { - $this->_callbacks = $this->_dompdf->get_callbacks(); - } - - if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) { - $info = array(0 => $this->_canvas, "canvas" => $this->_canvas, - 1 => $frame, "frame" => $frame); - $fs = $this->_callbacks[$event]; - foreach ($fs as $f) { - if (is_callable($f)) { - if (is_array($f)) { - $f[0]->$f[1]($info); - } else { - $f($info); - } - } - } - } - } - - /** - * Render a single frame - * - * Creates Renderer objects on demand - * - * @param string $type type of renderer to use - * @param Frame $frame the frame to render - */ - protected function _render_frame($type, $frame) { - - if ( !isset($this->_renderers[$type]) ) { - - switch ($type) { - case "block": - $this->_renderers[$type] = new Block_Renderer($this->_dompdf); - break; - - case "inline": - $this->_renderers[$type] = new Inline_Renderer($this->_dompdf); - break; - - case "text": - $this->_renderers[$type] = new Text_Renderer($this->_dompdf); - break; - - case "image": - $this->_renderers[$type] = new Image_Renderer($this->_dompdf); - break; - - case "table-cell": - $this->_renderers[$type] = new Table_Cell_Renderer($this->_dompdf); - break; - - case "table-row-group": - $this->_renderers[$type] = new Table_Row_Group_Renderer($this->_dompdf); - break; - - case "list-bullet": - $this->_renderers[$type] = new List_Bullet_Renderer($this->_dompdf); - break; - - case "php": - $this->_renderers[$type] = new PHP_Evaluator($this->_canvas); - break; - - case "javascript": - $this->_renderers[$type] = new Javascript_Embedder($this->_dompdf); - break; - - } - } - - $this->_renderers[$type]->render($frame); - - } -} diff --git a/application/helpers/dompdf/include/style.cls.php b/application/helpers/dompdf/include/style.cls.php deleted file mode 100755 index d08fb4baa..000000000 --- a/application/helpers/dompdf/include/style.cls.php +++ /dev/null @@ -1,2435 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * Represents CSS properties. - * - * The Style class is responsible for handling and storing CSS properties. - * It includes methods to resolve colors and lengths, as well as getters & - * setters for many CSS properites. - * - * Actual CSS parsing is performed in the {@link Stylesheet} class. - * - * @package dompdf - */ -class Style { - - const CSS_IDENTIFIER = "-?[_a-zA-Z]+[_a-zA-Z0-9-]*"; - const CSS_INTEGER = "-?\d+"; - - /** - * Default font size, in points. - * - * @var float - */ - static $default_font_size = 12; - - /** - * Default line height, as a fraction of the font size. - * - * @var float - */ - static $default_line_height = 1.2; - - /** - * Default "absolute" font sizes relative to the default font-size - * http://www.w3.org/TR/css3-fonts/#font-size-the-font-size-property - * @var array - */ - static $font_size_keywords = array( - "xx-small" => 0.6, // 3/5 - "x-small" => 0.75, // 3/4 - "small" => 0.889, // 8/9 - "medium" => 1, // 1 - "large" => 1.2, // 6/5 - "x-large" => 1.5, // 3/2 - "xx-large" => 2.0, // 2/1 - ); - - /** - * List of all inline types. Should really be a constant. - * - * @var array - */ - static $INLINE_TYPES = array("inline"); - - /** - * List of all block types. Should really be a constant. - * - * @var array - */ - static $BLOCK_TYPES = array("block", "inline-block", "table-cell", "list-item"); - - /** - * List of all positionned types. Should really be a constant. - * - * @var array - */ - static $POSITIONNED_TYPES = array("relative", "absolute", "fixed"); - - /** - * List of all table types. Should really be a constant. - * - * @var array; - */ - static $TABLE_TYPES = array("table", "inline-table"); - - /** - * List of valid border styles. Should also really be a constant. - * - * @var array - */ - static $BORDER_STYLES = array("none", "hidden", "dotted", "dashed", "solid", - "double", "groove", "ridge", "inset", "outset"); - - /** - * Default style values. - * - * @link http://www.w3.org/TR/CSS21/propidx.html - * - * @var array - */ - static protected $_defaults = null; - - /** - * List of inherited properties - * - * @link http://www.w3.org/TR/CSS21/propidx.html - * - * @var array - */ - static protected $_inherited = null; - - /** - * Caches method_exists result - * - * @var array - */ - static protected $_methods_cache = array(); - - /** - * The stylesheet this style belongs to - * - * @see Stylesheet - * @var Stylesheet - */ - protected $_stylesheet; // stylesheet this style is attached to - - /** - * Main array of all CSS properties & values - * - * @var array - */ - protected $_props; - - /* var instead of protected would allow access outside of class */ - protected $_important_props; - - /** - * Cached property values - * - * @var array - */ - protected $_prop_cache; - - /** - * Font size of parent element in document tree. Used for relative font - * size resolution. - * - * @var float - */ - protected $_parent_font_size; // Font size of parent element - - protected $_font_family; - - /** - * @var Frame - */ - protected $_frame; - - /** - * The origin of the style - * - * @var int - */ - protected $_origin = Stylesheet::ORIG_AUTHOR; - - // private members - /** - * True once the font size is resolved absolutely - * - * @var bool - */ - private $__font_size_calculated; // Cache flag - - /** - * The computed border radius - */ - private $_computed_border_radius = null; - - /** - * @var bool - */ - public $_has_border_radius = false; - - /** - * Class constructor - * - * @param Stylesheet $stylesheet the stylesheet this Style is associated with. - * @param int $origin - */ - function __construct(Stylesheet $stylesheet, $origin = Stylesheet::ORIG_AUTHOR) { - $this->_props = array(); - $this->_important_props = array(); - $this->_stylesheet = $stylesheet; - $this->_origin = $origin; - $this->_parent_font_size = null; - $this->__font_size_calculated = false; - - if ( !isset(self::$_defaults) ) { - - // Shorthand - $d =& self::$_defaults; - - // All CSS 2.1 properties, and their default values - $d["azimuth"] = "center"; - $d["background_attachment"] = "scroll"; - $d["background_color"] = "transparent"; - $d["background_image"] = "none"; - $d["background_image_resolution"] = "normal"; - $d["_dompdf_background_image_resolution"] = $d["background_image_resolution"]; - $d["background_position"] = "0% 0%"; - $d["background_repeat"] = "repeat"; - $d["background"] = ""; - $d["border_collapse"] = "separate"; - $d["border_color"] = ""; - $d["border_spacing"] = "0"; - $d["border_style"] = ""; - $d["border_top"] = ""; - $d["border_right"] = ""; - $d["border_bottom"] = ""; - $d["border_left"] = ""; - $d["border_top_color"] = ""; - $d["border_right_color"] = ""; - $d["border_bottom_color"] = ""; - $d["border_left_color"] = ""; - $d["border_top_style"] = "none"; - $d["border_right_style"] = "none"; - $d["border_bottom_style"] = "none"; - $d["border_left_style"] = "none"; - $d["border_top_width"] = "medium"; - $d["border_right_width"] = "medium"; - $d["border_bottom_width"] = "medium"; - $d["border_left_width"] = "medium"; - $d["border_width"] = "medium"; - $d["border_bottom_left_radius"] = ""; - $d["border_bottom_right_radius"] = ""; - $d["border_top_left_radius"] = ""; - $d["border_top_right_radius"] = ""; - $d["border_radius"] = ""; - $d["border"] = ""; - $d["bottom"] = "auto"; - $d["caption_side"] = "top"; - $d["clear"] = "none"; - $d["clip"] = "auto"; - $d["color"] = "#000000"; - $d["content"] = "normal"; - $d["counter_increment"] = "none"; - $d["counter_reset"] = "none"; - $d["cue_after"] = "none"; - $d["cue_before"] = "none"; - $d["cue"] = ""; - $d["cursor"] = "auto"; - $d["direction"] = "ltr"; - $d["display"] = "inline"; - $d["elevation"] = "level"; - $d["empty_cells"] = "show"; - $d["float"] = "none"; - $d["font_family"] = $stylesheet->get_dompdf()->get_option("default_font"); - $d["font_size"] = "medium"; - $d["font_style"] = "normal"; - $d["font_variant"] = "normal"; - $d["font_weight"] = "normal"; - $d["font"] = ""; - $d["height"] = "auto"; - $d["image_resolution"] = "normal"; - $d["_dompdf_image_resolution"] = $d["image_resolution"]; - $d["_dompdf_keep"] = ""; - $d["left"] = "auto"; - $d["letter_spacing"] = "normal"; - $d["line_height"] = "normal"; - $d["list_style_image"] = "none"; - $d["list_style_position"] = "outside"; - $d["list_style_type"] = "disc"; - $d["list_style"] = ""; - $d["margin_right"] = "0"; - $d["margin_left"] = "0"; - $d["margin_top"] = "0"; - $d["margin_bottom"] = "0"; - $d["margin"] = ""; - $d["max_height"] = "none"; - $d["max_width"] = "none"; - $d["min_height"] = "0"; - $d["min_width"] = "0"; - $d["opacity"] = "1.0"; // CSS3 - $d["orphans"] = "2"; - $d["outline_color"] = ""; // "invert" special color is not supported - $d["outline_style"] = "none"; - $d["outline_width"] = "medium"; - $d["outline"] = ""; - $d["overflow"] = "visible"; - $d["padding_top"] = "0"; - $d["padding_right"] = "0"; - $d["padding_bottom"] = "0"; - $d["padding_left"] = "0"; - $d["padding"] = ""; - $d["page_break_after"] = "auto"; - $d["page_break_before"] = "auto"; - $d["page_break_inside"] = "auto"; - $d["pause_after"] = "0"; - $d["pause_before"] = "0"; - $d["pause"] = ""; - $d["pitch_range"] = "50"; - $d["pitch"] = "medium"; - $d["play_during"] = "auto"; - $d["position"] = "static"; - $d["quotes"] = ""; - $d["richness"] = "50"; - $d["right"] = "auto"; - $d["size"] = "auto"; // @page - $d["speak_header"] = "once"; - $d["speak_numeral"] = "continuous"; - $d["speak_punctuation"] = "none"; - $d["speak"] = "normal"; - $d["speech_rate"] = "medium"; - $d["stress"] = "50"; - $d["table_layout"] = "auto"; - $d["text_align"] = "left"; - $d["text_decoration"] = "none"; - $d["text_indent"] = "0"; - $d["text_transform"] = "none"; - $d["top"] = "auto"; - $d["transform"] = "none"; // CSS3 - $d["transform_origin"] = "50% 50%"; // CSS3 - $d["_webkit_transform"] = $d["transform"]; // CSS3 - $d["_webkit_transform_origin"] = $d["transform_origin"]; // CSS3 - $d["unicode_bidi"] = "normal"; - $d["vertical_align"] = "baseline"; - $d["visibility"] = "visible"; - $d["voice_family"] = ""; - $d["volume"] = "medium"; - $d["white_space"] = "normal"; - $d["word_wrap"] = "normal"; - $d["widows"] = "2"; - $d["width"] = "auto"; - $d["word_spacing"] = "normal"; - $d["z_index"] = "auto"; - - // for @font-face - $d["src"] = ""; - $d["unicode_range"] = ""; - - // Properties that inherit by default - self::$_inherited = array( - "azimuth", - "background_image_resolution", - "border_collapse", - "border_spacing", - "caption_side", - "color", - "cursor", - "direction", - "elevation", - "empty_cells", - "font_family", - "font_size", - "font_style", - "font_variant", - "font_weight", - "font", - "image_resolution", - "letter_spacing", - "line_height", - "list_style_image", - "list_style_position", - "list_style_type", - "list_style", - "orphans", - "page_break_inside", - "pitch_range", - "pitch", - "quotes", - "richness", - "speak_header", - "speak_numeral", - "speak_punctuation", - "speak", - "speech_rate", - "stress", - "text_align", - "text_indent", - "text_transform", - "visibility", - "voice_family", - "volume", - "white_space", - "word_wrap", - "widows", - "word_spacing", - ); - } - } - - /** - * "Destructor": forcibly free all references held by this object - */ - function dispose() { - clear_object($this); - } - - function set_frame(Frame $frame) { - $this->_frame = $frame; - } - - function get_frame() { - return $this->_frame; - } - - function set_origin($origin) { - $this->_origin = $origin; - } - - function get_origin() { - return $this->_origin; - } - - /** - * returns the {@link Stylesheet} this Style is associated with. - * - * @return Stylesheet - */ - function get_stylesheet() { return $this->_stylesheet; } - - /** - * Converts any CSS length value into an absolute length in points. - * - * length_in_pt() takes a single length (e.g. '1em') or an array of - * lengths and returns an absolute length. If an array is passed, then - * the return value is the sum of all elements. - * - * If a reference size is not provided, the default font size is used - * ({@link Style::$default_font_size}). - * - * @param float|array $length the length or array of lengths to resolve - * @param float $ref_size an absolute reference size to resolve percentage lengths - * @return float - */ - function length_in_pt($length, $ref_size = null) { - static $cache = array(); - - if ( !is_array($length) ) { - $length = array($length); - } - - if ( !isset($ref_size) ) { - $ref_size = self::$default_font_size; - } - - $key = implode("@", $length)."/$ref_size"; - - if ( isset($cache[$key]) ) { - return $cache[$key]; - } - - $ret = 0; - foreach ($length as $l) { - - if ( $l === "auto" ) { - return "auto"; - } - - if ( $l === "none" ) { - return "none"; - } - - // Assume numeric values are already in points - if ( is_numeric($l) ) { - $ret += $l; - continue; - } - - if ( $l === "normal" ) { - $ret += $ref_size; - continue; - } - - // Border lengths - if ( $l === "thin" ) { - $ret += 0.5; - continue; - } - - if ( $l === "medium" ) { - $ret += 1.5; - continue; - } - - if ( $l === "thick" ) { - $ret += 2.5; - continue; - } - - if ( ($i = mb_strpos($l, "px")) !== false ) { - $dpi = $this->_stylesheet->get_dompdf()->get_option("dpi"); - $ret += ( mb_substr($l, 0, $i) * 72 ) / $dpi; - continue; - } - - if ( ($i = mb_strpos($l, "pt")) !== false ) { - $ret += (float)mb_substr($l, 0, $i); - continue; - } - - if ( ($i = mb_strpos($l, "%")) !== false ) { - $ret += (float)mb_substr($l, 0, $i)/100 * $ref_size; - continue; - } - - if ( ($i = mb_strpos($l, "rem")) !== false ) { - $ret += (float)mb_substr($l, 0, $i) * $this->_stylesheet->get_dompdf()->get_tree()->get_root()->get_style()->font_size; - continue; - } - - if ( ($i = mb_strpos($l, "em")) !== false ) { - $ret += (float)mb_substr($l, 0, $i) * $this->__get("font_size"); - continue; - } - - if ( ($i = mb_strpos($l, "cm")) !== false ) { - $ret += mb_substr($l, 0, $i) * 72 / 2.54; - continue; - } - - if ( ($i = mb_strpos($l, "mm")) !== false ) { - $ret += mb_substr($l, 0, $i) * 72 / 25.4; - continue; - } - - // FIXME: em:ex ratio? - if ( ($i = mb_strpos($l, "ex")) !== false ) { - $ret += mb_substr($l, 0, $i) * $this->__get("font_size") / 2; - continue; - } - - if ( ($i = mb_strpos($l, "in")) !== false ) { - $ret += (float)mb_substr($l, 0, $i) * 72; - continue; - } - - if ( ($i = mb_strpos($l, "pc")) !== false ) { - $ret += (float)mb_substr($l, 0, $i) * 12; - continue; - } - - // Bogus value - $ret += $ref_size; - } - - return $cache[$key] = $ret; - } - - - /** - * Set inherited properties in this style using values in $parent - * - * @param Style $parent - * - * @return Style - */ - function inherit(Style $parent) { - - // Set parent font size - $this->_parent_font_size = $parent->get_font_size(); - - foreach (self::$_inherited as $prop) { - //inherit the !important property also. - //if local property is also !important, don't inherit. - if ( isset($parent->_props[$prop]) && - ( !isset($this->_props[$prop]) || - ( isset($parent->_important_props[$prop]) && !isset($this->_important_props[$prop]) ) - ) - ) { - if ( isset($parent->_important_props[$prop]) ) { - $this->_important_props[$prop] = true; - } - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$prop] = null; - $this->_props[$prop] = $parent->_props[$prop]; - } - } - - foreach ($this->_props as $prop => $value) { - if ( $value === "inherit" ) { - if ( isset($parent->_important_props[$prop]) ) { - $this->_important_props[$prop] = true; - } - //do not assign direct, but - //implicite assignment through __set, redirect to specialized, get value with __get - //This is for computing defaults if the parent setting is also missing. - //Therefore do not directly assign the value without __set - //set _important_props before that to be able to propagate. - //see __set and __get, on all assignments clear cache! - //$this->_prop_cache[$prop] = null; - //$this->_props[$prop] = $parent->_props[$prop]; - //props_set for more obvious explicite assignment not implemented, because - //too many implicite uses. - // $this->props_set($prop, $parent->$prop); - $this->__set($prop, $parent->__get($prop)); - } - } - - return $this; - } - - /** - * Override properties in this style with those in $style - * - * @param Style $style - */ - function merge(Style $style) { - //treat the !important attribute - //if old rule has !important attribute, override with new rule only if - //the new rule is also !important - foreach($style->_props as $prop => $val ) { - if (isset($style->_important_props[$prop])) { - $this->_important_props[$prop] = true; - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$prop] = null; - $this->_props[$prop] = $val; - } - else if ( !isset($this->_important_props[$prop]) ) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$prop] = null; - $this->_props[$prop] = $val; - } - } - - if ( isset($style->_props["font_size"]) ) { - $this->__font_size_calculated = false; - } - } - - /** - * Returns an array(r, g, b, "r"=> r, "g"=>g, "b"=>b, "hex"=>"#rrggbb") - * based on the provided CSS color value. - * - * @param string $color - * @return array - */ - function munge_color($color) { - return CSS_Color::parse($color); - } - - /* direct access to _important_props array from outside would work only when declared as - * 'var $_important_props;' instead of 'protected $_important_props;' - * Don't call _set/__get on missing attribute. Therefore need a special access. - * Assume that __set will be also called when this is called, so do not check validity again. - * Only created, if !important exists -> always set true. - */ - function important_set($prop) { - $prop = str_replace("-", "_", $prop); - $this->_important_props[$prop] = true; - } - - function important_get($prop) { - return isset($this->_important_props[$prop]); - } - - /** - * PHP5 overloaded setter - * - * This function along with {@link Style::__get()} permit a user of the - * Style class to access any (CSS) property using the following syntax: - * - * Style->margin_top = "1em"; - * echo (Style->margin_top); - * - * - * __set() automatically calls the provided set function, if one exists, - * otherwise it sets the property directly. Typically, __set() is not - * called directly from outside of this class. - * - * On each modification clear cache to return accurate setting. - * Also affects direct settings not using __set - * For easier finding all assignments, attempted to allowing only explicite assignment: - * Very many uses, e.g. frame_reflower.cls.php -> for now leave as it is - * function __set($prop, $val) { - * throw new DOMPDF_Exception("Implicite replacement of assignment by __set. Not good."); - * } - * function props_set($prop, $val) { ... } - * - * @param string $prop the property to set - * @param mixed $val the value of the property - * - */ - function __set($prop, $val) { - $prop = str_replace("-", "_", $prop); - $this->_prop_cache[$prop] = null; - - if ( !isset(self::$_defaults[$prop]) ) { - global $_dompdf_warnings; - $_dompdf_warnings[] = "'$prop' is not a valid CSS2 property."; - return; - } - - if ( $prop !== "content" && is_string($val) && strlen($val) > 5 && mb_strpos($val, "url") === false ) { - $val = mb_strtolower(trim(str_replace(array("\n", "\t"), array(" "), $val))); - $val = preg_replace("/([0-9]+) (pt|px|pc|em|ex|in|cm|mm|%)/S", "\\1\\2", $val); - } - - $method = "set_$prop"; - - if ( !isset(self::$_methods_cache[$method]) ) { - self::$_methods_cache[$method] = method_exists($this, $method); - } - - if ( self::$_methods_cache[$method] ) { - $this->$method($val); - } - else { - $this->_props[$prop] = $val; - } - } - - /** - * PHP5 overloaded getter - * Along with {@link Style::__set()} __get() provides access to all CSS - * properties directly. Typically __get() is not called directly outside - * of this class. - * On each modification clear cache to return accurate setting. - * Also affects direct settings not using __set - * - * @param string $prop - * - * @throws DOMPDF_Exception - * @return mixed - */ - function __get($prop) { - if ( !isset(self::$_defaults[$prop]) ) { - throw new DOMPDF_Exception("'$prop' is not a valid CSS2 property."); - } - - if ( isset($this->_prop_cache[$prop]) && $this->_prop_cache[$prop] != null ) { - return $this->_prop_cache[$prop]; - } - - $method = "get_$prop"; - - // Fall back on defaults if property is not set - if ( !isset($this->_props[$prop]) ) { - $this->_props[$prop] = self::$_defaults[$prop]; - } - - if ( !isset(self::$_methods_cache[$method]) ) { - self::$_methods_cache[$method] = method_exists($this, $method); - } - - if ( self::$_methods_cache[$method] ) { - return $this->_prop_cache[$prop] = $this->$method(); - } - - return $this->_prop_cache[$prop] = $this->_props[$prop]; - } - - function get_font_family_raw(){ - return trim($this->_props["font_family"], " \t\n\r\x0B\"'"); - } - - /** - * Getter for the 'font-family' CSS property. - * Uses the {@link Font_Metrics} class to resolve the font family into an - * actual font file. - * - * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-family - * @throws DOMPDF_Exception - * - * @return string - */ - function get_font_family() { - if ( isset($this->_font_family) ) { - return $this->_font_family; - } - - $DEBUGCSS=DEBUGCSS; //=DEBUGCSS; Allow override of global setting for ad hoc debug - - // Select the appropriate font. First determine the subtype, then check - // the specified font-families for a candidate. - - // Resolve font-weight - $weight = $this->__get("font_weight"); - - if ( is_numeric($weight) ) { - if ( $weight < 600 ) { - $weight = "normal"; - } - else { - $weight = "bold"; - } - } - else if ( $weight === "bold" || $weight === "bolder" ) { - $weight = "bold"; - } - else { - $weight = "normal"; - } - - // Resolve font-style - $font_style = $this->__get("font_style"); - - if ( $weight === "bold" && ($font_style === "italic" || $font_style === "oblique") ) { - $subtype = "bold_italic"; - } - else if ( $weight === "bold" && $font_style !== "italic" && $font_style !== "oblique" ) { - $subtype = "bold"; - } - else if ( $weight !== "bold" && ($font_style === "italic" || $font_style === "oblique") ) { - $subtype = "italic"; - } - else { - $subtype = "normal"; - } - - // Resolve the font family - if ( $DEBUGCSS ) { - print "
[get_font_family:";
-      print '('.$this->_props["font_family"].'.'.$font_style.'.'.$this->__get("font_weight").'.'.$weight.'.'.$subtype.')';
-    }
-    
-    $families = preg_split("/\s*,\s*/", $this->_props["font_family"]);
-
-    $font = null;
-    foreach($families as $family) {
-      //remove leading and trailing string delimiters, e.g. on font names with spaces;
-      //remove leading and trailing whitespace
-      $family = trim($family, " \t\n\r\x0B\"'");
-      if ( $DEBUGCSS ) {
-        print '('.$family.')';
-      }
-      $font = Font_Metrics::get_font($family, $subtype);
-
-      if ( $font ) {
-        if ($DEBUGCSS) print '('.$font.")get_font_family]\n
"; - return $this->_font_family = $font; - } - } - - $family = null; - if ( $DEBUGCSS ) { - print '(default)'; - } - $font = Font_Metrics::get_font($family, $subtype); - - if ( $font ) { - if ( $DEBUGCSS ) print '('.$font.")get_font_family]\n"; - return$this->_font_family = $font; - } - - throw new DOMPDF_Exception("Unable to find a suitable font replacement for: '" . $this->_props["font_family"] ."'"); - - } - - /** - * Returns the resolved font size, in points - * - * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-size - * @return float - */ - function get_font_size() { - - if ( $this->__font_size_calculated ) { - return $this->_props["font_size"]; - } - - if ( !isset($this->_props["font_size"]) ) { - $fs = self::$_defaults["font_size"]; - } - else { - $fs = $this->_props["font_size"]; - } - - if ( !isset($this->_parent_font_size) ) { - $this->_parent_font_size = self::$default_font_size; - } - - switch ((string)$fs) { - case "xx-small": - case "x-small": - case "small": - case "medium": - case "large": - case "x-large": - case "xx-large": - $fs = self::$default_font_size * self::$font_size_keywords[$fs]; - break; - - case "smaller": - $fs = 8/9 * $this->_parent_font_size; - break; - - case "larger": - $fs = 6/5 * $this->_parent_font_size; - break; - - default: - break; - } - - // Ensure relative sizes resolve to something - if ( ($i = mb_strpos($fs, "em")) !== false ) { - $fs = mb_substr($fs, 0, $i) * $this->_parent_font_size; - } - else if ( ($i = mb_strpos($fs, "ex")) !== false ) { - $fs = mb_substr($fs, 0, $i) * $this->_parent_font_size; - } - else { - $fs = $this->length_in_pt($fs); - } - - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["font_size"] = null; - $this->_props["font_size"] = $fs; - $this->__font_size_calculated = true; - return $this->_props["font_size"]; - - } - - /** - * @link http://www.w3.org/TR/CSS21/text.html#propdef-word-spacing - * @return float - */ - function get_word_spacing() { - if ( $this->_props["word_spacing"] === "normal" ) { - return 0; - } - - return $this->_props["word_spacing"]; - } - - /** - * @link http://www.w3.org/TR/CSS21/text.html#propdef-letter-spacing - * @return float - */ - function get_letter_spacing() { - if ( $this->_props["letter_spacing"] === "normal" ) { - return 0; - } - - return $this->_props["letter_spacing"]; - } - - /** - * @link http://www.w3.org/TR/CSS21/visudet.html#propdef-line-height - * @return float - */ - function get_line_height() { - $line_height = $this->_props["line_height"]; - - if ( $line_height === "normal" ) { - return self::$default_line_height * $this->get_font_size(); - } - - if ( is_numeric($line_height) ) { - return $this->length_in_pt( $line_height . "em", $this->get_font_size()); - } - - return $this->length_in_pt( $line_height, $this->_parent_font_size ); - } - - /** - * Returns the color as an array - * - * The array has the following format: - * array(r,g,b, "r" => r, "g" => g, "b" => b, "hex" => "#rrggbb") - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-color - * @return array - */ - function get_color() { - return $this->munge_color( $this->_props["color"] ); - } - - /** - * Returns the background color as an array - * - * The returned array has the same format as {@link Style::get_color()} - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-color - * @return array - */ - function get_background_color() { - return $this->munge_color( $this->_props["background_color"] ); - } - - /** - * Returns the background position as an array - * - * The returned array has the following format: - * array(x,y, "x" => x, "y" => y) - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-position - * @return array - */ - function get_background_position() { - $tmp = explode(" ", $this->_props["background_position"]); - - switch ($tmp[0]) { - case "left": - $x = "0%"; - break; - - case "right": - $x = "100%"; - break; - - case "top": - $y = "0%"; - break; - - case "bottom": - $y = "100%"; - break; - - case "center": - $x = "50%"; - $y = "50%"; - break; - - default: - $x = $tmp[0]; - break; - } - - if ( isset($tmp[1]) ) { - - switch ($tmp[1]) { - case "left": - $x = "0%"; - break; - - case "right": - $x = "100%"; - break; - - case "top": - $y = "0%"; - break; - - case "bottom": - $y = "100%"; - break; - - case "center": - if ( $tmp[0] === "left" || $tmp[0] === "right" || $tmp[0] === "center" ) { - $y = "50%"; - } - else { - $x = "50%"; - } - break; - - default: - $y = $tmp[1]; - break; - } - - } - else { - $y = "50%"; - } - - if ( !isset($x) ) { - $x = "0%"; - } - - if ( !isset($y) ) { - $y = "0%"; - } - - return array( - 0 => $x, "x" => $x, - 1 => $y, "y" => $y, - ); - } - - - /** - * Returns the background as it is currently stored - * - * (currently anyway only for completeness. - * not used for further processing) - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-attachment - * @return string - */ - function get_background_attachment() { - return $this->_props["background_attachment"]; - } - - - /** - * Returns the background_repeat as it is currently stored - * - * (currently anyway only for completeness. - * not used for further processing) - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-repeat - * @return string - */ - function get_background_repeat() { - return $this->_props["background_repeat"]; - } - - - /** - * Returns the background as it is currently stored - * - * (currently anyway only for completeness. - * not used for further processing, but the individual get_background_xxx) - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background - * @return string - */ - function get_background() { - return $this->_props["background"]; - } - - - /**#@+ - * Returns the border color as an array - * - * See {@link Style::get_color()} - * - * @link http://www.w3.org/TR/CSS21/box.html#border-color-properties - * @return array - */ - function get_border_top_color() { - if ( $this->_props["border_top_color"] === "" ) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["border_top_color"] = null; - $this->_props["border_top_color"] = $this->__get("color"); - } - - return $this->munge_color($this->_props["border_top_color"]); - } - - function get_border_right_color() { - if ( $this->_props["border_right_color"] === "" ) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["border_right_color"] = null; - $this->_props["border_right_color"] = $this->__get("color"); - } - - return $this->munge_color($this->_props["border_right_color"]); - } - - function get_border_bottom_color() { - if ( $this->_props["border_bottom_color"] === "" ) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["border_bottom_color"] = null; - $this->_props["border_bottom_color"] = $this->__get("color"); - } - - return $this->munge_color($this->_props["border_bottom_color"]); - } - - function get_border_left_color() { - if ( $this->_props["border_left_color"] === "" ) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["border_left_color"] = null; - $this->_props["border_left_color"] = $this->__get("color"); - } - - return $this->munge_color($this->_props["border_left_color"]); - } - - /**#@-*/ - - /**#@+ - * Returns the border width, as it is currently stored - * - * @link http://www.w3.org/TR/CSS21/box.html#border-width-properties - * @return float|string - */ - function get_border_top_width() { - $style = $this->__get("border_top_style"); - return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_top_width"]) : 0; - } - - function get_border_right_width() { - $style = $this->__get("border_right_style"); - return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_right_width"]) : 0; - } - - function get_border_bottom_width() { - $style = $this->__get("border_bottom_style"); - return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_bottom_width"]) : 0; - } - - function get_border_left_width() { - $style = $this->__get("border_left_style"); - return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_left_width"]) : 0; - } - /**#@-*/ - - /** - * Return an array of all border properties. - * - * The returned array has the following structure: - * - * array("top" => array("width" => [border-width], - * "style" => [border-style], - * "color" => [border-color (array)]), - * "bottom" ... ) - * - * - * @return array - */ - function get_border_properties() { - return array( - "top" => array( - "width" => $this->__get("border_top_width"), - "style" => $this->__get("border_top_style"), - "color" => $this->__get("border_top_color"), - ), - "bottom" => array( - "width" => $this->__get("border_bottom_width"), - "style" => $this->__get("border_bottom_style"), - "color" => $this->__get("border_bottom_color"), - ), - "right" => array( - "width" => $this->__get("border_right_width"), - "style" => $this->__get("border_right_style"), - "color" => $this->__get("border_right_color"), - ), - "left" => array( - "width" => $this->__get("border_left_width"), - "style" => $this->__get("border_left_style"), - "color" => $this->__get("border_left_color"), - ), - ); - } - - /** - * Return a single border property - * - * @param string $side - * - * @return mixed - */ - protected function _get_border($side) { - $color = $this->__get("border_" . $side . "_color"); - - return $this->__get("border_" . $side . "_width") . " " . - $this->__get("border_" . $side . "_style") . " " . $color["hex"]; - } - - /**#@+ - * Return full border properties as a string - * - * Border properties are returned just as specified in CSS: - *
[width] [style] [color]
- * e.g. "1px solid blue" - * - * @link http://www.w3.org/TR/CSS21/box.html#border-shorthand-properties - * @return string - */ - function get_border_top() { - return $this->_get_border("top"); - } - - function get_border_right() { - return $this->_get_border("right"); - } - - function get_border_bottom() { - return $this->_get_border("bottom"); - } - - function get_border_left() { - return $this->_get_border("left"); - } - /**#@-*/ - - function get_computed_border_radius($w, $h) { - if ( !empty($this->_computed_border_radius) ) { - return $this->_computed_border_radius; - } - - $rTL = $this->__get("border_top_left_radius"); - $rTR = $this->__get("border_top_right_radius"); - $rBL = $this->__get("border_bottom_left_radius"); - $rBR = $this->__get("border_bottom_right_radius"); - - if ( $rTL + $rTR + $rBL + $rBR == 0 ) { - return $this->_computed_border_radius = array( - 0, 0, 0, 0, - "top-left" => 0, - "top-right" => 0, - "bottom-right" => 0, - "bottom-left" => 0, - ); - } - - $t = $this->__get("border_top_width"); - $r = $this->__get("border_right_width"); - $b = $this->__get("border_bottom_width"); - $l = $this->__get("border_left_width"); - - $rTL = min($rTL, $h - $rBL - $t/2 - $b/2, $w - $rTR - $l/2 - $r/2); - $rTR = min($rTR, $h - $rBR - $t/2 - $b/2, $w - $rTL - $l/2 - $r/2); - $rBL = min($rBL, $h - $rTL - $t/2 - $b/2, $w - $rBR - $l/2 - $r/2); - $rBR = min($rBR, $h - $rTR - $t/2 - $b/2, $w - $rBL - $l/2 - $r/2); - - return $this->_computed_border_radius = array( - $rTL, $rTR, $rBR, $rBL, - "top-left" => $rTL, - "top-right" => $rTR, - "bottom-right" => $rBR, - "bottom-left" => $rBL, - ); - } - /**#@-*/ - - - /** - * Returns the outline color as an array - * - * See {@link Style::get_color()} - * - * @link http://www.w3.org/TR/CSS21/box.html#border-color-properties - * @return array - */ - function get_outline_color() { - if ( $this->_props["outline_color"] === "" ) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["outline_color"] = null; - $this->_props["outline_color"] = $this->__get("color"); - } - - return $this->munge_color($this->_props["outline_color"]); - } - - /**#@+ - * Returns the outline width, as it is currently stored - * @return float|string - */ - function get_outline_width() { - $style = $this->__get("outline_style"); - return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["outline_width"]) : 0; - } - - /**#@+ - * Return full outline properties as a string - * - * Outline properties are returned just as specified in CSS: - *
[width] [style] [color]
- * e.g. "1px solid blue" - * - * @link http://www.w3.org/TR/CSS21/box.html#border-shorthand-properties - * @return string - */ - function get_outline() { - $color = $this->__get("outline_color"); - return - $this->__get("outline_width") . " " . - $this->__get("outline_style") . " " . - $color["hex"]; - } - /**#@-*/ - - /** - * Returns border spacing as an array - * - * The array has the format (h_space,v_space) - * - * @link http://www.w3.org/TR/CSS21/tables.html#propdef-border-spacing - * @return array - */ - function get_border_spacing() { - $arr = explode(" ", $this->_props["border_spacing"]); - if ( count($arr) == 1 ) { - $arr[1] = $arr[0]; - } - return $arr; - } - -/*==============================*/ - - /* - !important attribute - For basic functionality of the !important attribute with overloading - of several styles of an element, changes in inherit(), merge() and _parse_properties() - are sufficient [helpers var $_important_props, __construct(), important_set(), important_get()] - - Only for combined attributes extra treatment needed. See below. - - div { border: 1px red; } - div { border: solid; } // Not combined! Only one occurence of same style per context - // - div { border: 1px red; } - div a { border: solid; } // Adding to border style ok by inheritance - // - div { border-style: solid; } // Adding to border style ok because of different styles - div { border: 1px red; } - // - div { border-style: solid; !important} // border: overrides, even though not !important - div { border: 1px dashed red; } - // - div { border: 1px red; !important } - div a { border-style: solid; } // Need to override because not set - - Special treatment: - At individual property like border-top-width need to check whether overriding value is also !important. - Also store the !important condition for later overrides. - Since not known who is initiating the override, need to get passed !important as parameter. - !important Paramter taken as in the original style in the css file. - When property border !important given, do not mark subsets like border_style as important. Only - individual properties. - - Note: - Setting individual property directly from css with e.g. set_border_top_style() is not needed, because - missing set funcions handled by a generic handler __set(), including the !important. - Setting individual property of as sub-property is handled below. - - Implementation see at _set_style_side_type() - Callers _set_style_sides_type(), _set_style_type, _set_style_type_important() - - Related functionality for background, padding, margin, font, list_style - */ - - /* Generalized set function for individual attribute of combined style. - * With check for !important - * Applicable for background, border, padding, margin, font, list_style - * Note: $type has a leading underscore (or is empty), the others not. - */ - protected function _set_style_side_type($style, $side, $type, $val, $important) { - $prop = $style.'_'.$side.$type; - - if ( !isset($this->_important_props[$prop]) || $important) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$prop] = null; - if ( $important ) { - $this->_important_props[$prop] = true; - } - $this->_props[$prop] = $val; - } - } - - protected function _set_style_sides_type($style,$top,$right,$bottom,$left,$type,$important) { - $this->_set_style_side_type($style,'top',$type,$top,$important); - $this->_set_style_side_type($style,'right',$type,$right,$important); - $this->_set_style_side_type($style,'bottom',$type,$bottom,$important); - $this->_set_style_side_type($style,'left',$type,$left,$important); - } - - protected function _set_style_type($style,$type,$val,$important) { - $val = preg_replace("/\s*\,\s*/", ",", $val); // when rgb() has spaces - $arr = explode(" ", $val); - - switch (count($arr)) { - case 1: $this->_set_style_sides_type($style,$arr[0],$arr[0],$arr[0],$arr[0],$type,$important); break; - case 2: $this->_set_style_sides_type($style,$arr[0],$arr[1],$arr[0],$arr[1],$type,$important); break; - case 3: $this->_set_style_sides_type($style,$arr[0],$arr[1],$arr[2],$arr[1],$type,$important); break; - case 4: $this->_set_style_sides_type($style,$arr[0],$arr[1],$arr[2],$arr[3],$type,$important); break; - } - - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$style.$type] = null; - $this->_props[$style.$type] = $val; - } - - protected function _set_style_type_important($style,$type,$val) { - $this->_set_style_type($style,$type,$val,isset($this->_important_props[$style.$type])); - } - - /* Anyway only called if _important matches and is assigned - * E.g. _set_style_side_type($style,$side,'',str_replace("none", "0px", $val),isset($this->_important_props[$style.'_'.$side])); - */ - protected function _set_style_side_width_important($style,$side,$val) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$style.'_'.$side] = null; - $this->_props[$style.'_'.$side] = str_replace("none", "0px", $val); - } - - protected function _set_style($style,$val,$important) { - if ( !isset($this->_important_props[$style]) || $important) { - if ( $important ) { - $this->_important_props[$style] = true; - } - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$style] = null; - $this->_props[$style] = $val; - } - } - - protected function _image($val) { - $DEBUGCSS=DEBUGCSS; - $parsed_url = "none"; - - if ( mb_strpos($val, "url") === false ) { - $path = "none"; //Don't resolve no image -> otherwise would prefix path and no longer recognize as none - } - else { - $val = preg_replace("/url\(['\"]?([^'\")]+)['\"]?\)/","\\1", trim($val)); - - // Resolve the url now in the context of the current stylesheet - $parsed_url = explode_url($val); - if ( $parsed_url["protocol"] == "" && $this->_stylesheet->get_protocol() == "" ) { - if ($parsed_url["path"][0] === '/' || $parsed_url["path"][0] === '\\' ) { - $path = $_SERVER["DOCUMENT_ROOT"].'/'; - } - else { - $path = $this->_stylesheet->get_base_path(); - } - - $path .= $parsed_url["path"] . $parsed_url["file"]; - $path = realpath($path); - // If realpath returns FALSE then specifically state that there is no background image - if ( !$path ) { - $path = 'none'; - } - } - else { - $path = build_url($this->_stylesheet->get_protocol(), - $this->_stylesheet->get_host(), - $this->_stylesheet->get_base_path(), - $val); - } - } - if ($DEBUGCSS) { - print "
[_image\n";
-      print_r($parsed_url);
-      print $this->_stylesheet->get_protocol()."\n".$this->_stylesheet->get_base_path()."\n".$path."\n";
-      print "_image]
";; - } - return $path; - } - -/*======================*/ - - /** - * Sets color - * - * The color parameter can be any valid CSS color value - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-color - * @param string $color - */ - function set_color($color) { - $col = $this->munge_color($color); - - if ( is_null($col) || !isset($col["hex"]) ) { - $color = "inherit"; - } - else { - $color = $col["hex"]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["color"] = null; - $this->_props["color"] = $color; - } - - /** - * Sets the background color - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-color - * @param string $color - */ - function set_background_color($color) { - $col = $this->munge_color($color); - - if ( is_null($col) ) { - return; - //$col = self::$_defaults["background_color"]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["background_color"] = null; - $this->_props["background_color"] = is_array($col) ? $col["hex"] : $col; - } - - /** - * Set the background image url - * @link http://www.w3.org/TR/CSS21/colors.html#background-properties - * - * @param string $val - */ - function set_background_image($val) { - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["background_image"] = null; - $this->_props["background_image"] = $this->_image($val); - } - - /** - * Sets the background repeat - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-repeat - * @param string $val - */ - function set_background_repeat($val) { - if ( is_null($val) ) { - $val = self::$_defaults["background_repeat"]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["background_repeat"] = null; - $this->_props["background_repeat"] = $val; - } - - /** - * Sets the background attachment - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-attachment - * @param string $val - */ - function set_background_attachment($val) { - if ( is_null($val) ) { - $val = self::$_defaults["background_attachment"]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["background_attachment"] = null; - $this->_props["background_attachment"] = $val; - } - - /** - * Sets the background position - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-position - * @param string $val - */ - function set_background_position($val) { - if ( is_null($val) ) { - $val = self::$_defaults["background_position"]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["background_position"] = null; - $this->_props["background_position"] = $val; - } - - /** - * Sets the background - combined options - * - * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background - * @param string $val - */ - function set_background($val) { - $val = trim($val); - $important = isset($this->_important_props["background"]); - - if ( $val === "none" ) { - $this->_set_style("background_image", "none", $important); - $this->_set_style("background_color", "transparent", $important); - } - else { - $pos = array(); - $tmp = preg_replace("/\s*\,\s*/", ",", $val); // when rgb() has spaces - $tmp = preg_split("/\s+/", $tmp); - - foreach($tmp as $attr) { - if ( mb_substr($attr, 0, 3) === "url" || $attr === "none" ) { - $this->_set_style("background_image", $this->_image($attr), $important); - } - elseif ( $attr === "fixed" || $attr === "scroll" ) { - $this->_set_style("background_attachment", $attr, $important); - } - elseif ( $attr === "repeat" || $attr === "repeat-x" || $attr === "repeat-y" || $attr === "no-repeat" ) { - $this->_set_style("background_repeat", $attr, $important); - } - elseif ( ($col = $this->munge_color($attr)) != null ) { - $this->_set_style("background_color", is_array($col) ? $col["hex"] : $col, $important); - } - else { - $pos[] = $attr; - } - } - - if (count($pos)) { - $this->_set_style("background_position", implode(" ", $pos), $important); - } - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["background"] = null; - $this->_props["background"] = $val; - } - - /** - * Sets the font size - * - * $size can be any acceptable CSS size - * - * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-size - * @param string|float $size - */ - function set_font_size($size) { - $this->__font_size_calculated = false; - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["font_size"] = null; - $this->_props["font_size"] = $size; - } - - /** - * Sets the font style - * - * combined attributes - * set individual attributes also, respecting !important mark - * exactly this order, separate by space. Multiple fonts separated by comma: - * font-style, font-variant, font-weight, font-size, line-height, font-family - * - * Other than with border and list, existing partial attributes should - * reset when starting here, even when not mentioned. - * If individual attribute is !important and explicite or implicite replacement is not, - * keep individual attribute - * - * require whitespace as delimiters for single value attributes - * On delimiter "/" treat first as font height, second as line height - * treat all remaining at the end of line as font - * font-style, font-variant, font-weight, font-size, line-height, font-family - * - * missing font-size and font-family might be not allowed, but accept it here and - * use default (medium size, enpty font name) - * - * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style - * @param $val - */ - function set_font($val) { - $this->__font_size_calculated = false; - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["font"] = null; - $this->_props["font"] = $val; - - $important = isset($this->_important_props["font"]); - - if ( preg_match("/^(italic|oblique|normal)\s*(.*)$/i",$val,$match) ) { - $this->_set_style("font_style", $match[1], $important); - $val = $match[2]; - } - else { - $this->_set_style("font_style", self::$_defaults["font_style"], $important); - } - - if ( preg_match("/^(small-caps|normal)\s*(.*)$/i",$val,$match) ) { - $this->_set_style("font_variant", $match[1], $important); - $val = $match[2]; - } - else { - $this->_set_style("font_variant", self::$_defaults["font_variant"], $important); - } - - //matching numeric value followed by unit -> this is indeed a subsequent font size. Skip! - if ( preg_match("/^(bold|bolder|lighter|100|200|300|400|500|600|700|800|900|normal)\s*(.*)$/i", $val, $match) && - !preg_match("/^(?:pt|px|pc|em|ex|in|cm|mm|%)/",$match[2]) - ) { - $this->_set_style("font_weight", $match[1], $important); - $val = $match[2]; - } - else { - $this->_set_style("font_weight", self::$_defaults["font_weight"], $important); - } - - if ( preg_match("/^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger|\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))\s*(.*)$/i",$val,$match) ) { - $this->_set_style("font_size", $match[1], $important); - $val = $match[2]; - if ( preg_match("/^\/\s*(\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))\s*(.*)$/i", $val, $match ) ) { - $this->_set_style("line_height", $match[1], $important); - $val = $match[2]; - } - else { - $this->_set_style("line_height", self::$_defaults["line_height"], $important); - } - } - else { - $this->_set_style("font_size", self::$_defaults["font_size"], $important); - $this->_set_style("line_height", self::$_defaults["line_height"], $important); - } - - if( strlen($val) != 0 ) { - $this->_set_style("font_family", $val, $important); - } - else { - $this->_set_style("font_family", self::$_defaults["font_family"], $important); - } - } - - /**#@+ - * Sets page break properties - * - * @link http://www.w3.org/TR/CSS21/page.html#page-breaks - * @param string $break - */ - function set_page_break_before($break) { - if ( $break === "left" || $break === "right" ) { - $break = "always"; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["page_break_before"] = null; - $this->_props["page_break_before"] = $break; - } - - function set_page_break_after($break) { - if ( $break === "left" || $break === "right" ) { - $break = "always"; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["page_break_after"] = null; - $this->_props["page_break_after"] = $break; - } - /**#@-*/ - - //........................................................................ - - /**#@+ - * Sets the margin size - * - * @link http://www.w3.org/TR/CSS21/box.html#margin-properties - * @param $val - */ - function set_margin_top($val) { - $this->_set_style_side_width_important('margin','top',$val); - } - - function set_margin_right($val) { - $this->_set_style_side_width_important('margin','right',$val); - } - - function set_margin_bottom($val) { - $this->_set_style_side_width_important('margin','bottom',$val); - } - - function set_margin_left($val) { - $this->_set_style_side_width_important('margin','left',$val); - } - - function set_margin($val) { - $val = str_replace("none", "0px", $val); - $this->_set_style_type_important('margin','',$val); - } - /**#@-*/ - - /**#@+ - * Sets the padding size - * - * @link http://www.w3.org/TR/CSS21/box.html#padding-properties - * @param $val - */ - function set_padding_top($val) { - $this->_set_style_side_width_important('padding','top',$val); - } - - function set_padding_right($val) { - $this->_set_style_side_width_important('padding','right',$val); - } - - function set_padding_bottom($val) { - $this->_set_style_side_width_important('padding','bottom',$val); - } - - function set_padding_left($val) { - $this->_set_style_side_width_important('padding','left',$val); - } - - function set_padding($val) { - $val = str_replace("none", "0px", $val); - $this->_set_style_type_important('padding','',$val); - } - /**#@-*/ - - /** - * Sets a single border - * - * @param string $side - * @param string $border_spec ([width] [style] [color]) - * @param boolean $important - */ - protected function _set_border($side, $border_spec, $important) { - $border_spec = preg_replace("/\s*\,\s*/", ",", $border_spec); - //$border_spec = str_replace(",", " ", $border_spec); // Why did we have this ?? rbg(10, 102, 10) > rgb(10 102 10) - $arr = explode(" ", $border_spec); - - // FIXME: handle partial values - - //For consistency of individal and combined properties, and with ie8 and firefox3 - //reset all attributes, even if only partially given - $this->_set_style_side_type('border',$side,'_style',self::$_defaults['border_'.$side.'_style'],$important); - $this->_set_style_side_type('border',$side,'_width',self::$_defaults['border_'.$side.'_width'],$important); - $this->_set_style_side_type('border',$side,'_color',self::$_defaults['border_'.$side.'_color'],$important); - - foreach ($arr as $value) { - $value = trim($value); - if ( in_array($value, self::$BORDER_STYLES) ) { - $this->_set_style_side_type('border',$side,'_style',$value,$important); - } - else if ( preg_match("/[.0-9]+(?:px|pt|pc|em|ex|%|in|mm|cm)|(?:thin|medium|thick)/", $value ) ) { - $this->_set_style_side_type('border',$side,'_width',$value,$important); - } - else { - // must be color - $this->_set_style_side_type('border',$side,'_color',$value,$important); - } - } - - //see __set and __get, on all assignments clear cache! - $this->_prop_cache['border_'.$side] = null; - $this->_props['border_'.$side] = $border_spec; - } - - /** - * Sets the border styles - * - * @link http://www.w3.org/TR/CSS21/box.html#border-properties - * @param string $val - */ - function set_border_top($val) { - $this->_set_border("top", $val, isset($this->_important_props['border_top'])); - } - - function set_border_right($val) { - $this->_set_border("right", $val, isset($this->_important_props['border_right'])); - } - - function set_border_bottom($val) { - $this->_set_border("bottom", $val, isset($this->_important_props['border_bottom'])); - } - - function set_border_left($val) { - $this->_set_border("left", $val, isset($this->_important_props['border_left'])); - } - - function set_border($val) { - $important = isset($this->_important_props["border"]); - $this->_set_border("top", $val, $important); - $this->_set_border("right", $val, $important); - $this->_set_border("bottom", $val, $important); - $this->_set_border("left", $val, $important); - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["border"] = null; - $this->_props["border"] = $val; - } - - function set_border_width($val) { - $this->_set_style_type_important('border','_width',$val); - } - - function set_border_color($val) { - $this->_set_style_type_important('border','_color',$val); - } - - function set_border_style($val) { - $this->_set_style_type_important('border','_style',$val); - } - - /** - * Sets the border radius size - * - * http://www.w3.org/TR/css3-background/#corners - */ - function set_border_top_left_radius($val) { - $this->_set_border_radius_corner($val, "top_left"); - } - - function set_border_top_right_radius($val) { - $this->_set_border_radius_corner($val, "top_right"); - } - - function set_border_bottom_left_radius($val) { - $this->_set_border_radius_corner($val, "bottom_left"); - } - - function set_border_bottom_right_radius($val) { - $this->_set_border_radius_corner($val, "bottom_right"); - } - - function set_border_radius($val) { - $val = preg_replace("/\s*\,\s*/", ",", $val); // when border-radius has spaces - $arr = explode(" ", $val); - - switch (count($arr)) { - case 1: $this->_set_border_radii($arr[0],$arr[0],$arr[0],$arr[0]); break; - case 2: $this->_set_border_radii($arr[0],$arr[1],$arr[0],$arr[1]); break; - case 3: $this->_set_border_radii($arr[0],$arr[1],$arr[2],$arr[1]); break; - case 4: $this->_set_border_radii($arr[0],$arr[1],$arr[2],$arr[3]); break; - } - } - - protected function _set_border_radii($val1, $val2, $val3, $val4) { - $this->_set_border_radius_corner($val1, "top_left"); - $this->_set_border_radius_corner($val2, "top_right"); - $this->_set_border_radius_corner($val3, "bottom_right"); - $this->_set_border_radius_corner($val4, "bottom_left"); - } - - protected function _set_border_radius_corner($val, $corner) { - $this->_has_border_radius = true; - - //see __set and __get, on all assignments clear cache! - $this->_prop_cache["border_" . $corner . "_radius"] = null; - - $this->_props["border_" . $corner . "_radius"] = $this->length_in_pt($val); - } - - /** - * Sets the outline styles - * - * @link http://www.w3.org/TR/CSS21/ui.html#dynamic-outlines - * @param string $val - */ - function set_outline($val) { - $important = isset($this->_important_props["outline"]); - - $props = array( - "outline_style", - "outline_width", - "outline_color", - ); - - foreach($props as $prop) { - $_val = self::$_defaults[$prop]; - - if ( !isset($this->_important_props[$prop]) || $important) { - //see __set and __get, on all assignments clear cache! - $this->_prop_cache[$prop] = null; - if ( $important ) { - $this->_important_props[$prop] = true; - } - $this->_props[$prop] = $_val; - } - } - - $val = preg_replace("/\s*\,\s*/", ",", $val); // when rgb() has spaces - $arr = explode(" ", $val); - foreach ($arr as $value) { - $value = trim($value); - - if ( in_array($value, self::$BORDER_STYLES) ) { - $this->set_outline_style($value); - } - else if ( preg_match("/[.0-9]+(?:px|pt|pc|em|ex|%|in|mm|cm)|(?:thin|medium|thick)/", $value ) ) { - $this->set_outline_width($value); - } - else { - // must be color - $this->set_outline_color($value); - } - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["outline"] = null; - $this->_props["outline"] = $val; - } - - function set_outline_width($val) { - $this->_set_style_type_important('outline','_width',$val); - } - - function set_outline_color($val) { - $this->_set_style_type_important('outline','_color',$val); - } - - function set_outline_style($val) { - $this->_set_style_type_important('outline','_style',$val); - } - - /** - * Sets the border spacing - * - * @link http://www.w3.org/TR/CSS21/box.html#border-properties - * @param float $val - */ - function set_border_spacing($val) { - $arr = explode(" ", $val); - - if ( count($arr) == 1 ) { - $arr[1] = $arr[0]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["border_spacing"] = null; - $this->_props["border_spacing"] = "$arr[0] $arr[1]"; - } - - /** - * Sets the list style image - * - * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image - * @param $val - */ - function set_list_style_image($val) { - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["list_style_image"] = null; - $this->_props["list_style_image"] = $this->_image($val); - } - - /** - * Sets the list style - * - * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style - * @param $val - */ - function set_list_style($val) { - $important = isset($this->_important_props["list_style"]); - $arr = explode(" ", str_replace(",", " ", $val)); - - static $types = array( - "disc", "circle", "square", - "decimal-leading-zero", "decimal", "1", - "lower-roman", "upper-roman", "a", "A", - "lower-greek", - "lower-latin", "upper-latin", - "lower-alpha", "upper-alpha", - "armenian", "georgian", "hebrew", - "cjk-ideographic", "hiragana", "katakana", - "hiragana-iroha", "katakana-iroha", "none" - ); - - static $positions = array("inside", "outside"); - - foreach ($arr as $value) { - /* http://www.w3.org/TR/CSS21/generate.html#list-style - * A value of 'none' for the 'list-style' property sets both 'list-style-type' and 'list-style-image' to 'none' - */ - if ( $value === "none" ) { - $this->_set_style("list_style_type", $value, $important); - $this->_set_style("list_style_image", $value, $important); - continue; - } - - //On setting or merging or inheriting list_style_image as well as list_style_type, - //and url exists, then url has precedence, otherwise fall back to list_style_type - //Firefox is wrong here (list_style_image gets overwritten on explicite list_style_type) - //Internet Explorer 7/8 and dompdf is right. - - if ( mb_substr($value, 0, 3) === "url" ) { - $this->_set_style("list_style_image", $this->_image($value), $important); - continue; - } - - if ( in_array($value, $types) ) { - $this->_set_style("list_style_type", $value, $important); - } - else if ( in_array($value, $positions) ) { - $this->_set_style("list_style_position", $value, $important); - } - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["list_style"] = null; - $this->_props["list_style"] = $val; - } - - function set_size($val) { - $length_re = "/(\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))/"; - - $val = mb_strtolower($val); - - if ( $val === "auto" ) { - return; - } - - $parts = preg_split("/\s+/", $val); - - $computed = array(); - if ( preg_match($length_re, $parts[0]) ) { - $computed[] = $this->length_in_pt($parts[0]); - - if ( isset($parts[1]) && preg_match($length_re, $parts[1]) ) { - $computed[] = $this->length_in_pt($parts[1]); - } - else { - $computed[] = $computed[0]; - } - } - elseif ( isset(CPDF_Adapter::$PAPER_SIZES[$parts[0]]) ) { - $computed = array_slice(CPDF_Adapter::$PAPER_SIZES[$parts[0]], 2, 2); - - if ( isset($parts[1]) && $parts[1] === "landscape" ) { - $computed = array_reverse($computed); - } - } - else { - return; - } - - $this->_props["size"] = $computed; - } - - /** - * Sets the CSS3 transform property - * - * @link http://www.w3.org/TR/css3-2d-transforms/#transform-property - * @param string $val - */ - function set_transform($val) { - $number = "\s*([^,\s]+)\s*"; - $tr_value = "\s*([^,\s]+)\s*"; - $angle = "\s*([^,\s]+(?:deg|rad)?)\s*"; - - if ( !preg_match_all("/[a-z]+\([^\)]+\)/i", $val, $parts, PREG_SET_ORDER) ) { - return; - } - - $functions = array( - //"matrix" => "\($number,$number,$number,$number,$number,$number\)", - - "translate" => "\($tr_value(?:,$tr_value)?\)", - "translateX" => "\($tr_value\)", - "translateY" => "\($tr_value\)", - - "scale" => "\($number(?:,$number)?\)", - "scaleX" => "\($number\)", - "scaleY" => "\($number\)", - - "rotate" => "\($angle\)", - - "skew" => "\($angle(?:,$angle)?\)", - "skewX" => "\($angle\)", - "skewY" => "\($angle\)", - ); - - $transforms = array(); - - foreach($parts as $part) { - $t = $part[0]; - - foreach($functions as $name => $pattern) { - if ( preg_match("/$name\s*$pattern/i", $t, $matches) ) { - $values = array_slice($matches, 1); - - switch($name) { - // units - case "rotate": - case "skew": - case "skewX": - case "skewY": - - foreach($values as $i => $value) { - if ( strpos($value, "rad") ) { - $values[$i] = rad2deg(floatval($value)); - } - else { - $values[$i] = floatval($value); - } - } - - switch($name) { - case "skew": - if ( !isset($values[1]) ) { - $values[1] = 0; - } - break; - case "skewX": - $name = "skew"; - $values = array($values[0], 0); - break; - case "skewY": - $name = "skew"; - $values = array(0, $values[0]); - break; - } - break; - - // units - case "translate": - $values[0] = $this->length_in_pt($values[0], $this->width); - - if ( isset($values[1]) ) { - $values[1] = $this->length_in_pt($values[1], $this->height); - } - else { - $values[1] = 0; - } - break; - - case "translateX": - $name = "translate"; - $values = array($this->length_in_pt($values[0], $this->width), 0); - break; - - case "translateY": - $name = "translate"; - $values = array(0, $this->length_in_pt($values[0], $this->height)); - break; - - // units - case "scale": - if ( !isset($values[1]) ) { - $values[1] = $values[0]; - } - break; - - case "scaleX": - $name = "scale"; - $values = array($values[0], 1.0); - break; - - case "scaleY": - $name = "scale"; - $values = array(1.0, $values[0]); - break; - } - - $transforms[] = array( - $name, - $values, - ); - } - } - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["transform"] = null; - $this->_props["transform"] = $transforms; - } - - function set__webkit_transform($val) { - $this->set_transform($val); - } - - function set__webkit_transform_origin($val) { - $this->set_transform_origin($val); - } - - /** - * Sets the CSS3 transform-origin property - * - * @link http://www.w3.org/TR/css3-2d-transforms/#transform-origin - * @param string $val - */ - function set_transform_origin($val) { - $values = preg_split("/\s+/", $val); - - if ( count($values) === 0) { - return; - } - - foreach($values as &$value) { - if ( in_array($value, array("top", "left")) ) { - $value = 0; - } - - if ( in_array($value, array("bottom", "right")) ) { - $value = "100%"; - } - } - - if ( !isset($values[1]) ) { - $values[1] = $values[0]; - } - - //see __set and __get, on all assignments clear cache, not needed on direct set through __set - $this->_prop_cache["transform_origin"] = null; - $this->_props["transform_origin"] = $values; - } - - protected function parse_image_resolution($val) { - // If exif data could be get: - // $re = '/^\s*(\d+|normal|auto)(?:\s*,\s*(\d+|normal))?\s*$/'; - - $re = '/^\s*(\d+|normal|auto)\s*$/'; - - if ( !preg_match($re, $val, $matches) ) { - return null; - } - - return $matches[1]; - } - - // auto | normal | dpi - function set_background_image_resolution($val) { - $parsed = $this->parse_image_resolution($val); - - $this->_prop_cache["background_image_resolution"] = null; - $this->_props["background_image_resolution"] = $parsed; - } - - // auto | normal | dpi - function set_image_resolution($val) { - $parsed = $this->parse_image_resolution($val); - - $this->_prop_cache["image_resolution"] = null; - $this->_props["image_resolution"] = $parsed; - } - - function set__dompdf_background_image_resolution($val) { - $this->set_background_image_resolution($val); - } - - function set__dompdf_image_resolution($val) { - $this->set_image_resolution($val); - } - - function set_z_index($val) { - if ( round($val) != $val && $val !== "auto" ) { - return; - } - - $this->_prop_cache["z_index"] = null; - $this->_props["z_index"] = $val; - } - - function set_counter_increment($val) { - $val = trim($val); - $value = null; - - if ( in_array($val, array("none", "inherit")) ) { - $value = $val; - } - else { - if ( preg_match_all("/(".self::CSS_IDENTIFIER.")(?:\s+(".self::CSS_INTEGER."))?/", $val, $matches, PREG_SET_ORDER) ){ - $value = array(); - foreach($matches as $match) { - $value[$match[1]] = isset($match[2]) ? $match[2] : 1; - } - } - } - - $this->_prop_cache["counter_increment"] = null; - $this->_props["counter_increment"] = $value; - } - - /** - * Generate a string representation of the Style - * - * This dumps the entire property array into a string via print_r. Useful - * for debugging. - * - * @return string - */ - /*DEBUGCSS print: see below additional debugging util*/ - function __toString() { - return print_r(array_merge(array("parent_font_size" => $this->_parent_font_size), - $this->_props), true); - } - -/*DEBUGCSS*/ function debug_print() { -/*DEBUGCSS*/ print "parent_font_size:".$this->_parent_font_size . ";\n"; -/*DEBUGCSS*/ foreach($this->_props as $prop => $val ) { -/*DEBUGCSS*/ print $prop.':'.$val; -/*DEBUGCSS*/ if (isset($this->_important_props[$prop])) { -/*DEBUGCSS*/ print '!important'; -/*DEBUGCSS*/ } -/*DEBUGCSS*/ print ";\n"; -/*DEBUGCSS*/ } -/*DEBUGCSS*/ } -} diff --git a/application/helpers/dompdf/include/stylesheet.cls.php b/application/helpers/dompdf/include/stylesheet.cls.php deleted file mode 100755 index 3b2ba3180..000000000 --- a/application/helpers/dompdf/include/stylesheet.cls.php +++ /dev/null @@ -1,1418 +0,0 @@ - - * @author Helmut Tischer - * @author Fabien Ménager - * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License - */ - -/** - * The location of the default built-in CSS file. - * {@link Stylesheet::DEFAULT_STYLESHEET} - */ -define('__DEFAULT_STYLESHEET', DOMPDF_LIB_DIR . DIRECTORY_SEPARATOR . "res" . DIRECTORY_SEPARATOR . "html.css"); - -/** - * The master stylesheet class - * - * The Stylesheet class is responsible for parsing stylesheets and style - * tags/attributes. It also acts as a registry of the individual Style - * objects generated by the current set of loaded CSS files and style - * elements. - * - * @see Style - * @package dompdf - */ -class Stylesheet { - - /** - * The location of the default built-in CSS file. - */ - const DEFAULT_STYLESHEET = __DEFAULT_STYLESHEET; - - /** - * User agent stylesheet origin - * - * @var int - */ - const ORIG_UA = 1; - - /** - * User normal stylesheet origin - * - * @var int - */ - const ORIG_USER = 2; - - /** - * Author normal stylesheet origin - * - * @var int - */ - const ORIG_AUTHOR = 3; - - private static $_stylesheet_origins = array( - self::ORIG_UA => -0x0FFFFFFF, // user agent style sheets - self::ORIG_USER => -0x0000FFFF, // user normal style sheets - self::ORIG_AUTHOR => 0x00000000, // author normal style sheets - ); - - /** - * Current dompdf instance - * - * @var DOMPDF - */ - private $_dompdf; - - /** - * Array of currently defined styles - * - * @var Style[] - */ - private $_styles; - - /** - * Base protocol of the document being parsed - * Used to handle relative urls. - * - * @var string - */ - private $_protocol; - - /** - * Base hostname of the document being parsed - * Used to handle relative urls. - * - * @var string - */ - private $_base_host; - - /** - * Base path of the document being parsed - * Used to handle relative urls. - * - * @var string - */ - private $_base_path; - - /** - * The styles defined by @page rules - * - * @var array" ).appendTo( body ); - } - - if(o.opacity) { // opacity option - if (this.helper.css("opacity")) { - this._storedOpacity = this.helper.css("opacity"); - } - this.helper.css("opacity", o.opacity); - } - - if(o.zIndex) { // zIndex option - if (this.helper.css("zIndex")) { - this._storedZIndex = this.helper.css("zIndex"); - } - this.helper.css("zIndex", o.zIndex); - } - - //Prepare scrolling - if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { - this.overflowOffset = this.scrollParent.offset(); - } - - //Call callbacks - this._trigger("start", event, this._uiHash()); - - //Recache the helper size - if(!this._preserveHelperProportions) { - this._cacheHelperProportions(); - } - - - //Post "activate" events to possible containers - if( !noActivation ) { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); - } - } - - //Prepare possible droppables - if($.ui.ddmanager) { - $.ui.ddmanager.current = this; - } - - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - - this.dragging = true; - - this.helper.addClass("ui-sortable-helper"); - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position - return true; - - }, - - _mouseDrag: function(event) { - var i, item, itemElement, intersection, - o = this.options, - scrolled = false; - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - if (!this.lastPositionAbs) { - this.lastPositionAbs = this.positionAbs; - } - - //Do scrolling - if(this.options.scroll) { - if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { - - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; - } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; - } - - if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; - } - - } else { - - if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) { - scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed); - } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) { - scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed); - } - - if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) { - scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed); - } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) { - scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed); - } - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - } - - //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); - - //Set the helper position - if(!this.options.axis || this.options.axis !== "y") { - this.helper[0].style.left = this.position.left+"px"; - } - if(!this.options.axis || this.options.axis !== "x") { - this.helper[0].style.top = this.position.top+"px"; - } - - //Rearrange - for (i = this.items.length - 1; i >= 0; i--) { - - //Cache variables and intersection, continue if no intersection - item = this.items[i]; - itemElement = item.item[0]; - intersection = this._intersectsWithPointer(item); - if (!intersection) { - continue; - } - - // Only put the placeholder inside the current Container, skip all - // items from other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this, moving items in "sub-sortables" can cause - // the placeholder to jitter between the outer and inner container. - if (item.instance !== this.currentContainer) { - continue; - } - - // cannot intersect with itself - // no useless actions that have been done before - // no action if the item moved is the parent of the item checked - if (itemElement !== this.currentItem[0] && - this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && - !$.contains(this.placeholder[0], itemElement) && - (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) - ) { - - this.direction = intersection === 1 ? "down" : "up"; - - if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { - this._rearrange(event, item); - } else { - break; - } - - this._trigger("change", event, this._uiHash()); - break; - } - } - - //Post events to containers - this._contactContainers(event); - - //Interconnect with droppables - if($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); - } - - //Call callbacks - this._trigger("sort", event, this._uiHash()); - - this.lastPositionAbs = this.positionAbs; - return false; - - }, - - _mouseStop: function(event, noPropagation) { - - if(!event) { - return; - } - - //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) { - $.ui.ddmanager.drop(this, event); - } - - if(this.options.revert) { - var that = this, - cur = this.placeholder.offset(), - axis = this.options.axis, - animation = {}; - - if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft); - } - if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop); - } - this.reverting = true; - $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { - that._clear(event); - }); - } else { - this._clear(event, noPropagation); - } - - return false; - - }, - - cancel: function() { - - if(this.dragging) { - - this._mouseUp({ target: null }); - - if(this.options.helper === "original") { - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - this.containers[i]._trigger("deactivate", null, this._uiHash(this)); - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", null, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - if (this.placeholder) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - if(this.placeholder[0].parentNode) { - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - } - if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { - this.helper.remove(); - } - - $.extend(this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - }); - - if(this.domPosition.prev) { - $(this.domPosition.prev).after(this.currentItem); - } else { - $(this.domPosition.parent).prepend(this.currentItem); - } - } - - return this; - - }, - - serialize: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected), - str = []; - o = o || {}; - - $(items).each(function() { - var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); - if (res) { - str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); - } - }); - - if(!str.length && o.key) { - str.push(o.key + "="); - } - - return str.join("&"); - - }, - - toArray: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected), - ret = []; - - o = o || {}; - - items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); - return ret; - - }, - - /* Be careful with the following core functions */ - _intersectsWith: function(item) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height, - l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height, - dyClick = this.offset.click.top, - dxClick = this.offset.click.left, - isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), - isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), - isOverElement = isOverElementHeight && isOverElementWidth; - - if ( this.options.tolerance === "pointer" || - this.options.forcePointerForContainers || - (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) - ) { - return isOverElement; - } else { - - return (l < x1 + (this.helperProportions.width / 2) && // Right Half - x2 - (this.helperProportions.width / 2) < r && // Left Half - t < y1 + (this.helperProportions.height / 2) && // Bottom Half - y2 - (this.helperProportions.height / 2) < b ); // Top Half - - } - }, - - _intersectsWithPointer: function(item) { - - var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), - isOverElement = isOverElementHeight && isOverElementWidth, - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (!isOverElement) { - return false; - } - - return this.floating ? - ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); - - }, - - _intersectsWithSides: function(item) { - - var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (this.floating && horizontalDirection) { - return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); - } else { - return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); - } - - }, - - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta !== 0 && (delta > 0 ? "down" : "up"); - }, - - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta !== 0 && (delta > 0 ? "right" : "left"); - }, - - refresh: function(event) { - this._refreshItems(event); - this._setHandleClassName(); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; - }, - - _getItemsAsjQuery: function(connected) { - - var i, j, cur, inst, - items = [], - queries = [], - connectWith = this._connectWith(); - - if(connectWith && connected) { - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i], this.document[0]); - for ( j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); - } - } - } - } - - queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); - - function addItems() { - items.push( this ); - } - for (i = queries.length - 1; i >= 0; i--){ - queries[i][0].each( addItems ); - } - - return $(items); - - }, - - _removeCurrentsFromItems: function() { - - var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); - - this.items = $.grep(this.items, function (item) { - for (var j=0; j < list.length; j++) { - if(list[j] === item.item[0]) { - return false; - } - } - return true; - }); - - }, - - _refreshItems: function(event) { - - this.items = []; - this.containers = [this]; - - var i, j, cur, inst, targetData, _queries, item, queriesLength, - items = this.items, - queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], - connectWith = this._connectWith(); - - if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i], this.document[0]); - for (j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); - this.containers.push(inst); - } - } - } - } - - for (i = queries.length - 1; i >= 0; i--) { - targetData = queries[i][1]; - _queries = queries[i][0]; - - for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { - item = $(_queries[j]); - - item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) - - items.push({ - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - }); - } - } - - }, - - refreshPositions: function(fast) { - - // Determine whether items are being displayed horizontally - this.floating = this.items.length ? - this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : - false; - - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change - if(this.offsetParent && this.helper) { - this.offset.parent = this._getParentOffset(); - } - - var i, item, t, p; - - for (i = this.items.length - 1; i >= 0; i--){ - item = this.items[i]; - - //We ignore calculating positions of all connected containers when we're not over them - if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { - continue; - } - - t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; - - if (!fast) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } - - p = t.offset(); - item.left = p.left; - item.top = p.top; - } - - if(this.options.custom && this.options.custom.refreshContainers) { - this.options.custom.refreshContainers.call(this); - } else { - for (i = this.containers.length - 1; i >= 0; i--){ - p = this.containers[i].element.offset(); - this.containers[i].containerCache.left = p.left; - this.containers[i].containerCache.top = p.top; - this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); - this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); - } - } - - return this; - }, - - _createPlaceholder: function(that) { - that = that || this; - var className, - o = that.options; - - if(!o.placeholder || o.placeholder.constructor === String) { - className = o.placeholder; - o.placeholder = { - element: function() { - - var nodeName = that.currentItem[0].nodeName.toLowerCase(), - element = $( "<" + nodeName + ">", that.document[0] ) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper"); - - if ( nodeName === "tbody" ) { - that._createTrPlaceholder( - that.currentItem.find( "tr" ).eq( 0 ), - $( "", that.document[ 0 ] ).appendTo( element ) - ); - } else if ( nodeName === "tr" ) { - that._createTrPlaceholder( that.currentItem, element ); - } else if ( nodeName === "img" ) { - element.attr( "src", that.currentItem.attr( "src" ) ); - } - - if ( !className ) { - element.css( "visibility", "hidden" ); - } - - return element; - }, - update: function(container, p) { - - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified - if(className && !o.forcePlaceholderSize) { - return; - } - - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } - if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } - } - }; - } - - //Create the placeholder - that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); - - //Append it after the actual current item - that.currentItem.after(that.placeholder); - - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update(that, that.placeholder); - - }, - - _createTrPlaceholder: function( sourceTr, targetTr ) { - var that = this; - - sourceTr.children().each(function() { - $( " ", that.document[ 0 ] ) - .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) - .appendTo( targetTr ); - }); - }, - - _contactContainers: function(event) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, - innermostContainer = null, - innermostIndex = null; - - // get innermost container that intersects with item - for (i = this.containers.length - 1; i >= 0; i--) { - - // never consider a container that's located within the item itself - if($.contains(this.currentItem[0], this.containers[i].element[0])) { - continue; - } - - if(this._intersectsWith(this.containers[i].containerCache)) { - - // if we've already found a container and it's more "inner" than this, then continue - if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { - continue; - } - - innermostContainer = this.containers[i]; - innermostIndex = i; - - } else { - // container doesn't intersect. trigger "out" event if necessary - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", event, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - // if no intersecting containers found, return - if(!innermostContainer) { - return; - } - - // move the item into the container if it's not there already - if(this.containers.length === 1) { - if (!this.containers[innermostIndex].containerCache.over) { - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - } else { - - //When entering a new container, we will find the item with the least distance and append our item near it - dist = 10000; - itemWithLeastDistance = null; - floating = innermostContainer.floating || this._isFloating(this.currentItem); - posProperty = floating ? "left" : "top"; - sizeProperty = floating ? "width" : "height"; - axis = floating ? "clientX" : "clientY"; - - for (j = this.items.length - 1; j >= 0; j--) { - if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { - continue; - } - if(this.items[j].item[0] === this.currentItem[0]) { - continue; - } - - cur = this.items[j].item.offset()[posProperty]; - nearBottom = false; - if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { - nearBottom = true; - } - - if ( Math.abs( event[ axis ] - cur ) < dist ) { - dist = Math.abs( event[ axis ] - cur ); - itemWithLeastDistance = this.items[ j ]; - this.direction = nearBottom ? "up": "down"; - } - } - - //Check if dropOnEmpty is enabled - if(!itemWithLeastDistance && !this.options.dropOnEmpty) { - return; - } - - if(this.currentContainer === this.containers[innermostIndex]) { - if ( !this.currentContainer.containerCache.over ) { - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); - this.currentContainer.containerCache.over = 1; - } - return; - } - - itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); - this.currentContainer = this.containers[innermostIndex]; - - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); - - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - - - }, - - _createHelper: function(event) { - - var o = this.options, - helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); - - //Add the helper to the DOM if that didn't happen already - if(!helper.parents("body").length) { - $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); - } - - if(helper[0] === this.currentItem[0]) { - this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; - } - - if(!helper[0].style.width || o.forceHelperSize) { - helper.width(this.currentItem.width()); - } - if(!helper[0].style.height || o.forceHelperSize) { - helper.height(this.currentItem.height()); - } - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ("left" in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ("right" in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ("top" in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ("bottom" in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - // This needs to be actually done for all browsers, since pageX/pageY includes this information - // with an ugly IE fix - if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition === "relative") { - var p = this.currentItem.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var ce, co, over, - o = this.options; - if(o.containment === "parent") { - o.containment = this.helper[0].parentNode; - } - if(o.containment === "document" || o.containment === "window") { - this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, - (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - } - - if(!(/^(document|window|parent)$/).test(o.containment)) { - ce = $(o.containment)[0]; - co = $(o.containment).offset(); - over = ($(ce).css("overflow") !== "hidden"); - - this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - ]; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) { - pos = this.position; - } - var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, - scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var top, left, - o = this.options, - pageX = event.pageX, - pageY = event.pageY, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) { - this.offset.relative = this._getRelativeOffset(); - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - - if(this.containment) { - if(event.pageX - this.offset.click.left < this.containment[0]) { - pageX = this.containment[0] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top < this.containment[1]) { - pageY = this.containment[1] + this.offset.click.top; - } - if(event.pageX - this.offset.click.left > this.containment[2]) { - pageX = this.containment[2] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top > this.containment[3]) { - pageY = this.containment[3] + this.offset.click.top; - } - } - - if(o.grid) { - top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; - pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; - pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _rearrange: function(event, i, a, hardRefresh) { - - a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); - - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var counter = this.counter; - - this._delay(function() { - if(counter === this.counter) { - this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove - } - }); - - }, - - _clear: function(event, noPropagation) { - - this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again - var i, - delayedTriggers = []; - - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem.parent().length) { - this.placeholder.before(this.currentItem); - } - this._noFinalSort = null; - - if(this.helper[0] === this.currentItem[0]) { - for(i in this._storedCSS) { - if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { - this._storedCSS[i] = ""; - } - } - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - if(this.fromOutside && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); - } - if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed - } - - // Check if the items Container has Changed and trigger appropriate - // events. - if (this !== this.currentContainer) { - if(!noPropagation) { - delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); - delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - } - } - - - //Post events to containers - function delayEvent( type, instance, container ) { - return function( event ) { - container._trigger( type, event, instance._uiHash( instance ) ); - }; - } - for (i = this.containers.length - 1; i >= 0; i--){ - if (!noPropagation) { - delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); - } - if(this.containers[i].containerCache.over) { - delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); - this.containers[i].containerCache.over = 0; - } - } - - //Do what was originally in plugins - if ( this.storedCursor ) { - this.document.find( "body" ).css( "cursor", this.storedCursor ); - this.storedStylesheet.remove(); - } - if(this._storedOpacity) { - this.helper.css("opacity", this._storedOpacity); - } - if(this._storedZIndex) { - this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); - } - - this.dragging = false; - - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - } - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - - if ( !this.cancelHelperRemoval ) { - if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { - this.helper.remove(); - } - this.helper = null; - } - - if(!noPropagation) { - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return !this.cancelHelperRemoval; - - }, - - _trigger: function() { - if ($.Widget.prototype._trigger.apply(this, arguments) === false) { - this.cancel(); - } - }, - - _uiHash: function(_inst) { - var inst = _inst || this; - return { - helper: inst.helper, - placeholder: inst.placeholder || $([]), - position: inst.position, - originalPosition: inst.originalPosition, - offset: inst.positionAbs, - item: inst.currentItem, - sender: _inst ? _inst.element : null - }; - } - -}); - - -/*! - * jQuery UI Spinner 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/spinner/ - */ - - -function spinner_modifier( fn ) { - return function() { - var previous = this.element.val(); - fn.apply( this, arguments ); - this._refresh(); - if ( previous !== this.element.val() ) { - this._trigger( "change" ); - } - }; -} - -var spinner = $.widget( "ui.spinner", { - version: "1.11.4", - defaultElement: "", - widgetEventPrefix: "spin", - options: { - culture: null, - icons: { - down: "ui-icon-triangle-1-s", - up: "ui-icon-triangle-1-n" - }, - incremental: true, - max: null, - min: null, - numberFormat: null, - page: 10, - step: 1, - - change: null, - spin: null, - start: null, - stop: null - }, - - _create: function() { - // handle string values that need to be parsed - this._setOption( "max", this.options.max ); - this._setOption( "min", this.options.min ); - this._setOption( "step", this.options.step ); - - // Only format if there is a value, prevents the field from being marked - // as invalid in Firefox, see #9573. - if ( this.value() !== "" ) { - // Format the value, but don't constrain. - this._value( this.element.val(), true ); - } - - this._draw(); - this._on( this._events ); - this._refresh(); - - // turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - }); - }, - - _getCreateOptions: function() { - var options = {}, - element = this.element; - - $.each( [ "min", "max", "step" ], function( i, option ) { - var value = element.attr( option ); - if ( value !== undefined && value.length ) { - options[ option ] = value; - } - }); - - return options; - }, - - _events: { - keydown: function( event ) { - if ( this._start( event ) && this._keydown( event ) ) { - event.preventDefault(); - } - }, - keyup: "_stop", - focus: function() { - this.previous = this.element.val(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - this._stop(); - this._refresh(); - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event ); - } - }, - mousewheel: function( event, delta ) { - if ( !delta ) { - return; - } - if ( !this.spinning && !this._start( event ) ) { - return false; - } - - this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); - clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = this._delay(function() { - if ( this.spinning ) { - this._stop( event ); - } - }, 100 ); - event.preventDefault(); - }, - "mousedown .ui-spinner-button": function( event ) { - var previous; - - // We never want the buttons to have focus; whenever the user is - // interacting with the spinner, the focus should be on the input. - // If the input is focused then this.previous is properly set from - // when the input first received focus. If the input is not focused - // then we need to set this.previous based on the value before spinning. - previous = this.element[0] === this.document[0].activeElement ? - this.previous : this.element.val(); - function checkFocus() { - var isActive = this.element[0] === this.document[0].activeElement; - if ( !isActive ) { - this.element.focus(); - this.previous = previous; - // support: IE - // IE sets focus asynchronously, so we need to check if focus - // moved off of the input because the user clicked on the button. - this._delay(function() { - this.previous = previous; - }); - } - } - - // ensure focus is on (or stays on) the text field - event.preventDefault(); - checkFocus.call( this ); - - // support: IE - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - // and check (again) if focus moved off of the input. - this.cancelBlur = true; - this._delay(function() { - delete this.cancelBlur; - checkFocus.call( this ); - }); - - if ( this._start( event ) === false ) { - return; - } - - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - "mouseup .ui-spinner-button": "_stop", - "mouseenter .ui-spinner-button": function( event ) { - // button will add ui-state-active if mouse was down while mouseleave and kept down - if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { - return; - } - - if ( this._start( event ) === false ) { - return false; - } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - // TODO: do we really want to consider this a stop? - // shouldn't we just stop the repeater and wait until mouseup before - // we trigger the stop event? - "mouseleave .ui-spinner-button": "_stop" - }, - - _draw: function() { - var uiSpinner = this.uiSpinner = this.element - .addClass( "ui-spinner-input" ) - .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) - .parent() - // add buttons - .append( this._buttonHtml() ); - - this.element.attr( "role", "spinbutton" ); - - // button bindings - this.buttons = uiSpinner.find( ".ui-spinner-button" ) - .attr( "tabIndex", -1 ) - .button() - .removeClass( "ui-corner-all" ); - - // IE 6 doesn't understand height: 50% for the buttons - // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && - uiSpinner.height() > 0 ) { - uiSpinner.height( uiSpinner.height() ); - } - - // disable spinner if element was already disabled - if ( this.options.disabled ) { - this.disable(); - } - }, - - _keydown: function( event ) { - var options = this.options, - keyCode = $.ui.keyCode; - - switch ( event.keyCode ) { - case keyCode.UP: - this._repeat( null, 1, event ); - return true; - case keyCode.DOWN: - this._repeat( null, -1, event ); - return true; - case keyCode.PAGE_UP: - this._repeat( null, options.page, event ); - return true; - case keyCode.PAGE_DOWN: - this._repeat( null, -options.page, event ); - return true; - } - - return false; - }, - - _uiSpinnerHtml: function() { - return ""; - }, - - _buttonHtml: function() { - return "" + - "" + - "" + - "" + - "" + - "" + - ""; - }, - - _start: function( event ) { - if ( !this.spinning && this._trigger( "start", event ) === false ) { - return false; - } - - if ( !this.counter ) { - this.counter = 1; - } - this.spinning = true; - return true; - }, - - _repeat: function( i, steps, event ) { - i = i || 500; - - clearTimeout( this.timer ); - this.timer = this._delay(function() { - this._repeat( 40, steps, event ); - }, i ); - - this._spin( steps * this.options.step, event ); - }, - - _spin: function( step, event ) { - var value = this.value() || 0; - - if ( !this.counter ) { - this.counter = 1; - } - - value = this._adjustValue( value + step * this._increment( this.counter ) ); - - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { - this._value( value ); - this.counter++; - } - }, - - _increment: function( i ) { - var incremental = this.options.incremental; - - if ( incremental ) { - return $.isFunction( incremental ) ? - incremental( i ) : - Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); - } - - return 1; - }, - - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, - - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, - - _adjustValue: function( value ) { - var base, aboveMin, - options = this.options; - - // make sure we're at a valid step - // - find out where we are relative to the base (min or 0) - base = options.min !== null ? options.min : 0; - aboveMin = value - base; - // - round to the nearest step - aboveMin = Math.round(aboveMin / options.step) * options.step; - // - rounding is based on 0, so adjust back to our base - value = base + aboveMin; - - // fix precision from bad JS floating point math - value = parseFloat( value.toFixed( this._precision() ) ); - - // clamp the value - if ( options.max !== null && value > options.max) { - return options.max; - } - if ( options.min !== null && value < options.min ) { - return options.min; - } - - return value; - }, - - _stop: function( event ) { - if ( !this.spinning ) { - return; - } - - clearTimeout( this.timer ); - clearTimeout( this.mousewheelTimer ); - this.counter = 0; - this.spinning = false; - this._trigger( "stop", event ); - }, - - _setOption: function( key, value ) { - if ( key === "culture" || key === "numberFormat" ) { - var prevValue = this._parse( this.element.val() ); - this.options[ key ] = value; - this.element.val( this._format( prevValue ) ); - return; - } - - if ( key === "max" || key === "min" || key === "step" ) { - if ( typeof value === "string" ) { - value = this._parse( value ); - } - } - if ( key === "icons" ) { - this.buttons.first().find( ".ui-icon" ) - .removeClass( this.options.icons.up ) - .addClass( value.up ); - this.buttons.last().find( ".ui-icon" ) - .removeClass( this.options.icons.down ) - .addClass( value.down ); - } - - this._super( key, value ); - - if ( key === "disabled" ) { - this.widget().toggleClass( "ui-state-disabled", !!value ); - this.element.prop( "disabled", !!value ); - this.buttons.button( value ? "disable" : "enable" ); - } - }, - - _setOptions: spinner_modifier(function( options ) { - this._super( options ); - }), - - _parse: function( val ) { - if ( typeof val === "string" && val !== "" ) { - val = window.Globalize && this.options.numberFormat ? - Globalize.parseFloat( val, 10, this.options.culture ) : +val; - } - return val === "" || isNaN( val ) ? null : val; - }, - - _format: function( value ) { - if ( value === "" ) { - return ""; - } - return window.Globalize && this.options.numberFormat ? - Globalize.format( value, this.options.numberFormat, this.options.culture ) : - value; - }, - - _refresh: function() { - this.element.attr({ - "aria-valuemin": this.options.min, - "aria-valuemax": this.options.max, - // TODO: what should we do with values that can't be parsed? - "aria-valuenow": this._parse( this.element.val() ) - }); - }, - - isValid: function() { - var value = this.value(); - - // null is invalid - if ( value === null ) { - return false; - } - - // if value gets adjusted, it's invalid - return value === this._adjustValue( value ); - }, - - // update the value without triggering change - _value: function( value, allowAny ) { - var parsed; - if ( value !== "" ) { - parsed = this._parse( value ); - if ( parsed !== null ) { - if ( !allowAny ) { - parsed = this._adjustValue( parsed ); - } - value = this._format( parsed ); - } - } - this.element.val( value ); - this._refresh(); - }, - - _destroy: function() { - this.element - .removeClass( "ui-spinner-input" ) - .prop( "disabled", false ) - .removeAttr( "autocomplete" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - this.uiSpinner.replaceWith( this.element ); - }, - - stepUp: spinner_modifier(function( steps ) { - this._stepUp( steps ); - }), - _stepUp: function( steps ) { - if ( this._start() ) { - this._spin( (steps || 1) * this.options.step ); - this._stop(); - } - }, - - stepDown: spinner_modifier(function( steps ) { - this._stepDown( steps ); - }), - _stepDown: function( steps ) { - if ( this._start() ) { - this._spin( (steps || 1) * -this.options.step ); - this._stop(); - } - }, - - pageUp: spinner_modifier(function( pages ) { - this._stepUp( (pages || 1) * this.options.page ); - }), - - pageDown: spinner_modifier(function( pages ) { - this._stepDown( (pages || 1) * this.options.page ); - }), - - value: function( newVal ) { - if ( !arguments.length ) { - return this._parse( this.element.val() ); - } - spinner_modifier( this._value ).call( this, newVal ); - }, - - widget: function() { - return this.uiSpinner; - } -}); - - -/*! - * jQuery UI Tabs 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/tabs/ - */ - - -var tabs = $.widget( "ui.tabs", { - version: "1.11.4", - delay: 300, - options: { - active: null, - collapsible: false, - event: "click", - heightStyle: "content", - hide: null, - show: null, - - // callbacks - activate: null, - beforeActivate: null, - beforeLoad: null, - load: null - }, - - _isLocal: (function() { - var rhash = /#.*$/; - - return function( anchor ) { - var anchorUrl, locationUrl; - - // support: IE7 - // IE7 doesn't normalize the href property when set via script (#9317) - anchor = anchor.cloneNode( false ); - - anchorUrl = anchor.href.replace( rhash, "" ); - locationUrl = location.href.replace( rhash, "" ); - - // decoding may throw an error if the URL isn't UTF-8 (#9518) - try { - anchorUrl = decodeURIComponent( anchorUrl ); - } catch ( error ) {} - try { - locationUrl = decodeURIComponent( locationUrl ); - } catch ( error ) {} - - return anchor.hash.length > 1 && anchorUrl === locationUrl; - }; - })(), - - _create: function() { - var that = this, - options = this.options; - - this.running = false; - - this.element - .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-tabs-collapsible", options.collapsible ); - - this._processTabs(); - options.active = this._initialActive(); - - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - if ( $.isArray( options.disabled ) ) { - options.disabled = $.unique( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); - }) - ) ).sort(); - } - - // check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( options.active ); - } else { - this.active = $(); - } - - this._refresh(); - - if ( this.active.length ) { - this.load( options.active ); - } - }, - - _initialActive: function() { - var active = this.options.active, - collapsible = this.options.collapsible, - locationHash = location.hash.substring( 1 ); - - if ( active === null ) { - // check the fragment identifier in the URL - if ( locationHash ) { - this.tabs.each(function( i, tab ) { - if ( $( tab ).attr( "aria-controls" ) === locationHash ) { - active = i; - return false; - } - }); - } - - // check for a tab marked active via a class - if ( active === null ) { - active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); - } - - // no active tab, set to false - if ( active === null || active === -1 ) { - active = this.tabs.length ? 0 : false; - } - } - - // handle numbers: negative, out of range - if ( active !== false ) { - active = this.tabs.index( this.tabs.eq( active ) ); - if ( active === -1 ) { - active = collapsible ? false : 0; - } - } - - // don't allow collapsible: false and active: false - if ( !collapsible && active === false && this.anchors.length ) { - active = 0; - } - - return active; - }, - - _getCreateEventData: function() { - return { - tab: this.active, - panel: !this.active.length ? $() : this._getPanelForTab( this.active ) - }; - }, - - _tabKeydown: function( event ) { - var focusedTab = $( this.document[0].activeElement ).closest( "li" ), - selectedIndex = this.tabs.index( focusedTab ), - goingForward = true; - - if ( this._handlePageNav( event ) ) { - return; - } - - switch ( event.keyCode ) { - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - selectedIndex++; - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.LEFT: - goingForward = false; - selectedIndex--; - break; - case $.ui.keyCode.END: - selectedIndex = this.anchors.length - 1; - break; - case $.ui.keyCode.HOME: - selectedIndex = 0; - break; - case $.ui.keyCode.SPACE: - // Activate only, no collapsing - event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); - return; - case $.ui.keyCode.ENTER: - // Toggle (cancel delayed activation, allow collapsing) - event.preventDefault(); - clearTimeout( this.activating ); - // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); - return; - default: - return; - } - - // Focus the appropriate tab, based on which key was pressed - event.preventDefault(); - clearTimeout( this.activating ); - selectedIndex = this._focusNextTab( selectedIndex, goingForward ); - - // Navigating with control/command key will prevent automatic activation - if ( !event.ctrlKey && !event.metaKey ) { - - // Update aria-selected immediately so that AT think the tab is already selected. - // Otherwise AT may confuse the user by stating that they need to activate the tab, - // but the tab will already be activated by the time the announcement finishes. - focusedTab.attr( "aria-selected", "false" ); - this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); - - this.activating = this._delay(function() { - this.option( "active", selectedIndex ); - }, this.delay ); - } - }, - - _panelKeydown: function( event ) { - if ( this._handlePageNav( event ) ) { - return; - } - - // Ctrl+up moves focus to the current tab - if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { - event.preventDefault(); - this.active.focus(); - } - }, - - // Alt+page up/down moves focus to the previous/next tab (and activates) - _handlePageNav: function( event ) { - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { - this._activate( this._focusNextTab( this.options.active - 1, false ) ); - return true; - } - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { - this._activate( this._focusNextTab( this.options.active + 1, true ) ); - return true; - } - }, - - _findNextTab: function( index, goingForward ) { - var lastTabIndex = this.tabs.length - 1; - - function constrain() { - if ( index > lastTabIndex ) { - index = 0; - } - if ( index < 0 ) { - index = lastTabIndex; - } - return index; - } - - while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { - index = goingForward ? index + 1 : index - 1; - } - - return index; - }, - - _focusNextTab: function( index, goingForward ) { - index = this._findNextTab( index, goingForward ); - this.tabs.eq( index ).focus(); - return index; - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "disabled" ) { - // don't use the widget factory's disabled handling - this._setupDisabled( value ); - return; - } - - this._super( key, value); - - if ( key === "collapsible" ) { - this.element.toggleClass( "ui-tabs-collapsible", value ); - // Setting collapsible: false while collapsed; open first panel - if ( !value && this.options.active === false ) { - this._activate( 0 ); - } - } - - if ( key === "event" ) { - this._setupEvents( value ); - } - - if ( key === "heightStyle" ) { - this._setupHeightStyle( value ); - } - }, - - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; - }, - - refresh: function() { - var options = this.options, - lis = this.tablist.children( ":has(a[href])" ); - - // get disabled tabs from class attribute from HTML - // this will get converted to a boolean if needed in _refresh() - options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { - return lis.index( tab ); - }); - - this._processTabs(); - - // was collapsed or no tabs - if ( options.active === false || !this.anchors.length ) { - options.active = false; - this.active = $(); - // was active, but active tab is gone - } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { - // all remaining tabs are disabled - if ( this.tabs.length === options.disabled.length ) { - options.active = false; - this.active = $(); - // activate previous tab - } else { - this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); - } - // was active, active tab still exists - } else { - // make sure active index is correct - options.active = this.tabs.index( this.active ); - } - - this._refresh(); - }, - - _refresh: function() { - this._setupDisabled( this.options.disabled ); - this._setupEvents( this.options.event ); - this._setupHeightStyle( this.options.heightStyle ); - - this.tabs.not( this.active ).attr({ - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - }); - this.panels.not( this._getPanelForTab( this.active ) ) - .hide() - .attr({ - "aria-hidden": "true" - }); - - // Make sure one tab is in the tab order - if ( !this.active.length ) { - this.tabs.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active - .addClass( "ui-tabs-active ui-state-active" ) - .attr({ - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - }); - this._getPanelForTab( this.active ) - .show() - .attr({ - "aria-hidden": "false" - }); - } - }, - - _processTabs: function() { - var that = this, - prevTabs = this.tabs, - prevAnchors = this.anchors, - prevPanels = this.panels; - - this.tablist = this._getList() - .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .attr( "role", "tablist" ) - - // Prevent users from focusing disabled tabs via click - .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { - event.preventDefault(); - } - }) - - // support: IE <9 - // Preventing the default action in mousedown doesn't prevent IE - // from focusing the element, so if the anchor gets focused, blur. - // We don't have to worry about focusing the previously focused - // element since clicking on a non-focusable element should focus - // the body anyway. - .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { - this.blur(); - } - }); - - this.tabs = this.tablist.find( "> li:has(a[href])" ) - .addClass( "ui-state-default ui-corner-top" ) - .attr({ - role: "tab", - tabIndex: -1 - }); - - this.anchors = this.tabs.map(function() { - return $( "a", this )[ 0 ]; - }) - .addClass( "ui-tabs-anchor" ) - .attr({ - role: "presentation", - tabIndex: -1 - }); - - this.panels = $(); - - this.anchors.each(function( i, anchor ) { - var selector, panel, panelId, - anchorId = $( anchor ).uniqueId().attr( "id" ), - tab = $( anchor ).closest( "li" ), - originalAriaControls = tab.attr( "aria-controls" ); - - // inline tab - if ( that._isLocal( anchor ) ) { - selector = anchor.hash; - panelId = selector.substring( 1 ); - panel = that.element.find( that._sanitizeSelector( selector ) ); - // remote tab - } else { - // If the tab doesn't already have aria-controls, - // generate an id by using a throw-away element - panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; - selector = "#" + panelId; - panel = that.element.find( selector ); - if ( !panel.length ) { - panel = that._createPanel( panelId ); - panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); - } - panel.attr( "aria-live", "polite" ); - } - - if ( panel.length) { - that.panels = that.panels.add( panel ); - } - if ( originalAriaControls ) { - tab.data( "ui-tabs-aria-controls", originalAriaControls ); - } - tab.attr({ - "aria-controls": panelId, - "aria-labelledby": anchorId - }); - panel.attr( "aria-labelledby", anchorId ); - }); - - this.panels - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .attr( "role", "tabpanel" ); - - // Avoid memory leaks (#10056) - if ( prevTabs ) { - this._off( prevTabs.not( this.tabs ) ); - this._off( prevAnchors.not( this.anchors ) ); - this._off( prevPanels.not( this.panels ) ); - } - }, - - // allow overriding how to find the list for rare usage scenarios (#7715) - _getList: function() { - return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); - }, - - _createPanel: function( id ) { - return $( "
" ) - .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .data( "ui-tabs-destroy", true ); - }, - - _setupDisabled: function( disabled ) { - if ( $.isArray( disabled ) ) { - if ( !disabled.length ) { - disabled = false; - } else if ( disabled.length === this.anchors.length ) { - disabled = true; - } - } - - // disable tabs - for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { - if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - $( li ) - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } else { - $( li ) - .removeClass( "ui-state-disabled" ) - .removeAttr( "aria-disabled" ); - } - } - - this.options.disabled = disabled; - }, - - _setupEvents: function( event ) { - var events = {}; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - } - - this._off( this.anchors.add( this.tabs ).add( this.panels ) ); - // Always prevent the default action, even when disabled - this._on( true, this.anchors, { - click: function( event ) { - event.preventDefault(); - } - }); - this._on( this.anchors, events ); - this._on( this.tabs, { keydown: "_tabKeydown" } ); - this._on( this.panels, { keydown: "_panelKeydown" } ); - - this._focusable( this.tabs ); - this._hoverable( this.tabs ); - }, - - _setupHeightStyle: function( heightStyle ) { - var maxHeight, - parent = this.element.parent(); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - maxHeight -= this.element.outerHeight() - this.element.height(); - - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - - this.element.children().not( this.panels ).each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.panels.each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.panels.each(function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - }).height( maxHeight ); - } - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - anchor = $( event.currentTarget ), - tab = anchor.closest( "li" ), - clickedIsActive = tab[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : this._getPanelForTab( tab ), - toHide = !active.length ? $() : this._getPanelForTab( active ), - eventData = { - oldTab: active, - oldPanel: toHide, - newTab: collapsing ? $() : tab, - newPanel: toShow - }; - - event.preventDefault(); - - if ( tab.hasClass( "ui-state-disabled" ) || - // tab is already loading - tab.hasClass( "ui-tabs-loading" ) || - // can't switch durning an animation - this.running || - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.tabs.index( tab ); - - this.active = clickedIsActive ? $() : tab; - if ( this.xhr ) { - this.xhr.abort(); - } - - if ( !toHide.length && !toShow.length ) { - $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); - } - - if ( toShow.length ) { - this.load( this.tabs.index( tab ), event ); - } - this._toggle( event, eventData ); - }, - - // handles show/hide for selecting tabs - _toggle: function( event, eventData ) { - var that = this, - toShow = eventData.newPanel, - toHide = eventData.oldPanel; - - this.running = true; - - function complete() { - that.running = false; - that._trigger( "activate", event, eventData ); - } - - function show() { - eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); - - if ( toShow.length && that.options.show ) { - that._show( toShow, that.options.show, complete ); - } else { - toShow.show(); - complete(); - } - } - - // start out by hiding, then showing, then completing - if ( toHide.length && this.options.hide ) { - this._hide( toHide, this.options.hide, function() { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - show(); - }); - } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); - toHide.hide(); - show(); - } - - toHide.attr( "aria-hidden", "true" ); - eventData.oldTab.attr({ - "aria-selected": "false", - "aria-expanded": "false" - }); - // If we're switching tabs, remove the old tab from the tab order. - // If we're opening from collapsed state, remove the previous tab from the tab order. - // If we're collapsing, then keep the collapsing tab in the tab order. - if ( toShow.length && toHide.length ) { - eventData.oldTab.attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.tabs.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow.attr( "aria-hidden", "false" ); - eventData.newTab.attr({ - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - }); - }, - - _activate: function( index ) { - var anchor, - active = this._findActive( index ); - - // trying to activate the already active panel - if ( active[ 0 ] === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the current active header - if ( !active.length ) { - active = this.active; - } - - anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; - this._eventHandler({ - target: anchor, - currentTarget: anchor, - preventDefault: $.noop - }); - }, - - _findActive: function( index ) { - return index === false ? $() : this.tabs.eq( index ); - }, - - _getIndex: function( index ) { - // meta-function to give users option to provide a href string instead of a numerical index. - if ( typeof index === "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); - } - - return index; - }, - - _destroy: function() { - if ( this.xhr ) { - this.xhr.abort(); - } - - this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); - - this.tablist - .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .removeAttr( "role" ); - - this.anchors - .removeClass( "ui-tabs-anchor" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeUniqueId(); - - this.tablist.unbind( this.eventNamespace ); - - this.tabs.add( this.panels ).each(function() { - if ( $.data( this, "ui-tabs-destroy" ) ) { - $( this ).remove(); - } else { - $( this ) - .removeClass( "ui-state-default ui-state-active ui-state-disabled " + - "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-live" ) - .removeAttr( "aria-busy" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "role" ); - } - }); - - this.tabs.each(function() { - var li = $( this ), - prev = li.data( "ui-tabs-aria-controls" ); - if ( prev ) { - li - .attr( "aria-controls", prev ) - .removeData( "ui-tabs-aria-controls" ); - } else { - li.removeAttr( "aria-controls" ); - } - }); - - this.panels.show(); - - if ( this.options.heightStyle !== "content" ) { - this.panels.css( "height", "" ); - } - }, - - enable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === false ) { - return; - } - - if ( index === undefined ) { - disabled = false; - } else { - index = this._getIndex( index ); - if ( $.isArray( disabled ) ) { - disabled = $.map( disabled, function( num ) { - return num !== index ? num : null; - }); - } else { - disabled = $.map( this.tabs, function( li, num ) { - return num !== index ? num : null; - }); - } - } - this._setupDisabled( disabled ); - }, - - disable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === true ) { - return; - } - - if ( index === undefined ) { - disabled = true; - } else { - index = this._getIndex( index ); - if ( $.inArray( index, disabled ) !== -1 ) { - return; - } - if ( $.isArray( disabled ) ) { - disabled = $.merge( [ index ], disabled ).sort(); - } else { - disabled = [ index ]; - } - } - this._setupDisabled( disabled ); - }, - - load: function( index, event ) { - index = this._getIndex( index ); - var that = this, - tab = this.tabs.eq( index ), - anchor = tab.find( ".ui-tabs-anchor" ), - panel = this._getPanelForTab( tab ), - eventData = { - tab: tab, - panel: panel - }, - complete = function( jqXHR, status ) { - if ( status === "abort" ) { - that.panels.stop( false, true ); - } - - tab.removeClass( "ui-tabs-loading" ); - panel.removeAttr( "aria-busy" ); - - if ( jqXHR === that.xhr ) { - delete that.xhr; - } - }; - - // not remote - if ( this._isLocal( anchor[ 0 ] ) ) { - return; - } - - this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - - // support: jQuery <1.8 - // jQuery <1.8 returns false if the request is canceled in beforeSend, - // but as of 1.8, $.ajax() always returns a jqXHR object. - if ( this.xhr && this.xhr.statusText !== "canceled" ) { - tab.addClass( "ui-tabs-loading" ); - panel.attr( "aria-busy", "true" ); - - this.xhr - .done(function( response, status, jqXHR ) { - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - panel.html( response ); - that._trigger( "load", event, eventData ); - - complete( jqXHR, status ); - }, 1 ); - }) - .fail(function( jqXHR, status ) { - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - complete( jqXHR, status ); - }, 1 ); - }); - } - }, - - _ajaxSettings: function( anchor, event, eventData ) { - var that = this; - return { - url: anchor.attr( "href" ), - beforeSend: function( jqXHR, settings ) { - return that._trigger( "beforeLoad", event, - $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); - } - }; - }, - - _getPanelForTab: function( tab ) { - var id = $( tab ).attr( "aria-controls" ); - return this.element.find( this._sanitizeSelector( "#" + id ) ); - } -}); - - -/*! - * jQuery UI Tooltip 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/tooltip/ - */ - - -var tooltip = $.widget( "ui.tooltip", { - version: "1.11.4", - options: { - content: function() { - // support: IE<9, Opera in jQuery <1.7 - // .text() can't accept undefined, so coerce to a string - var title = $( this ).attr( "title" ) || ""; - // Escape title, since we're going from an attribute to raw HTML - return $( "" ).text( title ).html(); - }, - hide: true, - // Disabled elements have inconsistent behavior across browsers (#8661) - items: "[title]:not([disabled])", - position: { - my: "left top+15", - at: "left bottom", - collision: "flipfit flip" - }, - show: true, - tooltipClass: null, - track: false, - - // callbacks - close: null, - open: null - }, - - _addDescribedBy: function( elem, id ) { - var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); - describedby.push( id ); - elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); - }, - - _removeDescribedBy: function( elem ) { - var id = elem.data( "ui-tooltip-id" ), - describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), - index = $.inArray( id, describedby ); - - if ( index !== -1 ) { - describedby.splice( index, 1 ); - } - - elem.removeData( "ui-tooltip-id" ); - describedby = $.trim( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); - } else { - elem.removeAttr( "aria-describedby" ); - } - }, - - _create: function() { - this._on({ - mouseover: "open", - focusin: "open" - }); - - // IDs of generated tooltips, needed for destroy - this.tooltips = {}; - - // IDs of parent tooltips where we removed the title attribute - this.parents = {}; - - if ( this.options.disabled ) { - this._disable(); - } - - // Append the aria-live region so tooltips announce correctly - this.liveRegion = $( "
" ) - .attr({ - role: "log", - "aria-live": "assertive", - "aria-relevant": "additions" - }) - .addClass( "ui-helper-hidden-accessible" ) - .appendTo( this.document[ 0 ].body ); - }, - - _setOption: function( key, value ) { - var that = this; - - if ( key === "disabled" ) { - this[ value ? "_disable" : "_enable" ](); - this.options[ key ] = value; - // disable element style changes - return; - } - - this._super( key, value ); - - if ( key === "content" ) { - $.each( this.tooltips, function( id, tooltipData ) { - that._updateContent( tooltipData.element ); - }); - } - }, - - _disable: function() { - var that = this; - - // close open tooltips - $.each( this.tooltips, function( id, tooltipData ) { - var event = $.Event( "blur" ); - event.target = event.currentTarget = tooltipData.element[ 0 ]; - that.close( event, true ); - }); - - // remove title attributes to prevent native tooltips - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { - element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .removeAttr( "title" ); - } - }); - }, - - _enable: function() { - // restore title attributes - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - } - }); - }, - - open: function( event ) { - var that = this, - target = $( event ? event.target : this.element ) - // we need closest here due to mouseover bubbling, - // but always pointing at the same event target - .closest( this.options.items ); - - // No element to show a tooltip for or the tooltip is already open - if ( !target.length || target.data( "ui-tooltip-id" ) ) { - return; - } - - if ( target.attr( "title" ) ) { - target.data( "ui-tooltip-title", target.attr( "title" ) ); - } - - target.data( "ui-tooltip-open", true ); - - // kill parent tooltips, custom or native, for hover - if ( event && event.type === "mouseover" ) { - target.parents().each(function() { - var parent = $( this ), - blurEvent; - if ( parent.data( "ui-tooltip-open" ) ) { - blurEvent = $.Event( "blur" ); - blurEvent.target = blurEvent.currentTarget = this; - that.close( blurEvent, true ); - } - if ( parent.attr( "title" ) ) { - parent.uniqueId(); - that.parents[ this.id ] = { - element: this, - title: parent.attr( "title" ) - }; - parent.attr( "title", "" ); - } - }); - } - - this._registerCloseHandlers( event, target ); - this._updateContent( target, event ); - }, - - _updateContent: function( target, event ) { - var content, - contentOption = this.options.content, - that = this, - eventType = event ? event.type : null; - - if ( typeof contentOption === "string" ) { - return this._open( event, target, contentOption ); - } - - content = contentOption.call( target[0], function( response ) { - - // IE may instantly serve a cached response for ajax requests - // delay this call to _open so the other call to _open runs first - that._delay(function() { - - // Ignore async response if tooltip was closed already - if ( !target.data( "ui-tooltip-open" ) ) { - return; - } - - // jQuery creates a special event for focusin when it doesn't - // exist natively. To improve performance, the native event - // object is reused and the type is changed. Therefore, we can't - // rely on the type being correct after the event finished - // bubbling, so we set it back to the previous value. (#8740) - if ( event ) { - event.type = eventType; - } - this._open( event, target, response ); - }); - }); - if ( content ) { - this._open( event, target, content ); - } - }, - - _open: function( event, target, content ) { - var tooltipData, tooltip, delayedShow, a11yContent, - positionOption = $.extend( {}, this.options.position ); - - if ( !content ) { - return; - } - - // Content can be updated multiple times. If the tooltip already - // exists, then just update the content and bail. - tooltipData = this._find( target ); - if ( tooltipData ) { - tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); - return; - } - - // if we have a title, clear it to prevent the native tooltip - // we have to check first to avoid defining a title if none exists - // (we don't want to cause an element to start matching [title]) - // - // We use removeAttr only for key events, to allow IE to export the correct - // accessible attributes. For mouse events, set to empty string to avoid - // native tooltip showing up (happens only when removing inside mouseover). - if ( target.is( "[title]" ) ) { - if ( event && event.type === "mouseover" ) { - target.attr( "title", "" ); - } else { - target.removeAttr( "title" ); - } - } - - tooltipData = this._tooltip( target ); - tooltip = tooltipData.tooltip; - this._addDescribedBy( target, tooltip.attr( "id" ) ); - tooltip.find( ".ui-tooltip-content" ).html( content ); - - // Support: Voiceover on OS X, JAWS on IE <= 9 - // JAWS announces deletions even when aria-relevant="additions" - // Voiceover will sometimes re-read the entire log region's contents from the beginning - this.liveRegion.children().hide(); - if ( content.clone ) { - a11yContent = content.clone(); - a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); - } else { - a11yContent = content; - } - $( "
" ).html( a11yContent ).appendTo( this.liveRegion ); - - function position( event ) { - positionOption.of = event; - if ( tooltip.is( ":hidden" ) ) { - return; - } - tooltip.position( positionOption ); - } - if ( this.options.track && event && /^mouse/.test( event.type ) ) { - this._on( this.document, { - mousemove: position - }); - // trigger once to override element-relative positioning - position( event ); - } else { - tooltip.position( $.extend({ - of: target - }, this.options.position ) ); - } - - tooltip.hide(); - - this._show( tooltip, this.options.show ); - // Handle tracking tooltips that are shown with a delay (#8644). As soon - // as the tooltip is visible, position the tooltip using the most recent - // event. - if ( this.options.show && this.options.show.delay ) { - delayedShow = this.delayedShow = setInterval(function() { - if ( tooltip.is( ":visible" ) ) { - position( positionOption.of ); - clearInterval( delayedShow ); - } - }, $.fx.interval ); - } - - this._trigger( "open", event, { tooltip: tooltip } ); - }, - - _registerCloseHandlers: function( event, target ) { - var events = { - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE ) { - var fakeEvent = $.Event(event); - fakeEvent.currentTarget = target[0]; - this.close( fakeEvent, true ); - } - } - }; - - // Only bind remove handler for delegated targets. Non-delegated - // tooltips will handle this in destroy. - if ( target[ 0 ] !== this.element[ 0 ] ) { - events.remove = function() { - this._removeTooltip( this._find( target ).tooltip ); - }; - } - - if ( !event || event.type === "mouseover" ) { - events.mouseleave = "close"; - } - if ( !event || event.type === "focusin" ) { - events.focusout = "close"; - } - this._on( true, target, events ); - }, - - close: function( event ) { - var tooltip, - that = this, - target = $( event ? event.currentTarget : this.element ), - tooltipData = this._find( target ); - - // The tooltip may already be closed - if ( !tooltipData ) { - - // We set ui-tooltip-open immediately upon open (in open()), but only set the - // additional data once there's actually content to show (in _open()). So even if the - // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in - // the period between open() and _open(). - target.removeData( "ui-tooltip-open" ); - return; - } - - tooltip = tooltipData.tooltip; - - // disabling closes the tooltip, so we need to track when we're closing - // to avoid an infinite loop in case the tooltip becomes disabled on close - if ( tooltipData.closing ) { - return; - } - - // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); - - // only set title if we had one before (see comment in _open()) - // If the title attribute has changed since open(), don't restore - if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { - target.attr( "title", target.data( "ui-tooltip-title" ) ); - } - - this._removeDescribedBy( target ); - - tooltipData.hiding = true; - tooltip.stop( true ); - this._hide( tooltip, this.options.hide, function() { - that._removeTooltip( $( this ) ); - }); - - target.removeData( "ui-tooltip-open" ); - this._off( target, "mouseleave focusout keyup" ); - - // Remove 'remove' binding only on delegated targets - if ( target[ 0 ] !== this.element[ 0 ] ) { - this._off( target, "remove" ); - } - this._off( this.document, "mousemove" ); - - if ( event && event.type === "mouseleave" ) { - $.each( this.parents, function( id, parent ) { - $( parent.element ).attr( "title", parent.title ); - delete that.parents[ id ]; - }); - } - - tooltipData.closing = true; - this._trigger( "close", event, { tooltip: tooltip } ); - if ( !tooltipData.hiding ) { - tooltipData.closing = false; - } - }, - - _tooltip: function( element ) { - var tooltip = $( "
" ) - .attr( "role", "tooltip" ) - .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ), - id = tooltip.uniqueId().attr( "id" ); - - $( "
" ) - .addClass( "ui-tooltip-content" ) - .appendTo( tooltip ); - - tooltip.appendTo( this.document[0].body ); - - return this.tooltips[ id ] = { - element: element, - tooltip: tooltip - }; - }, - - _find: function( target ) { - var id = target.data( "ui-tooltip-id" ); - return id ? this.tooltips[ id ] : null; - }, - - _removeTooltip: function( tooltip ) { - tooltip.remove(); - delete this.tooltips[ tooltip.attr( "id" ) ]; - }, - - _destroy: function() { - var that = this; - - // close open tooltips - $.each( this.tooltips, function( id, tooltipData ) { - // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ), - element = tooltipData.element; - event.target = event.currentTarget = element[ 0 ]; - that.close( event, true ); - - // Remove immediately; destroying an open tooltip doesn't use the - // hide animation - $( "#" + id ).remove(); - - // Restore the title - if ( element.data( "ui-tooltip-title" ) ) { - // If the title attribute has changed since open(), don't restore - if ( !element.attr( "title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - } - element.removeData( "ui-tooltip-title" ); - } - }); - this.liveRegion.remove(); - } -}); - - - -})); -/*! - * jQuery Validation Plugin v1.13.1 - * - * http://jqueryvalidation.org/ - * - * Copyright (c) 2014 Jörn Zaefferer - * Released under the MIT license - */ -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - define( ["jquery"], factory ); - } else { - factory( jQuery ); - } -}(function( $ ) { - -$.extend($.fn, { - // http://jqueryvalidation.org/validate/ - validate: function( options ) { - - // if nothing is selected, return nothing; can't chain anyway - if ( !this.length ) { - if ( options && options.debug && window.console ) { - console.warn( "Nothing selected, can't validate, returning nothing." ); - } - return; - } - - // check if a validator for this form was already created - var validator = $.data( this[ 0 ], "validator" ); - if ( validator ) { - return validator; - } - - // Add novalidate tag if HTML5. - this.attr( "novalidate", "novalidate" ); - - validator = new $.validator( options, this[ 0 ] ); - $.data( this[ 0 ], "validator", validator ); - - if ( validator.settings.onsubmit ) { - - this.validateDelegate( ":submit", "click", function( event ) { - if ( validator.settings.submitHandler ) { - validator.submitButton = event.target; - } - // allow suppressing validation by adding a cancel class to the submit button - if ( $( event.target ).hasClass( "cancel" ) ) { - validator.cancelSubmit = true; - } - - // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button - if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) { - validator.cancelSubmit = true; - } - }); - - // validate the form on submit - this.submit( function( event ) { - if ( validator.settings.debug ) { - // prevent form submit to be able to see console output - event.preventDefault(); - } - function handle() { - var hidden, result; - if ( validator.settings.submitHandler ) { - if ( validator.submitButton ) { - // insert a hidden input as a replacement for the missing submit button - hidden = $( "" ) - .attr( "name", validator.submitButton.name ) - .val( $( validator.submitButton ).val() ) - .appendTo( validator.currentForm ); - } - result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); - if ( validator.submitButton ) { - // and clean up afterwards; thanks to no-block-scope, hidden can be referenced - hidden.remove(); - } - if ( result !== undefined ) { - return result; - } - return false; - } - return true; - } - - // prevent submit for invalid forms or custom submit handlers - if ( validator.cancelSubmit ) { - validator.cancelSubmit = false; - return handle(); - } - if ( validator.form() ) { - if ( validator.pendingRequest ) { - validator.formSubmitted = true; - return false; - } - return handle(); - } else { - validator.focusInvalid(); - return false; - } - }); - } - - return validator; - }, - // http://jqueryvalidation.org/valid/ - valid: function() { - var valid, validator; - - if ( $( this[ 0 ] ).is( "form" ) ) { - valid = this.validate().form(); - } else { - valid = true; - validator = $( this[ 0 ].form ).validate(); - this.each( function() { - valid = validator.element( this ) && valid; - }); - } - return valid; - }, - // attributes: space separated list of attributes to retrieve and remove - removeAttrs: function( attributes ) { - var result = {}, - $element = this; - $.each( attributes.split( /\s/ ), function( index, value ) { - result[ value ] = $element.attr( value ); - $element.removeAttr( value ); - }); - return result; - }, - // http://jqueryvalidation.org/rules/ - rules: function( command, argument ) { - var element = this[ 0 ], - settings, staticRules, existingRules, data, param, filtered; - - if ( command ) { - settings = $.data( element.form, "validator" ).settings; - staticRules = settings.rules; - existingRules = $.validator.staticRules( element ); - switch ( command ) { - case "add": - $.extend( existingRules, $.validator.normalizeRule( argument ) ); - // remove messages from rules, but allow them to be set separately - delete existingRules.messages; - staticRules[ element.name ] = existingRules; - if ( argument.messages ) { - settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); - } - break; - case "remove": - if ( !argument ) { - delete staticRules[ element.name ]; - return existingRules; - } - filtered = {}; - $.each( argument.split( /\s/ ), function( index, method ) { - filtered[ method ] = existingRules[ method ]; - delete existingRules[ method ]; - if ( method === "required" ) { - $( element ).removeAttr( "aria-required" ); - } - }); - return filtered; - } - } - - data = $.validator.normalizeRules( - $.extend( - {}, - $.validator.classRules( element ), - $.validator.attributeRules( element ), - $.validator.dataRules( element ), - $.validator.staticRules( element ) - ), element ); - - // make sure required is at front - if ( data.required ) { - param = data.required; - delete data.required; - data = $.extend( { required: param }, data ); - $( element ).attr( "aria-required", "true" ); - } - - // make sure remote is at back - if ( data.remote ) { - param = data.remote; - delete data.remote; - data = $.extend( data, { remote: param }); - } - - return data; - } -}); - -// Custom selectors -$.extend( $.expr[ ":" ], { - // http://jqueryvalidation.org/blank-selector/ - blank: function( a ) { - return !$.trim( "" + $( a ).val() ); - }, - // http://jqueryvalidation.org/filled-selector/ - filled: function( a ) { - return !!$.trim( "" + $( a ).val() ); - }, - // http://jqueryvalidation.org/unchecked-selector/ - unchecked: function( a ) { - return !$( a ).prop( "checked" ); - } -}); - -// constructor for validator -$.validator = function( options, form ) { - this.settings = $.extend( true, {}, $.validator.defaults, options ); - this.currentForm = form; - this.init(); -}; - -// http://jqueryvalidation.org/jQuery.validator.format/ -$.validator.format = function( source, params ) { - if ( arguments.length === 1 ) { - return function() { - var args = $.makeArray( arguments ); - args.unshift( source ); - return $.validator.format.apply( this, args ); - }; - } - if ( arguments.length > 2 && params.constructor !== Array ) { - params = $.makeArray( arguments ).slice( 1 ); - } - if ( params.constructor !== Array ) { - params = [ params ]; - } - $.each( params, function( i, n ) { - source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { - return n; - }); - }); - return source; -}; - -$.extend( $.validator, { - - defaults: { - messages: {}, - groups: {}, - rules: {}, - errorClass: "error", - validClass: "valid", - errorElement: "label", - focusCleanup: false, - focusInvalid: true, - errorContainer: $( [] ), - errorLabelContainer: $( [] ), - onsubmit: true, - ignore: ":hidden", - ignoreTitle: false, - onfocusin: function( element ) { - this.lastActive = element; - - // Hide error label and remove error class on focus if enabled - if ( this.settings.focusCleanup ) { - if ( this.settings.unhighlight ) { - this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); - } - this.hideThese( this.errorsFor( element ) ); - } - }, - onfocusout: function( element ) { - if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { - this.element( element ); - } - }, - onkeyup: function( element, event ) { - if ( event.which === 9 && this.elementValue( element ) === "" ) { - return; - } else if ( element.name in this.submitted || element === this.lastElement ) { - this.element( element ); - } - }, - onclick: function( element ) { - // click on selects, radiobuttons and checkboxes - if ( element.name in this.submitted ) { - this.element( element ); - - // or option elements, check parent select in that case - } else if ( element.parentNode.name in this.submitted ) { - this.element( element.parentNode ); - } - }, - highlight: function( element, errorClass, validClass ) { - if ( element.type === "radio" ) { - this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); - } else { - $( element ).addClass( errorClass ).removeClass( validClass ); - } - }, - unhighlight: function( element, errorClass, validClass ) { - if ( element.type === "radio" ) { - this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); - } else { - $( element ).removeClass( errorClass ).addClass( validClass ); - } - } - }, - - // http://jqueryvalidation.org/jQuery.validator.setDefaults/ - setDefaults: function( settings ) { - $.extend( $.validator.defaults, settings ); - }, - - messages: { - required: "This field is required.", - remote: "Please fix this field.", - email: "Please enter a valid email address.", - url: "Please enter a valid URL.", - date: "Please enter a valid date.", - dateISO: "Please enter a valid date ( ISO ).", - number: "Please enter a valid number.", - digits: "Please enter only digits.", - creditcard: "Please enter a valid credit card number.", - equalTo: "Please enter the same value again.", - maxlength: $.validator.format( "Please enter no more than {0} characters." ), - minlength: $.validator.format( "Please enter at least {0} characters." ), - rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), - range: $.validator.format( "Please enter a value between {0} and {1}." ), - max: $.validator.format( "Please enter a value less than or equal to {0}." ), - min: $.validator.format( "Please enter a value greater than or equal to {0}." ) - }, - - autoCreateRanges: false, - - prototype: { - - init: function() { - this.labelContainer = $( this.settings.errorLabelContainer ); - this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); - this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); - this.submitted = {}; - this.valueCache = {}; - this.pendingRequest = 0; - this.pending = {}; - this.invalid = {}; - this.reset(); - - var groups = ( this.groups = {} ), - rules; - $.each( this.settings.groups, function( key, value ) { - if ( typeof value === "string" ) { - value = value.split( /\s/ ); - } - $.each( value, function( index, name ) { - groups[ name ] = key; - }); - }); - rules = this.settings.rules; - $.each( rules, function( key, value ) { - rules[ key ] = $.validator.normalizeRule( value ); - }); - - function delegate( event ) { - var validator = $.data( this[ 0 ].form, "validator" ), - eventType = "on" + event.type.replace( /^validate/, "" ), - settings = validator.settings; - if ( settings[ eventType ] && !this.is( settings.ignore ) ) { - settings[ eventType ].call( validator, this[ 0 ], event ); - } - } - $( this.currentForm ) - .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " + - "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + - "[type='email'], [type='datetime'], [type='date'], [type='month'], " + - "[type='week'], [type='time'], [type='datetime-local'], " + - "[type='range'], [type='color'], [type='radio'], [type='checkbox']", - "focusin focusout keyup", delegate) - // Support: Chrome, oldIE - // "select" is provided as event.target when clicking a option - .validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate); - - if ( this.settings.invalidHandler ) { - $( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler ); - } - - // Add aria-required to any Static/Data/Class required fields before first validation - // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html - $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" ); - }, - - // http://jqueryvalidation.org/Validator.form/ - form: function() { - this.checkForm(); - $.extend( this.submitted, this.errorMap ); - this.invalid = $.extend({}, this.errorMap ); - if ( !this.valid() ) { - $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); - } - this.showErrors(); - return this.valid(); - }, - - checkForm: function() { - this.prepareForm(); - for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { - this.check( elements[ i ] ); - } - return this.valid(); - }, - - // http://jqueryvalidation.org/Validator.element/ - element: function( element ) { - var cleanElement = this.clean( element ), - checkElement = this.validationTargetFor( cleanElement ), - result = true; - - this.lastElement = checkElement; - - if ( checkElement === undefined ) { - delete this.invalid[ cleanElement.name ]; - } else { - this.prepareElement( checkElement ); - this.currentElements = $( checkElement ); - - result = this.check( checkElement ) !== false; - if ( result ) { - delete this.invalid[ checkElement.name ]; - } else { - this.invalid[ checkElement.name ] = true; - } - } - // Add aria-invalid status for screen readers - $( element ).attr( "aria-invalid", !result ); - - if ( !this.numberOfInvalids() ) { - // Hide error containers on last error - this.toHide = this.toHide.add( this.containers ); - } - this.showErrors(); - return result; - }, - - // http://jqueryvalidation.org/Validator.showErrors/ - showErrors: function( errors ) { - if ( errors ) { - // add items to error list and map - $.extend( this.errorMap, errors ); - this.errorList = []; - for ( var name in errors ) { - this.errorList.push({ - message: errors[ name ], - element: this.findByName( name )[ 0 ] - }); - } - // remove items from success list - this.successList = $.grep( this.successList, function( element ) { - return !( element.name in errors ); - }); - } - if ( this.settings.showErrors ) { - this.settings.showErrors.call( this, this.errorMap, this.errorList ); - } else { - this.defaultShowErrors(); - } - }, - - // http://jqueryvalidation.org/Validator.resetForm/ - resetForm: function() { - if ( $.fn.resetForm ) { - $( this.currentForm ).resetForm(); - } - this.submitted = {}; - this.lastElement = null; - this.prepareForm(); - this.hideErrors(); - this.elements() - .removeClass( this.settings.errorClass ) - .removeData( "previousValue" ) - .removeAttr( "aria-invalid" ); - }, - - numberOfInvalids: function() { - return this.objectLength( this.invalid ); - }, - - objectLength: function( obj ) { - /* jshint unused: false */ - var count = 0, - i; - for ( i in obj ) { - count++; - } - return count; - }, - - hideErrors: function() { - this.hideThese( this.toHide ); - }, - - hideThese: function( errors ) { - errors.not( this.containers ).text( "" ); - this.addWrapper( errors ).hide(); - }, - - valid: function() { - return this.size() === 0; - }, - - size: function() { - return this.errorList.length; - }, - - focusInvalid: function() { - if ( this.settings.focusInvalid ) { - try { - $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || []) - .filter( ":visible" ) - .focus() - // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find - .trigger( "focusin" ); - } catch ( e ) { - // ignore IE throwing errors when focusing hidden elements - } - } - }, - - findLastActive: function() { - var lastActive = this.lastActive; - return lastActive && $.grep( this.errorList, function( n ) { - return n.element.name === lastActive.name; - }).length === 1 && lastActive; - }, - - elements: function() { - var validator = this, - rulesCache = {}; - - // select all valid inputs inside the form (no submit or reset buttons) - return $( this.currentForm ) - .find( "input, select, textarea" ) - .not( ":submit, :reset, :image, [disabled], [readonly]" ) - .not( this.settings.ignore ) - .filter( function() { - if ( !this.name && validator.settings.debug && window.console ) { - console.error( "%o has no name assigned", this ); - } - - // select only the first element for each name, and only those with rules specified - if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { - return false; - } - - rulesCache[ this.name ] = true; - return true; - }); - }, - - clean: function( selector ) { - return $( selector )[ 0 ]; - }, - - errors: function() { - var errorClass = this.settings.errorClass.split( " " ).join( "." ); - return $( this.settings.errorElement + "." + errorClass, this.errorContext ); - }, - - reset: function() { - this.successList = []; - this.errorList = []; - this.errorMap = {}; - this.toShow = $( [] ); - this.toHide = $( [] ); - this.currentElements = $( [] ); - }, - - prepareForm: function() { - this.reset(); - this.toHide = this.errors().add( this.containers ); - }, - - prepareElement: function( element ) { - this.reset(); - this.toHide = this.errorsFor( element ); - }, - - elementValue: function( element ) { - var val, - $element = $( element ), - type = element.type; - - if ( type === "radio" || type === "checkbox" ) { - return $( "input[name='" + element.name + "']:checked" ).val(); - } else if ( type === "number" && typeof element.validity !== "undefined" ) { - return element.validity.badInput ? false : $element.val(); - } - - val = $element.val(); - if ( typeof val === "string" ) { - return val.replace(/\r/g, "" ); - } - return val; - }, - - check: function( element ) { - element = this.validationTargetFor( this.clean( element ) ); - - var rules = $( element ).rules(), - rulesCount = $.map( rules, function( n, i ) { - return i; - }).length, - dependencyMismatch = false, - val = this.elementValue( element ), - result, method, rule; - - for ( method in rules ) { - rule = { method: method, parameters: rules[ method ] }; - try { - - result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); - - // if a method indicates that the field is optional and therefore valid, - // don't mark it as valid when there are no other rules - if ( result === "dependency-mismatch" && rulesCount === 1 ) { - dependencyMismatch = true; - continue; - } - dependencyMismatch = false; - - if ( result === "pending" ) { - this.toHide = this.toHide.not( this.errorsFor( element ) ); - return; - } - - if ( !result ) { - this.formatAndAdd( element, rule ); - return false; - } - } catch ( e ) { - if ( this.settings.debug && window.console ) { - console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); - } - throw e; - } - } - if ( dependencyMismatch ) { - return; - } - if ( this.objectLength( rules ) ) { - this.successList.push( element ); - } - return true; - }, - - // return the custom message for the given element and validation method - // specified in the element's HTML5 data attribute - // return the generic message if present and no method specific message is present - customDataMessage: function( element, method ) { - return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + - method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); - }, - - // return the custom message for the given element name and validation method - customMessage: function( name, method ) { - var m = this.settings.messages[ name ]; - return m && ( m.constructor === String ? m : m[ method ]); - }, - - // return the first defined argument, allowing empty strings - findDefined: function() { - for ( var i = 0; i < arguments.length; i++) { - if ( arguments[ i ] !== undefined ) { - return arguments[ i ]; - } - } - return undefined; - }, - - defaultMessage: function( element, method ) { - return this.findDefined( - this.customMessage( element.name, method ), - this.customDataMessage( element, method ), - // title is never undefined, so handle empty string as undefined - !this.settings.ignoreTitle && element.title || undefined, - $.validator.messages[ method ], - "Warning: No message defined for " + element.name + "" - ); - }, - - formatAndAdd: function( element, rule ) { - var message = this.defaultMessage( element, rule.method ), - theregex = /\$?\{(\d+)\}/g; - if ( typeof message === "function" ) { - message = message.call( this, rule.parameters, element ); - } else if ( theregex.test( message ) ) { - message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); - } - this.errorList.push({ - message: message, - element: element, - method: rule.method - }); - - this.errorMap[ element.name ] = message; - this.submitted[ element.name ] = message; - }, - - addWrapper: function( toToggle ) { - if ( this.settings.wrapper ) { - toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); - } - return toToggle; - }, - - defaultShowErrors: function() { - var i, elements, error; - for ( i = 0; this.errorList[ i ]; i++ ) { - error = this.errorList[ i ]; - if ( this.settings.highlight ) { - this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); - } - this.showLabel( error.element, error.message ); - } - if ( this.errorList.length ) { - this.toShow = this.toShow.add( this.containers ); - } - if ( this.settings.success ) { - for ( i = 0; this.successList[ i ]; i++ ) { - this.showLabel( this.successList[ i ] ); - } - } - if ( this.settings.unhighlight ) { - for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { - this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass ); - } - } - this.toHide = this.toHide.not( this.toShow ); - this.hideErrors(); - this.addWrapper( this.toShow ).show(); - }, - - validElements: function() { - return this.currentElements.not( this.invalidElements() ); - }, - - invalidElements: function() { - return $( this.errorList ).map(function() { - return this.element; - }); - }, - - showLabel: function( element, message ) { - var place, group, errorID, - error = this.errorsFor( element ), - elementID = this.idOrName( element ), - describedBy = $( element ).attr( "aria-describedby" ); - if ( error.length ) { - // refresh error/success class - error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); - // replace message on existing label - error.html( message ); - } else { - // create error element - error = $( "<" + this.settings.errorElement + ">" ) - .attr( "id", elementID + "-error" ) - .addClass( this.settings.errorClass ) - .html( message || "" ); - - // Maintain reference to the element to be placed into the DOM - place = error; - if ( this.settings.wrapper ) { - // make sure the element is visible, even in IE - // actually showing the wrapped element is handled elsewhere - place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); - } - if ( this.labelContainer.length ) { - this.labelContainer.append( place ); - } else if ( this.settings.errorPlacement ) { - this.settings.errorPlacement( place, $( element ) ); - } else { - place.insertAfter( element ); - } - - // Link error back to the element - if ( error.is( "label" ) ) { - // If the error is a label, then associate using 'for' - error.attr( "for", elementID ); - } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) { - // If the element is not a child of an associated label, then it's necessary - // to explicitly apply aria-describedby - - errorID = error.attr( "id" ).replace( /(:|\.|\[|\])/g, "\\$1"); - // Respect existing non-error aria-describedby - if ( !describedBy ) { - describedBy = errorID; - } else if ( !describedBy.match( new RegExp( "\\b" + errorID + "\\b" ) ) ) { - // Add to end of list if not already present - describedBy += " " + errorID; - } - $( element ).attr( "aria-describedby", describedBy ); - - // If this element is grouped, then assign to all elements in the same group - group = this.groups[ element.name ]; - if ( group ) { - $.each( this.groups, function( name, testgroup ) { - if ( testgroup === group ) { - $( "[name='" + name + "']", this.currentForm ) - .attr( "aria-describedby", error.attr( "id" ) ); - } - }); - } - } - } - if ( !message && this.settings.success ) { - error.text( "" ); - if ( typeof this.settings.success === "string" ) { - error.addClass( this.settings.success ); - } else { - this.settings.success( error, element ); - } - } - this.toShow = this.toShow.add( error ); - }, - - errorsFor: function( element ) { - var name = this.idOrName( element ), - describer = $( element ).attr( "aria-describedby" ), - selector = "label[for='" + name + "'], label[for='" + name + "'] *"; - - // aria-describedby should directly reference the error element - if ( describer ) { - selector = selector + ", #" + describer.replace( /\s+/g, ", #" ); - } - return this - .errors() - .filter( selector ); - }, - - idOrName: function( element ) { - return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name ); - }, - - validationTargetFor: function( element ) { - - // If radio/checkbox, validate first element in group instead - if ( this.checkable( element ) ) { - element = this.findByName( element.name ); - } - - // Always apply ignore filter - return $( element ).not( this.settings.ignore )[ 0 ]; - }, - - checkable: function( element ) { - return ( /radio|checkbox/i ).test( element.type ); - }, - - findByName: function( name ) { - return $( this.currentForm ).find( "[name='" + name + "']" ); - }, - - getLength: function( value, element ) { - switch ( element.nodeName.toLowerCase() ) { - case "select": - return $( "option:selected", element ).length; - case "input": - if ( this.checkable( element ) ) { - return this.findByName( element.name ).filter( ":checked" ).length; - } - } - return value.length; - }, - - depend: function( param, element ) { - return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true; - }, - - dependTypes: { - "boolean": function( param ) { - return param; - }, - "string": function( param, element ) { - return !!$( param, element.form ).length; - }, - "function": function( param, element ) { - return param( element ); - } - }, - - optional: function( element ) { - var val = this.elementValue( element ); - return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; - }, - - startRequest: function( element ) { - if ( !this.pending[ element.name ] ) { - this.pendingRequest++; - this.pending[ element.name ] = true; - } - }, - - stopRequest: function( element, valid ) { - this.pendingRequest--; - // sometimes synchronization fails, make sure pendingRequest is never < 0 - if ( this.pendingRequest < 0 ) { - this.pendingRequest = 0; - } - delete this.pending[ element.name ]; - if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { - $( this.currentForm ).submit(); - this.formSubmitted = false; - } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) { - $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); - this.formSubmitted = false; - } - }, - - previousValue: function( element ) { - return $.data( element, "previousValue" ) || $.data( element, "previousValue", { - old: null, - valid: true, - message: this.defaultMessage( element, "remote" ) - }); - } - - }, - - classRuleSettings: { - required: { required: true }, - email: { email: true }, - url: { url: true }, - date: { date: true }, - dateISO: { dateISO: true }, - number: { number: true }, - digits: { digits: true }, - creditcard: { creditcard: true } - }, - - addClassRules: function( className, rules ) { - if ( className.constructor === String ) { - this.classRuleSettings[ className ] = rules; - } else { - $.extend( this.classRuleSettings, className ); - } - }, - - classRules: function( element ) { - var rules = {}, - classes = $( element ).attr( "class" ); - - if ( classes ) { - $.each( classes.split( " " ), function() { - if ( this in $.validator.classRuleSettings ) { - $.extend( rules, $.validator.classRuleSettings[ this ]); - } - }); - } - return rules; - }, - - attributeRules: function( element ) { - var rules = {}, - $element = $( element ), - type = element.getAttribute( "type" ), - method, value; - - for ( method in $.validator.methods ) { - - // support for in both html5 and older browsers - if ( method === "required" ) { - value = element.getAttribute( method ); - // Some browsers return an empty string for the required attribute - // and non-HTML5 browsers might have required="" markup - if ( value === "" ) { - value = true; - } - // force non-HTML5 browsers to return bool - value = !!value; - } else { - value = $element.attr( method ); - } - - // convert the value to a number for number inputs, and for text for backwards compability - // allows type="date" and others to be compared as strings - if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { - value = Number( value ); - } - - if ( value || value === 0 ) { - rules[ method ] = value; - } else if ( type === method && type !== "range" ) { - // exception: the jquery validate 'range' method - // does not test for the html5 'range' type - rules[ method ] = true; - } - } - - // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs - if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { - delete rules.maxlength; - } - - return rules; - }, - - dataRules: function( element ) { - var method, value, - rules = {}, $element = $( element ); - for ( method in $.validator.methods ) { - value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); - if ( value !== undefined ) { - rules[ method ] = value; - } - } - return rules; - }, - - staticRules: function( element ) { - var rules = {}, - validator = $.data( element.form, "validator" ); - - if ( validator.settings.rules ) { - rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; - } - return rules; - }, - - normalizeRules: function( rules, element ) { - // handle dependency check - $.each( rules, function( prop, val ) { - // ignore rule when param is explicitly false, eg. required:false - if ( val === false ) { - delete rules[ prop ]; - return; - } - if ( val.param || val.depends ) { - var keepRule = true; - switch ( typeof val.depends ) { - case "string": - keepRule = !!$( val.depends, element.form ).length; - break; - case "function": - keepRule = val.depends.call( element, element ); - break; - } - if ( keepRule ) { - rules[ prop ] = val.param !== undefined ? val.param : true; - } else { - delete rules[ prop ]; - } - } - }); - - // evaluate parameters - $.each( rules, function( rule, parameter ) { - rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter; - }); - - // clean number parameters - $.each([ "minlength", "maxlength" ], function() { - if ( rules[ this ] ) { - rules[ this ] = Number( rules[ this ] ); - } - }); - $.each([ "rangelength", "range" ], function() { - var parts; - if ( rules[ this ] ) { - if ( $.isArray( rules[ this ] ) ) { - rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ]; - } else if ( typeof rules[ this ] === "string" ) { - parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ ); - rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ]; - } - } - }); - - if ( $.validator.autoCreateRanges ) { - // auto-create ranges - if ( rules.min != null && rules.max != null ) { - rules.range = [ rules.min, rules.max ]; - delete rules.min; - delete rules.max; - } - if ( rules.minlength != null && rules.maxlength != null ) { - rules.rangelength = [ rules.minlength, rules.maxlength ]; - delete rules.minlength; - delete rules.maxlength; - } - } - - return rules; - }, - - // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} - normalizeRule: function( data ) { - if ( typeof data === "string" ) { - var transformed = {}; - $.each( data.split( /\s/ ), function() { - transformed[ this ] = true; - }); - data = transformed; - } - return data; - }, - - // http://jqueryvalidation.org/jQuery.validator.addMethod/ - addMethod: function( name, method, message ) { - $.validator.methods[ name ] = method; - $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; - if ( method.length < 3 ) { - $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); - } - }, - - methods: { - - // http://jqueryvalidation.org/required-method/ - required: function( value, element, param ) { - // check if dependency is met - if ( !this.depend( param, element ) ) { - return "dependency-mismatch"; - } - if ( element.nodeName.toLowerCase() === "select" ) { - // could be an array for select-multiple or a string, both are fine this way - var val = $( element ).val(); - return val && val.length > 0; - } - if ( this.checkable( element ) ) { - return this.getLength( value, element ) > 0; - } - return $.trim( value ).length > 0; - }, - - // http://jqueryvalidation.org/email-method/ - email: function( value, element ) { - // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29 - // Retrieved 2014-01-14 - // If you have a problem with this implementation, report a bug against the above spec - // Or use custom methods to implement your own email validation - return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); - }, - - // http://jqueryvalidation.org/url-method/ - url: function( value, element ) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ - return this.optional( element ) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value ); - }, - - // http://jqueryvalidation.org/date-method/ - date: function( value, element ) { - return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); - }, - - // http://jqueryvalidation.org/dateISO-method/ - dateISO: function( value, element ) { - return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); - }, - - // http://jqueryvalidation.org/number-method/ - number: function( value, element ) { - return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); - }, - - // http://jqueryvalidation.org/digits-method/ - digits: function( value, element ) { - return this.optional( element ) || /^\d+$/.test( value ); - }, - - // http://jqueryvalidation.org/creditcard-method/ - // based on http://en.wikipedia.org/wiki/Luhn/ - creditcard: function( value, element ) { - if ( this.optional( element ) ) { - return "dependency-mismatch"; - } - // accept only spaces, digits and dashes - if ( /[^0-9 \-]+/.test( value ) ) { - return false; - } - var nCheck = 0, - nDigit = 0, - bEven = false, - n, cDigit; - - value = value.replace( /\D/g, "" ); - - // Basing min and max length on - // http://developer.ean.com/general_info/Valid_Credit_Card_Types - if ( value.length < 13 || value.length > 19 ) { - return false; - } - - for ( n = value.length - 1; n >= 0; n--) { - cDigit = value.charAt( n ); - nDigit = parseInt( cDigit, 10 ); - if ( bEven ) { - if ( ( nDigit *= 2 ) > 9 ) { - nDigit -= 9; - } - } - nCheck += nDigit; - bEven = !bEven; - } - - return ( nCheck % 10 ) === 0; - }, - - // http://jqueryvalidation.org/minlength-method/ - minlength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength( value, element ); - return this.optional( element ) || length >= param; - }, - - // http://jqueryvalidation.org/maxlength-method/ - maxlength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength( value, element ); - return this.optional( element ) || length <= param; - }, - - // http://jqueryvalidation.org/rangelength-method/ - rangelength: function( value, element, param ) { - var length = $.isArray( value ) ? value.length : this.getLength( value, element ); - return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); - }, - - // http://jqueryvalidation.org/min-method/ - min: function( value, element, param ) { - return this.optional( element ) || value >= param; - }, - - // http://jqueryvalidation.org/max-method/ - max: function( value, element, param ) { - return this.optional( element ) || value <= param; - }, - - // http://jqueryvalidation.org/range-method/ - range: function( value, element, param ) { - return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); - }, - - // http://jqueryvalidation.org/equalTo-method/ - equalTo: function( value, element, param ) { - // bind to the blur event of the target in order to revalidate whenever the target field is updated - // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead - var target = $( param ); - if ( this.settings.onfocusout ) { - target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() { - $( element ).valid(); - }); - } - return value === target.val(); - }, - - // http://jqueryvalidation.org/remote-method/ - remote: function( value, element, param ) { - if ( this.optional( element ) ) { - return "dependency-mismatch"; - } - - var previous = this.previousValue( element ), - validator, data; - - if (!this.settings.messages[ element.name ] ) { - this.settings.messages[ element.name ] = {}; - } - previous.originalMessage = this.settings.messages[ element.name ].remote; - this.settings.messages[ element.name ].remote = previous.message; - - param = typeof param === "string" && { url: param } || param; - - if ( previous.old === value ) { - return previous.valid; - } - - previous.old = value; - validator = this; - this.startRequest( element ); - data = {}; - data[ element.name ] = value; - $.ajax( $.extend( true, { - url: param, - mode: "abort", - port: "validate" + element.name, - dataType: "json", - data: data, - context: validator.currentForm, - success: function( response ) { - var valid = response === true || response === "true", - errors, message, submitted; - - validator.settings.messages[ element.name ].remote = previous.originalMessage; - if ( valid ) { - submitted = validator.formSubmitted; - validator.prepareElement( element ); - validator.formSubmitted = submitted; - validator.successList.push( element ); - delete validator.invalid[ element.name ]; - validator.showErrors(); - } else { - errors = {}; - message = response || validator.defaultMessage( element, "remote" ); - errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message; - validator.invalid[ element.name ] = true; - validator.showErrors( errors ); - } - previous.valid = valid; - validator.stopRequest( element, valid ); - } - }, param ) ); - return "pending"; - } - - } - -}); - -$.format = function deprecated() { - throw "$.format has been deprecated. Please use $.validator.format instead."; -}; - -// ajax mode: abort -// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); -// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() - -var pendingRequests = {}, - ajax; -// Use a prefilter if available (1.5+) -if ( $.ajaxPrefilter ) { - $.ajaxPrefilter(function( settings, _, xhr ) { - var port = settings.port; - if ( settings.mode === "abort" ) { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - pendingRequests[port] = xhr; - } - }); -} else { - // Proxy ajax - ajax = $.ajax; - $.ajax = function( settings ) { - var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, - port = ( "port" in settings ? settings : $.ajaxSettings ).port; - if ( mode === "abort" ) { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - pendingRequests[port] = ajax.apply(this, arguments); - return pendingRequests[port]; - } - return ajax.apply(this, arguments); - }; -} - -// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation -// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target - -$.extend($.fn, { - validateDelegate: function( delegate, type, handler ) { - return this.bind(type, function( event ) { - var target = $(event.target); - if ( target.is(delegate) ) { - return handler.apply(target, arguments); - } - }); - } -}); - -})); -/*jslint adsafe: false, bitwise: true, browser: true, cap: false, css: false, - debug: false, devel: true, eqeqeq: true, es5: false, evil: false, - forin: false, fragment: false, immed: true, laxbreak: false, newcap: true, - nomen: false, on: false, onevar: true, passfail: false, plusplus: true, - regexp: false, rhino: true, safe: false, strict: false, sub: false, - undef: true, white: false, widget: false, windows: false */ -/*global jQuery: false, window: false */ -"use strict"; - -/* - * Original code (c) 2010 Nick Galbreath - * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript - * - * jQuery port (c) 2010 Carlo Zottmann - * http://github.com/carlo/jquery-base64 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* base64 encode/decode compatible with window.btoa/atob - * - * window.atob/btoa is a Firefox extension to convert binary data (the "b") - * to base64 (ascii, the "a"). - * - * It is also found in Safari and Chrome. It is not available in IE. - * - * if (!window.btoa) window.btoa = $.base64.encode - * if (!window.atob) window.atob = $.base64.decode - * - * The original spec's for atob/btoa are a bit lacking - * https://developer.mozilla.org/en/DOM/window.atob - * https://developer.mozilla.org/en/DOM/window.btoa - * - * window.btoa and $.base64.encode takes a string where charCodeAt is [0,255] - * If any character is not [0,255], then an exception is thrown. - * - * window.atob and $.base64.decode take a base64-encoded string - * If the input length is not a multiple of 4, or contains invalid characters - * then an exception is thrown. - */ - -jQuery.base64 = ( function( $ ) { - - var _PADCHAR = "=", - _ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", - _VERSION = "1.0"; - - - function _getbyte64( s, i ) { - // This is oddly fast, except on Chrome/V8. - // Minimal or no improvement in performance by using a - // object with properties mapping chars to value (eg. 'A': 0) - - var idx = _ALPHA.indexOf( s.charAt( i ) ); - - if ( idx === -1 ) { - throw "Cannot decode base64"; - } - - return idx; - } - - - function _decode( s ) { - var pads = 0, - i, - b10, - imax = s.length, - x = []; - - s = String( s ); - - if ( imax === 0 ) { - return s; - } - - if ( imax % 4 !== 0 ) { - throw "Cannot decode base64"; - } - - if ( s.charAt( imax - 1 ) === _PADCHAR ) { - pads = 1; - - if ( s.charAt( imax - 2 ) === _PADCHAR ) { - pads = 2; - } - - // either way, we want to ignore this last block - imax -= 4; - } - - for ( i = 0; i < imax; i += 4 ) { - b10 = ( _getbyte64( s, i ) << 18 ) | ( _getbyte64( s, i + 1 ) << 12 ) | ( _getbyte64( s, i + 2 ) << 6 ) | _getbyte64( s, i + 3 ); - x.push( String.fromCharCode( b10 >> 16, ( b10 >> 8 ) & 0xff, b10 & 0xff ) ); - } - - switch ( pads ) { - case 1: - b10 = ( _getbyte64( s, i ) << 18 ) | ( _getbyte64( s, i + 1 ) << 12 ) | ( _getbyte64( s, i + 2 ) << 6 ); - x.push( String.fromCharCode( b10 >> 16, ( b10 >> 8 ) & 0xff ) ); - break; - - case 2: - b10 = ( _getbyte64( s, i ) << 18) | ( _getbyte64( s, i + 1 ) << 12 ); - x.push( String.fromCharCode( b10 >> 16 ) ); - break; - } - - return x.join( "" ); - } - - - function _getbyte( s, i ) { - var x = s.charCodeAt( i ); - - if ( x > 255 ) { - throw "INVALID_CHARACTER_ERR: DOM Exception 5"; - } - - return x; - } - - - function _encode( s ) { - if ( arguments.length !== 1 ) { - throw "SyntaxError: exactly one argument required"; - } - - s = String( s ); - - var i, - b10, - x = [], - imax = s.length - s.length % 3; - - if ( s.length === 0 ) { - return s; - } - - for ( i = 0; i < imax; i += 3 ) { - b10 = ( _getbyte( s, i ) << 16 ) | ( _getbyte( s, i + 1 ) << 8 ) | _getbyte( s, i + 2 ); - x.push( _ALPHA.charAt( b10 >> 18 ) ); - x.push( _ALPHA.charAt( ( b10 >> 12 ) & 0x3F ) ); - x.push( _ALPHA.charAt( ( b10 >> 6 ) & 0x3f ) ); - x.push( _ALPHA.charAt( b10 & 0x3f ) ); - } - - switch ( s.length - imax ) { - case 1: - b10 = _getbyte( s, i ) << 16; - x.push( _ALPHA.charAt( b10 >> 18 ) + _ALPHA.charAt( ( b10 >> 12 ) & 0x3F ) + _PADCHAR + _PADCHAR ); - break; - - case 2: - b10 = ( _getbyte( s, i ) << 16 ) | ( _getbyte( s, i + 1 ) << 8 ); - x.push( _ALPHA.charAt( b10 >> 18 ) + _ALPHA.charAt( ( b10 >> 12 ) & 0x3F ) + _ALPHA.charAt( ( b10 >> 6 ) & 0x3f ) + _PADCHAR ); - break; - } - - return x.join( "" ); - } - - - return { - decode: _decode, - encode: _encode, - VERSION: _VERSION - }; - -}( jQuery ) ); - - -(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{if(typeof exports==="object"){a(require("jquery"))}else{a(jQuery)}}}(function(f,c){if(!("indexOf" in Array.prototype)){Array.prototype.indexOf=function(k,j){if(j===c){j=0}if(j<0){j+=this.length}if(j<0){j=0}for(var l=this.length;j=this.startDate&&j<=this.endDate){this.date=j;this.setValue();this.viewDate=this.date;this.fill()}else{this.element.trigger({type:"outOfRange",date:j,startDate:this.startDate,endDate:this.endDate})}},setFormat:function(k){this.format=g.parseFormat(k,this.formatType);var j;if(this.isInput){j=this.element}else{if(this.component){j=this.element.find("input")}}if(j&&j.val()){this.setValue()}},setValue:function(){var j=this.getFormattedDate();if(!this.isInput){if(this.component){this.element.find("input").val(j)}this.element.data("date",j)}else{this.element.val(j)}if(this.linkField){f("#"+this.linkField).val(this.getFormattedDate(this.linkFormat))}},getFormattedDate:function(j){if(j==c){j=this.format}return g.formatDate(this.date,j,this.language,this.formatType,this.timezone)},setStartDate:function(j){this.startDate=j||-Infinity;if(this.startDate!==-Infinity){this.startDate=g.parseDate(this.startDate,this.format,this.language,this.formatType,this.timezone)}this.update();this.updateNavArrows()},setEndDate:function(j){this.endDate=j||Infinity;if(this.endDate!==Infinity){this.endDate=g.parseDate(this.endDate,this.format,this.language,this.formatType,this.timezone)}this.update();this.updateNavArrows()},setDatesDisabled:function(j){this.datesDisabled=j||[];if(!f.isArray(this.datesDisabled)){this.datesDisabled=this.datesDisabled.split(/,\s*/)}this.datesDisabled=f.map(this.datesDisabled,function(k){return g.parseDate(k,this.format,this.language,this.formatType,this.timezone).toDateString()});this.update();this.updateNavArrows()},setTitle:function(j,k){return this.picker.find(j).find("th:eq(1)").text(this.title===false?k:this.title)},setDaysOfWeekDisabled:function(j){this.daysOfWeekDisabled=j||[];if(!f.isArray(this.daysOfWeekDisabled)){this.daysOfWeekDisabled=this.daysOfWeekDisabled.split(/,\s*/)}this.daysOfWeekDisabled=f.map(this.daysOfWeekDisabled,function(k){return parseInt(k,10)});this.update();this.updateNavArrows()},setMinutesDisabled:function(j){this.minutesDisabled=j||[];if(!f.isArray(this.minutesDisabled)){this.minutesDisabled=this.minutesDisabled.split(/,\s*/)}this.minutesDisabled=f.map(this.minutesDisabled,function(k){return parseInt(k,10)});this.update();this.updateNavArrows()},setHoursDisabled:function(j){this.hoursDisabled=j||[];if(!f.isArray(this.hoursDisabled)){this.hoursDisabled=this.hoursDisabled.split(/,\s*/)}this.hoursDisabled=f.map(this.hoursDisabled,function(k){return parseInt(k,10)});this.update();this.updateNavArrows()},place:function(){if(this.isInline){return}if(!this.zIndex){var k=0;f("div").each(function(){var p=parseInt(f(this).css("zIndex"),10);if(p>k){k=p}});this.zIndex=k+10}var o,n,m,l;if(this.container instanceof f){l=this.container.offset()}else{l=f(this.container).offset()}if(this.component){o=this.component.offset();m=o.left;if(this.pickerPosition=="bottom-left"||this.pickerPosition=="top-left"){m+=this.component.outerWidth()-this.picker.outerWidth()}}else{o=this.element.offset();m=o.left;if(this.pickerPosition=="bottom-left"||this.pickerPosition=="top-left"){m+=this.element.outerWidth()-this.picker.outerWidth()}}var j=document.body.clientWidth||window.innerWidth;if(m+220>j){m=j-220}if(this.pickerPosition=="top-left"||this.pickerPosition=="top-right"){n=o.top-this.picker.outerHeight()}else{n=o.top+this.height}n=n-l.top;m=m-l.left;this.picker.css({top:n,left:m,zIndex:this.zIndex})},update:function(){var j,k=false;if(arguments&&arguments.length&&(typeof arguments[0]==="string"||arguments[0] instanceof Date)){j=arguments[0];k=true}else{j=(this.isInput?this.element.val():this.element.find("input").val())||this.element.data("date")||this.initialDate;if(typeof j=="string"||j instanceof String){j=j.replace(/^\s+|\s+$/g,"")}}if(!j){j=new Date();k=false}this.date=g.parseDate(j,this.format,this.language,this.formatType,this.timezone);if(k){this.setValue()}if(this.datethis.endDate){this.viewDate=new Date(this.endDate)}else{this.viewDate=new Date(this.date)}}this.fill()},fillDow:function(){var j=this.weekStart,k="";while(j'+a[this.language].daysMin[(j++)%7]+""}k+="";this.picker.find(".datetimepicker-days thead").append(k)},fillMonths:function(){var k="",j=0;while(j<12){k+=''+a[this.language].monthsShort[j++]+""}this.picker.find(".datetimepicker-months td").html(k)},fill:function(){if(this.date==null||this.viewDate==null){return}var H=new Date(this.viewDate),u=H.getUTCFullYear(),I=H.getUTCMonth(),n=H.getUTCDate(),D=H.getUTCHours(),y=H.getUTCMinutes(),z=this.startDate!==-Infinity?this.startDate.getUTCFullYear():-Infinity,E=this.startDate!==-Infinity?this.startDate.getUTCMonth():-Infinity,q=this.endDate!==Infinity?this.endDate.getUTCFullYear():Infinity,A=this.endDate!==Infinity?this.endDate.getUTCMonth()+1:Infinity,r=(new h(this.date.getUTCFullYear(),this.date.getUTCMonth(),this.date.getUTCDate())).valueOf(),G=new Date();this.setTitle(".datetimepicker-days",a[this.language].months[I]+" "+u);if(this.formatViewType=="time"){var k=this.getFormattedDate();this.setTitle(".datetimepicker-hours",k);this.setTitle(".datetimepicker-minutes",k)}else{this.setTitle(".datetimepicker-hours",n+" "+a[this.language].months[I]+" "+u);this.setTitle(".datetimepicker-minutes",n+" "+a[this.language].months[I]+" "+u)}this.picker.find("tfoot th.today").text(a[this.language].today||a.en.today).toggle(this.todayBtn!==false);this.picker.find("tfoot th.clear").text(a[this.language].clear||a.en.clear).toggle(this.clearBtn!==false);this.updateNavArrows();this.fillMonths();var K=h(u,I-1,28,0,0,0,0),C=g.getDaysInMonth(K.getUTCFullYear(),K.getUTCMonth());K.setUTCDate(C);K.setUTCDate(C-(K.getUTCDay()-this.weekStart+7)%7);var j=new Date(K);j.setUTCDate(j.getUTCDate()+42);j=j.valueOf();var s=[];var v;while(K.valueOf()")}v="";if(K.getUTCFullYear()u||(K.getUTCFullYear()==u&&K.getUTCMonth()>I)){v+=" new"}}if(this.todayHighlight&&K.getUTCFullYear()==G.getFullYear()&&K.getUTCMonth()==G.getMonth()&&K.getUTCDate()==G.getDate()){v+=" today"}if(K.valueOf()==r){v+=" active"}if((K.valueOf()+86400000)<=this.startDate||K.valueOf()>this.endDate||f.inArray(K.getUTCDay(),this.daysOfWeekDisabled)!==-1||f.inArray(K.toDateString(),this.datesDisabled)!==-1){v+=" disabled"}s.push(''+K.getUTCDate()+"");if(K.getUTCDay()==this.weekEnd){s.push("")}K.setUTCDate(K.getUTCDate()+1)}this.picker.find(".datetimepicker-days tbody").empty().append(s.join(""));s=[];var w="",F="",t="";var l=this.hoursDisabled||[];for(var B=0;B<24;B++){if(l.indexOf(B)!==-1){continue}var x=h(u,I,n,B);v="";if((x.valueOf()+3600000)<=this.startDate||x.valueOf()>this.endDate){v+=" disabled"}else{if(D==B){v+=" active"}}if(this.showMeridian&&a[this.language].meridiem.length==2){F=(B<12?a[this.language].meridiem[0]:a[this.language].meridiem[1]);if(F!=t){if(t!=""){s.push("")}s.push('
'+F.toUpperCase()+"")}t=F;w=(B%12?B%12:12);s.push(''+w+"");if(B==23){s.push("
")}}else{w=B+":00";s.push(''+w+"")}}this.picker.find(".datetimepicker-hours td").html(s.join(""));s=[];w="",F="",t="";var m=this.minutesDisabled||[];for(var B=0;B<60;B+=this.minuteStep){if(m.indexOf(B)!==-1){continue}var x=h(u,I,n,D,B,0);v="";if(x.valueOf()this.endDate){v+=" disabled"}else{if(Math.floor(y/this.minuteStep)==Math.floor(B/this.minuteStep)){v+=" active"}}if(this.showMeridian&&a[this.language].meridiem.length==2){F=(D<12?a[this.language].meridiem[0]:a[this.language].meridiem[1]);if(F!=t){if(t!=""){s.push("")}s.push('
'+F.toUpperCase()+"")}t=F;w=(D%12?D%12:12);s.push(''+w+":"+(B<10?"0"+B:B)+"");if(B==59){s.push("
")}}else{w=B+":00";s.push(''+D+":"+(B<10?"0"+B:B)+"")}}this.picker.find(".datetimepicker-minutes td").html(s.join(""));var L=this.date.getUTCFullYear();var p=this.setTitle(".datetimepicker-months",u).end().find("span").removeClass("active");if(L==u){var o=p.length-12;p.eq(this.date.getUTCMonth()+o).addClass("active")}if(uq){p.addClass("disabled")}if(u==z){p.slice(0,E).addClass("disabled")}if(u==q){p.slice(A).addClass("disabled")}s="";u=parseInt(u/10,10)*10;var J=this.setTitle(".datetimepicker-years",u+"-"+(u+9)).end().find("td");u-=1;for(var B=-1;B<11;B++){s+='q?" disabled":"")+'">'+u+"";u+=1}J.html(s);this.place()},updateNavArrows:function(){var n=new Date(this.viewDate),l=n.getUTCFullYear(),m=n.getUTCMonth(),k=n.getUTCDate(),j=n.getUTCHours();switch(this.viewMode){case 0:if(this.startDate!==-Infinity&&l<=this.startDate.getUTCFullYear()&&m<=this.startDate.getUTCMonth()&&k<=this.startDate.getUTCDate()&&j<=this.startDate.getUTCHours()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(this.endDate!==Infinity&&l>=this.endDate.getUTCFullYear()&&m>=this.endDate.getUTCMonth()&&k>=this.endDate.getUTCDate()&&j>=this.endDate.getUTCHours()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break;case 1:if(this.startDate!==-Infinity&&l<=this.startDate.getUTCFullYear()&&m<=this.startDate.getUTCMonth()&&k<=this.startDate.getUTCDate()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(this.endDate!==Infinity&&l>=this.endDate.getUTCFullYear()&&m>=this.endDate.getUTCMonth()&&k>=this.endDate.getUTCDate()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break;case 2:if(this.startDate!==-Infinity&&l<=this.startDate.getUTCFullYear()&&m<=this.startDate.getUTCMonth()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(this.endDate!==Infinity&&l>=this.endDate.getUTCFullYear()&&m>=this.endDate.getUTCMonth()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break;case 3:case 4:if(this.startDate!==-Infinity&&l<=this.startDate.getUTCFullYear()){this.picker.find(".prev").css({visibility:"hidden"})}else{this.picker.find(".prev").css({visibility:"visible"})}if(this.endDate!==Infinity&&l>=this.endDate.getUTCFullYear()){this.picker.find(".next").css({visibility:"hidden"})}else{this.picker.find(".next").css({visibility:"visible"})}break}},mousewheel:function(k){k.preventDefault();k.stopPropagation();if(this.wheelPause){return}this.wheelPause=true;var j=k.originalEvent;var m=j.wheelDelta;var l=m>0?1:(m===0)?0:-1;if(this.wheelViewModeNavigationInverseDirection){l=-l}this.showMode(l);setTimeout(f.proxy(function(){this.wheelPause=false},this),this.wheelViewModeNavigationDelay)},click:function(n){n.stopPropagation();n.preventDefault();var o=f(n.target).closest("span, td, th, legend");if(o.is("."+this.icontype)){o=f(o).parent().closest("span, td, th, legend")}if(o.length==1){if(o.is(".disabled")){this.element.trigger({type:"outOfRange",date:this.viewDate,startDate:this.startDate,endDate:this.endDate});return}switch(o[0].nodeName.toLowerCase()){case"th":switch(o[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var j=g.modes[this.viewMode].navStep*(o[0].className=="prev"?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveHour(this.viewDate,j);break;case 1:this.viewDate=this.moveDate(this.viewDate,j);break;case 2:this.viewDate=this.moveMonth(this.viewDate,j);break;case 3:case 4:this.viewDate=this.moveYear(this.viewDate,j);break}this.fill();this.element.trigger({type:o[0].className+":"+this.convertViewModeText(this.viewMode),date:this.viewDate,startDate:this.startDate,endDate:this.endDate});break;case"clear":this.reset();if(this.autoclose){this.hide()}break;case"today":var k=new Date();k=h(k.getFullYear(),k.getMonth(),k.getDate(),k.getHours(),k.getMinutes(),k.getSeconds(),0);if(kthis.endDate){k=this.endDate}}this.viewMode=this.startViewMode;this.showMode(0);this._setDate(k);this.fill();if(this.autoclose){this.hide()}break}break;case"span":if(!o.is(".disabled")){var q=this.viewDate.getUTCFullYear(),p=this.viewDate.getUTCMonth(),r=this.viewDate.getUTCDate(),s=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),t=this.viewDate.getUTCSeconds();if(o.is(".month")){this.viewDate.setUTCDate(1);p=o.parent().find("span").index(o);r=this.viewDate.getUTCDate();this.viewDate.setUTCMonth(p);this.element.trigger({type:"changeMonth",date:this.viewDate});if(this.viewSelect>=3){this._setDate(h(q,p,r,s,l,t,0))}}else{if(o.is(".year")){this.viewDate.setUTCDate(1);q=parseInt(o.text(),10)||0;this.viewDate.setUTCFullYear(q);this.element.trigger({type:"changeYear",date:this.viewDate});if(this.viewSelect>=4){this._setDate(h(q,p,r,s,l,t,0))}}else{if(o.is(".hour")){s=parseInt(o.text(),10)||0;if(o.hasClass("hour_am")||o.hasClass("hour_pm")){if(s==12&&o.hasClass("hour_am")){s=0}else{if(s!=12&&o.hasClass("hour_pm")){s+=12}}}this.viewDate.setUTCHours(s);this.element.trigger({type:"changeHour",date:this.viewDate});if(this.viewSelect>=1){this._setDate(h(q,p,r,s,l,t,0))}}else{if(o.is(".minute")){l=parseInt(o.text().substr(o.text().indexOf(":")+1),10)||0;this.viewDate.setUTCMinutes(l);this.element.trigger({type:"changeMinute",date:this.viewDate});if(this.viewSelect>=0){this._setDate(h(q,p,r,s,l,t,0))}}}}}if(this.viewMode!=0){var m=this.viewMode;this.showMode(-1);this.fill();if(m==this.viewMode&&this.autoclose){this.hide()}}else{this.fill();if(this.autoclose){this.hide()}}}break;case"td":if(o.is(".day")&&!o.is(".disabled")){var r=parseInt(o.text(),10)||1;var q=this.viewDate.getUTCFullYear(),p=this.viewDate.getUTCMonth(),s=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),t=this.viewDate.getUTCSeconds();if(o.is(".old")){if(p===0){p=11;q-=1}else{p-=1}}else{if(o.is(".new")){if(p==11){p=0;q+=1}else{p+=1}}}this.viewDate.setUTCFullYear(q);this.viewDate.setUTCMonth(p,r);this.element.trigger({type:"changeDay",date:this.viewDate});if(this.viewSelect>=2){this._setDate(h(q,p,r,s,l,t,0))}}var m=this.viewMode;this.showMode(-1);this.fill();if(m==this.viewMode&&this.autoclose){this.hide()}break}}},_setDate:function(j,l){if(!l||l=="date"){this.date=j}if(!l||l=="view"){this.viewDate=j}this.fill();this.setValue();var k;if(this.isInput){k=this.element}else{if(this.component){k=this.element.find("input")}}if(k){k.change();if(this.autoclose&&(!l||l=="date")){}}this.element.trigger({type:"changeDate",date:this.getDate()});if(j==null){this.date=this.viewDate}},moveMinute:function(k,j){if(!j){return k}var l=new Date(k.valueOf());l.setUTCMinutes(l.getUTCMinutes()+(j*this.minuteStep));return l},moveHour:function(k,j){if(!j){return k}var l=new Date(k.valueOf());l.setUTCHours(l.getUTCHours()+j);return l},moveDate:function(k,j){if(!j){return k}var l=new Date(k.valueOf());l.setUTCDate(l.getUTCDate()+j);return l},moveMonth:function(j,k){if(!k){return j}var n=new Date(j.valueOf()),r=n.getUTCDate(),o=n.getUTCMonth(),m=Math.abs(k),q,p;k=k>0?1:-1;if(m==1){p=k==-1?function(){return n.getUTCMonth()==o}:function(){return n.getUTCMonth()!=q};q=o+k;n.setUTCMonth(q);if(q<0||q>11){q=(q+12)%12}}else{for(var l=0;l=this.startDate&&j<=this.endDate},keydown:function(n){if(this.picker.is(":not(:visible)")){if(n.keyCode==27){this.show()}return}var p=false,k,q,o,r,j;switch(n.keyCode){case 27:this.hide();n.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation){break}k=n.keyCode==37?-1:1;viewMode=this.viewMode;if(n.ctrlKey){viewMode+=2}else{if(n.shiftKey){viewMode+=1}}if(viewMode==4){r=this.moveYear(this.date,k);j=this.moveYear(this.viewDate,k)}else{if(viewMode==3){r=this.moveMonth(this.date,k);j=this.moveMonth(this.viewDate,k)}else{if(viewMode==2){r=this.moveDate(this.date,k);j=this.moveDate(this.viewDate,k)}else{if(viewMode==1){r=this.moveHour(this.date,k);j=this.moveHour(this.viewDate,k)}else{if(viewMode==0){r=this.moveMinute(this.date,k);j=this.moveMinute(this.viewDate,k)}}}}}if(this.dateWithinRange(r)){this.date=r;this.viewDate=j;this.setValue();this.update();n.preventDefault();p=true}break;case 38:case 40:if(!this.keyboardNavigation){break}k=n.keyCode==38?-1:1;viewMode=this.viewMode;if(n.ctrlKey){viewMode+=2}else{if(n.shiftKey){viewMode+=1}}if(viewMode==4){r=this.moveYear(this.date,k);j=this.moveYear(this.viewDate,k)}else{if(viewMode==3){r=this.moveMonth(this.date,k);j=this.moveMonth(this.viewDate,k)}else{if(viewMode==2){r=this.moveDate(this.date,k*7);j=this.moveDate(this.viewDate,k*7)}else{if(viewMode==1){if(this.showMeridian){r=this.moveHour(this.date,k*6);j=this.moveHour(this.viewDate,k*6)}else{r=this.moveHour(this.date,k*4);j=this.moveHour(this.viewDate,k*4)}}else{if(viewMode==0){r=this.moveMinute(this.date,k*4);j=this.moveMinute(this.viewDate,k*4)}}}}}if(this.dateWithinRange(r)){this.date=r;this.viewDate=j;this.setValue();this.update();n.preventDefault();p=true}break;case 13:if(this.viewMode!=0){var m=this.viewMode;this.showMode(-1);this.fill();if(m==this.viewMode&&this.autoclose){this.hide()}}else{this.fill();if(this.autoclose){this.hide()}}n.preventDefault();break;case 9:this.hide();break}if(p){var l;if(this.isInput){l=this.element}else{if(this.component){l=this.element.find("input")}}if(l){l.change()}this.element.trigger({type:"changeDate",date:this.getDate()})}},showMode:function(j){if(j){var k=Math.max(0,Math.min(g.modes.length-1,this.viewMode+j));if(k>=this.minView&&k<=this.maxView){this.element.trigger({type:"changeMode",date:this.viewDate,oldViewMode:this.viewMode,newViewMode:k});this.viewMode=k}}this.picker.find(">div").hide().filter(".datetimepicker-"+g.modes[this.viewMode].clsName).css("display","block");this.updateNavArrows()},reset:function(j){this._setDate(null,"date")},convertViewModeText:function(j){switch(j){case 4:return"decade";case 3:return"year";case 2:return"month";case 1:return"day";case 0:return"hour"}}};var b=f.fn.datetimepicker;f.fn.datetimepicker=function(l){var j=Array.apply(null,arguments);j.shift();var k;this.each(function(){var o=f(this),n=o.data("datetimepicker"),m=typeof l=="object"&&l;if(!n){o.data("datetimepicker",(n=new i(this,f.extend({},f.fn.datetimepicker.defaults,m))))}if(typeof l=="string"&&typeof n[l]=="function"){k=n[l].apply(n,j);if(k!==c){return false}}});if(k!==c){return k}else{return this}};f.fn.datetimepicker.defaults={};f.fn.datetimepicker.Constructor=i;var a=f.fn.datetimepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["am","pm"],suffix:["st","nd","rd","th"],today:"Today",clear:"Clear"}};var g={modes:[{clsName:"minutes",navFnc:"Hours",navStep:1},{clsName:"hours",navFnc:"Date",navStep:1},{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(j){return(((j%4===0)&&(j%100!==0))||(j%400===0))},getDaysInMonth:function(j,k){return[31,(g.isLeapYear(j)?29:28),31,30,31,30,31,31,30,31,30,31][k]},getDefaultFormat:function(j,k){if(j=="standard"){if(k=="input"){return"yyyy-mm-dd hh:ii"}else{return"yyyy-mm-dd hh:ii:ss"}}else{if(j=="php"){if(k=="input"){return"Y-m-d H:i"}else{return"Y-m-d H:i:s"}}else{throw new Error("Invalid format type.")}}},validParts:function(j){if(j=="standard"){return/t|hh?|HH?|p|P|z|Z|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g}else{if(j=="php"){return/[dDjlNwzFmMnStyYaABgGhHis]/g}else{throw new Error("Invalid format type.")}}},nonpunctuation:/[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,parseFormat:function(m,k){var j=m.replace(this.validParts(k),"\0").split("\0"),l=m.match(this.validParts(k));if(!j||!j.length||!l||l.length==0){throw new Error("Invalid date format.")}return{separators:j,parts:l}},parseDate:function(A,y,v,j,r){if(A instanceof Date){var u=new Date(A.valueOf()-A.getTimezoneOffset()*60000);u.setMilliseconds(0);return u}if(/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(A)){y=this.parseFormat("yyyy-mm-dd",j)}if(/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(A)){y=this.parseFormat("yyyy-mm-dd hh:ii",j)}if(/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(A)){y=this.parseFormat("yyyy-mm-dd hh:ii:ss",j)}if(/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(A)){var l=/([-+]\d+)([dmwy])/,q=A.match(/([-+]\d+)([dmwy])/g),t,p;A=new Date();for(var x=0;x',headTemplateV3:' ',contTemplate:'',footTemplate:''};g.template='
'+g.headTemplate+g.contTemplate+g.footTemplate+'
'+g.headTemplate+g.contTemplate+g.footTemplate+'
'+g.headTemplate+""+g.footTemplate+'
'+g.headTemplate+g.contTemplate+g.footTemplate+'
'+g.headTemplate+g.contTemplate+g.footTemplate+"
";g.templateV3='
'+g.headTemplateV3+g.contTemplate+g.footTemplate+'
'+g.headTemplateV3+g.contTemplate+g.footTemplate+'
'+g.headTemplateV3+""+g.footTemplate+'
'+g.headTemplateV3+g.contTemplate+g.footTemplate+'
'+g.headTemplateV3+g.contTemplate+g.footTemplate+"
";f.fn.datetimepicker.DPGlobal=g;f.fn.datetimepicker.noConflict=function(){f.fn.datetimepicker=b;return this};f(document).on("focus.datetimepicker.data-api click.datetimepicker.data-api",'[data-provide="datetimepicker"]',function(k){var j=f(this);if(j.data("datetimepicker")){return}k.preventDefault();j.datetimepicker("show")});f(function(){f('[data-provide="datetimepicker-inline"]').datetimepicker()})})); -/*The MIT License (MIT) - -Copyright (c) 2014 https://github.com/kayalshri/ - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE.*/ - -(function($){ - $.fn.extend({ - tableExport: function(options) { - var defaults = { - separator: ',', - ignoreColumn: [], - tableName:'yourTableName', - type:'csv', - pdfFontSize:14, - pdfLeftMargin:20, - escape:'true', - htmlContent:'false', - consoleLog:'false' - }; - - var options = $.extend(defaults, options); - var el = this; - - if(defaults.type == 'csv' || defaults.type == 'txt'){ - - // Header - var tdData =""; - $(el).find('thead').find('tr').each(function() { - tdData += "\n"; - $(this).filter(':visible').find('th').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - tdData += '"' + parseString($(this)) + '"' + defaults.separator; - } - } - - }); - tdData = $.trim(tdData); - tdData = $.trim(tdData).substring(0, tdData.length -1); - }); - - // Row vs Column - $(el).find('tbody').find('tr').each(function() { - tdData += "\n"; - $(this).filter(':visible').find('td').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - tdData += '"'+ parseString($(this)) + '"'+ defaults.separator; - } - } - }); - //tdData = $.trim(tdData); - tdData = $.trim(tdData).substring(0, tdData.length -1); - }); - - //output - if(defaults.consoleLog == 'true'){ - console.log(tdData); - } - var base64data = "base64," + $.base64.encode(tdData); - window.open('data:application/'+defaults.type+';filename=exportData;' + base64data); - }else if(defaults.type == 'sql'){ - - // Header - var tdData ="INSERT INTO `"+defaults.tableName+"` ("; - $(el).find('thead').find('tr').each(function() { - - $(this).filter(':visible').find('th').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - tdData += '`' + parseString($(this)) + '`,' ; - } - } - - }); - tdData = $.trim(tdData); - tdData = $.trim(tdData).substring(0, tdData.length -1); - }); - tdData += ") VALUES "; - // Row vs Column - $(el).find('tbody').find('tr').each(function() { - tdData += "("; - $(this).filter(':visible').find('td').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - tdData += '"'+ parseString($(this)) + '",'; - } - } - }); - - tdData = $.trim(tdData).substring(0, tdData.length -1); - tdData += "),"; - }); - tdData = $.trim(tdData).substring(0, tdData.length -1); - tdData += ";"; - - //output - //console.log(tdData); - - if(defaults.consoleLog == 'true'){ - console.log(tdData); - } - - var base64data = "base64," + $.base64.encode(tdData); - window.open('data:application/sql;filename=exportData;' + base64data); - - - }else if(defaults.type == 'json'){ - - var jsonHeaderArray = []; - $(el).find('thead').find('tr').each(function() { - var tdData =""; - var jsonArrayTd = []; - - $(this).filter(':visible').find('th').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - jsonArrayTd.push(parseString($(this))); - } - } - }); - jsonHeaderArray.push(jsonArrayTd); - - }); - - var jsonArray = []; - $(el).find('tbody').find('tr').each(function() { - var tdData =""; - var jsonArrayTd = []; - - $(this).filter(':visible').find('td').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - jsonArrayTd.push(parseString($(this))); - } - } - }); - jsonArray.push(jsonArrayTd); - - }); - - var jsonExportArray =[]; - jsonExportArray.push({header:jsonHeaderArray,data:jsonArray}); - - //Return as JSON - //console.log(JSON.stringify(jsonExportArray)); - - //Return as Array - //console.log(jsonExportArray); - if(defaults.consoleLog == 'true'){ - console.log(JSON.stringify(jsonExportArray)); - } - var base64data = "base64," + $.base64.encode(JSON.stringify(jsonExportArray)); - window.open('data:application/json;filename=exportData;' + base64data); - }else if(defaults.type == 'xml'){ - - var xml = ''; - xml += ''; - - // Header - $(el).find('thead').find('tr').each(function() { - $(this).filter(':visible').find('th').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - xml += "" + parseString($(this)) + ""; - } - } - }); - }); - xml += ''; - - // Row Vs Column - var rowCount=1; - $(el).find('tbody').find('tr').each(function() { - xml += ''; - var colCount=0; - $(this).filter(':visible').find('td').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - xml += ""+parseString($(this))+""; - } - } - colCount++; - }); - rowCount++; - xml += ''; - }); - xml += '' - - if(defaults.consoleLog == 'true'){ - console.log(xml); - } - - var base64data = "base64," + $.base64.encode(xml); - window.open('data:application/xml;filename=exportData;' + base64data); - - }else if(defaults.type == 'excel' || defaults.type == 'doc'|| defaults.type == 'powerpoint' ){ - //console.log($(this).html()); - var excel=""; - // Header - $(el).find('thead').find('tr').each(function() { - excel += ""; - $(this).filter(':visible').find('th').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - excel += ""; - } - } - }); - excel += ''; - - }); - - - // Row Vs Column - var rowCount=1; - $(el).find('tbody').find('tr').each(function() { - excel += ""; - var colCount=0; - $(this).filter(':visible').find('td').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - excel += ""; - } - } - colCount++; - }); - rowCount++; - excel += ''; - }); - excel += '
" + parseString($(this))+ "
"+parseString($(this))+"
' - - if(defaults.consoleLog == 'true'){ - console.log(excel); - } - - var excelFile = ""; - excelFile += ""; - excelFile += ""; - excelFile += ""; - excelFile += ""; - excelFile += excel; - excelFile += ""; - excelFile += ""; - - var base64data = "base64," + $.base64.encode(excelFile); - window.open('data:application/vnd.ms-'+defaults.type+';filename=exportData.doc;' + base64data); - - }else if(defaults.type == 'png'){ - html2canvas($(el), { - onrendered: function(canvas) { - var img = canvas.toDataURL("image/png"); - window.open(img); - - - } - }); - }else if(defaults.type == 'pdf'){ - - var doc = new jsPDF('p','pt', 'a4', true); - doc.setFontSize(defaults.pdfFontSize); - - // Header - var startColPosition=defaults.pdfLeftMargin; - $(el).find('thead').find('tr').each(function() { - $(this).filter(':visible').find('th').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - var colPosition = startColPosition+ (index * 50); - doc.text(colPosition,20, parseString($(this))); - } - } - }); - }); - - - // Row Vs Column - var startRowPosition = 20; var page =1;var rowPosition=0; - $(el).find('tbody').find('tr').each(function(index,data) { - rowCalc = index+1; - - if (rowCalc % 26 == 0){ - doc.addPage(); - page++; - startRowPosition=startRowPosition+10; - } - rowPosition=(startRowPosition + (rowCalc * 10)) - ((page -1) * 280); - - $(this).filter(':visible').find('td').each(function(index,data) { - if ($(this).css('display') != 'none'){ - if(defaults.ignoreColumn.indexOf(index) == -1){ - var colPosition = startColPosition+ (index * 50); - doc.text(colPosition,rowPosition, parseString($(this))); - } - } - - }); - - }); - - // Output as Data URI - doc.output('datauri'); - - } - - - function parseString(data){ - - if(defaults.htmlContent == 'true'){ - content_data = data.html().trim(); - }else{ - content_data = data.text().trim(); - } - - if(defaults.escape == 'true'){ - content_data = escape(content_data); - } - - - - return content_data; - } - - } - }); - })(jQuery); - -;function set_feedback(text, classname, keep_displayed) -{ - if(text) - { - $('#feedback_bar').removeClass().addClass(classname).html(text).css('opacity','1'); - - if(!keep_displayed) - { - $('#feedback_bar').fadeTo(5000, 1).fadeTo("fast",0); - } - } - else - { - $('#feedback_bar').css('opacity','0'); - } -} -;/* - * imgPreview jQuery plugin - * Copyright (c) 2009 James Padolsey - * j@qd9.co.uk | http://james.padolsey.com - * Dual licensed under MIT and GPL. - * Updated: 09/02/09 - * @author James Padolsey - * @version 0.22 - */ -(function($){ - - $.expr[':'].linkingToImage = function(elem, index, match){ - // This will return true if the specified attribute contains a valid link to an image: - return !! ($(elem).attr(match[3]) && $(elem).attr(match[3]).match(/\.(gif|jpe?g|png|bmp)$/i)); - }; - - $.fn.imgPreview = function(userDefinedSettings){ - - var s = $.extend({ - - /* DEFAULTS */ - - // CSS to be applied to image: - imgCSS: {}, - // Distance between cursor and preview: - distanceFromCursor: {top:10, left:10}, - // Boolean, whether or not to preload images: - preloadImages: true, - // Callback: run when link is hovered: container is shown: - onShow: function(){}, - // Callback: container is hidden: - onHide: function(){}, - // Callback: Run when image within container has loaded: - onLoad: function(){}, - // ID to give to container (for CSS styling): - containerID: 'imgPreviewContainer', - // Class to be given to container while image is loading: - containerLoadingClass: 'loading', - // Prefix (if using thumbnails), e.g. 'thumb_' - thumbPrefix: '', - // Where to retrieve the image from: - srcAttr: 'href' - - }, userDefinedSettings), - - $container = $('
').attr('id', s.containerID) - .append('').hide() - .css('position','absolute') - .appendTo('body'), - - $img = $('img', $container).css(s.imgCSS), - - // Get all valid elements (linking to images / ATTR with image link): - $collection = this.filter(':linkingToImage(' + s.srcAttr + ')'); - - // Re-usable means to add prefix (from setting): - function addPrefix(src) { - return src && src.replace(/(\/?)([^\/]+)$/,'$1' + s.thumbPrefix + '$2'); - } - - if (s.preloadImages) { - (function(i){ - var tempIMG = new Image(), - callee = arguments.callee; - var src = $($collection[i]).attr(s.srcAttr) - if (src) - { - tempIMG.src = addPrefix(src); - tempIMG.onload = function(){ - $collection[i + 1] && callee(i + 1); - }; - } - })(0); - } - - $collection - .mousemove(function(e){ - - $container.css({ - top: e.pageY + s.distanceFromCursor.top + 'px', - left: e.pageX + s.distanceFromCursor.left + 'px' - }); - - }) - .hover(function(){ - - var link = this; - $container - .addClass(s.containerLoadingClass) - .show(); - $img - .load(function(){ - $container.removeClass(s.containerLoadingClass); - $img.show(); - s.onLoad.call($img[0], link); - }) - .attr( 'src' , addPrefix($(link).attr(s.srcAttr)) ); - s.onShow.call($container[0], link); - - }, function(){ - - $container.hide(); - $img.unbind('load').attr('src','').hide(); - s.onHide.call($container[0], this); - - }); - - // Return full selection, not $collection! - return this; - - }; - -})(jQuery);;(function(dialog_support, $) { - - var btn_id, dialog_ref; - - var hide = function() { - dialog_ref.close(); - }; - - var clicked_id = function() { - return btn_id; - }; - - var submit = function(button_id) { - return function(dlog_ref) { - btn_id = button_id; - dialog_ref = dlog_ref; - if (button_id == 'submit') { - $('form', dlog_ref.$modalBody).first().submit(); - } - } - }; - - var button_class = { - 'submit' : 'btn-primary', - 'delete' : 'btn-danger' - }; - - var init = function(selector) { - - var buttons = function(event) { - var buttons = []; - var dialog_class = 'modal-dlg'; - $.each($(this).attr('class').split(/\s+/), function(classIndex, className) { - var width_class = className.split("modal-dlg-"); - if (width_class && width_class.length > 1) { - dialog_class = className; - } - var btn_class = className.split("modal-btn-"); - if (btn_class && btn_class.length > 1) { - var btn_name = btn_class[1]; - var is_submit = btn_name == 'submit'; - buttons.push({ - id: btn_name, - label: btn_name.charAt(0).toUpperCase() + btn_name.slice(1), - cssClass: button_class[btn_name], - hotkey: is_submit ? 13 : undefined, // Enter. - action: submit(btn_name) - }); - } - }); - - !buttons.length && buttons.push({ - id: 'close', - label: 'Close', - cssClass: 'btn-primary', - action: function(dialog_ref) { - dialog_ref.close(); - } - }); - return { buttons: buttons, cssClass: dialog_class}; - }; - - $(selector).each(function(index, $element) { - - return $(selector).off('click').on('click', function(event) { - var $link = $(event.target); - $link = !$link.is("a, button") ? $link.parents("a") : $link ; - BootstrapDialog.show($.extend({ - title: $link.attr('title'), - message: (function() { - var node = $('
'); - $.get($link.attr('href') || $link.data('href'), function(data) { - node.html(data); - }); - return node; - }) - }, buttons.call(this, event))); - - return false; - }); - }); - }; - - dialog_support.error = { - errorClass: "has-error", - errorLabelContainer: "#error_message_box", - wrapper: "li", - highlight: function (e) { - $(e).closest('.form-group').addClass('has-error'); - }, - unhighlight: function (e) { - $(e).closest('.form-group').removeClass('has-error'); - } - }; - - $.extend(dialog_support, { - init: init, - submit: submit, - hide: hide, - clicked_id: clicked_id - }); - -})(window.dialog_support = window.dialog_support || {}, jQuery); - -(function(table_support, $) { - - var enable_actions = function(callback) { - return function() { - var selection_empty = selected_rows().length == 0; - $("#toolbar button:not(.dropdown-toggle)").attr('disabled', selection_empty); - typeof callback == 'function' && callback(); - } - }; - - var table = function() { - return $("#table").data('bootstrap.table'); - } - - var selected_ids = function () { - return $.map(table().getSelections(), function (element) { - return element[options.uniqueId || 'id']; - }); - }; - - var selected_rows = function () { - return $("#table td input:checkbox:checked").parents("tr"); - }; - - var row_selector = function(id) { - return "tr[data-uniqueid='" + id + "']"; - }; - - var rows_selector = function(ids) { - var selectors = []; - ids = ids instanceof Array ? ids : ("" + ids).split(":"); - $.each(ids, function(index, element) { - selectors.push(row_selector(element)); - }); - return selectors;; - }; - - var highlight_row = function (id, color) { - $(rows_selector(id)).each(function(index, element) { - var original = $(element).css('backgroundColor'); - $(element).find("td").animate({backgroundColor: color || '#e1ffdd'}, "slow", "linear") - .animate({backgroundColor: color || '#e1ffdd'}, 5000) - .animate({backgroundColor: original}, "slow", "linear"); - }); - }; - - var do_delete = function (url, ids) { - if (confirm($.fn.bootstrapTable.defaults.formatConfirmDelete())) { - $.post((url || options.resource) + '/delete', {'ids[]': ids || selected_ids()}, function (response) { - //delete was successful, remove checkbox rows - if (response.success) { - var selector = ids ? row_selector(ids) : selected_rows(); - table().collapseAllRows(); - $(selector).each(function (index, element) { - $(this).find("td").animate({backgroundColor: "green"}, 1200, "linear") - .end().animate({opacity: 0}, 1200, "linear", function () { - table().remove({ - field: 'id', - values: selected_ids() - }); - $(this).remove(); - if (index == $(selector).length - 1) { - refresh(); - enable_actions(); - } - }); - }); - set_feedback(response.message, 'alert alert-dismissible alert-success', false); - } else { - set_feedback(response.message, 'alert alert-dismissible alert-danger', true); - } - }, "json"); - } else { - return false; - } - }; - - var load_success = function(callback) { - return function(response) { - typeof options.load_callback == 'function' && options.load_callback(); - options.load_callback = undefined; - typeof callback == 'function' && callback.call(this, response); - } - }; - - var options; - - var toggle_column_visbility = function() { - if (localStorage[options.employee_id]) { - var user_settings = JSON.parse(localStorage[options.employee_id]); - user_settings[options.resource] && $.each(user_settings[options.resource], function(index, element) { - element ? table().showColumn(index) : table().hideColumn(index); - }); - } - }; - - var init = function (_options) { - options = _options; - enable_actions = enable_actions(options.enableActions); - $('#table').bootstrapTable($.extend(options, { - columns: options.headers, - url: options.resource + '/search', - sidePagination: 'server', - pageSize: options.pageSize, - striped: true, - pagination: true, - search: options.resource || false, - showColumns: true, - clickToSelect: true, - showExport: true, - onPageChange: load_success(options.onLoadSuccess), - toolbar: '#toolbar', - uniqueId: options.uniqueId || 'id', - onCheck: enable_actions, - onUncheck: enable_actions, - onCheckAll: enable_actions, - onUncheckAll: enable_actions, - onLoadSuccess: load_success(options.onLoadSuccess), - onPostBody: function() { - dialog_support.init("a.modal-dlg, button.modal-dlg"); - }, - onColumnSwitch : function(field, checked) { - var user_settings = localStorage[options.employee_id]; - user_settings = (user_settings && JSON.parse(user_settings)) || {}; - user_settings[options.resource] = user_settings[options.resource] || {}; - user_settings[options.resource][field] = checked; - localStorage[options.employee_id] = JSON.stringify(user_settings); - }, - queryParamsType: 'limit', - iconSize: 'sm', - silentSort: true, - paginationVAlign: 'bottom' - })); - enable_actions(); - init_delete(); - toggle_column_visbility(); - }; - - var init_delete = function (confirmMessage) { - $("#delete").click(function (event) { - do_delete(); - }); - }; - - var refresh = function() { - table().refresh(); - } - - var submit_handler = function(url) { - return function (resource, response) { - var id = response.id; - - if (!response.success) { - set_feedback(response.message, 'alert alert-dismissible alert-danger', true); - } else { - var message = response.message; - var selector = rows_selector(response.id); - if ($(selector.join(",")).length > 0) { - var ids = response.id.split(":"); - $.get({ - url: [url || resource + '/get_row', id].join("/"), - success: function (response) { - $.each(selector, function (index, element) { - var id = $(element).data('uniqueid'); - table().updateByUniqueId({id: id, row: response[id]}); - dialog_support.init(element + " a.modal-dlg"); - }); - highlight_row(ids); - }, - dataType: 'json' - }); - } else { - // call hightlight function once after refresh - options.load_callback = function () { - enable_actions(); - highlight_row(id); - }; - refresh(); - } - set_feedback(message, 'alert alert-dismissible alert-success', false); - } - }; - }; - - var handle_submit = submit_handler(); - - $.extend(table_support, { - submit_handler: function(url) { - this.handle_submit = submit_handler(url); - }, - handle_submit: handle_submit, - init: init, - do_delete: do_delete, - refresh : refresh, - selected_ids : selected_ids, - }); - -})(window.table_support = window.table_support || {}, jQuery);;(function($) { - - function http_s(url) - { - return document.location.protocol + '//' + url; - } - - var url = http_s('nominatim.openstreetmap.org/search'); - - var handle_auto_completion = function(fields) { - return function(event, ui) { - var results = ui.item.results; - if (results != null && results.length > 0) { - // handle auto completion - for(var i in fields) { - $("#" + fields[i]).val(results[i]); - } - return false; - } - return true; - }; - }; - - var create_parser = function(field_name, parse_format) - { - var parse_field = function(format, address) - { - var fields = []; - $.each(format.split("|"), function(key, value) - { - if (address[value] && fields.length < 2 && $.inArray(address[value], fields) === -1) - { - fields.push(address[value]); - } - }); - return fields[0] + (fields[1] ? ' (' + fields[1] + ')' : ''); - }; - - return function(data) - { - var parsed = []; - $.each(data, function(index, value) - { - var row = []; - var address = value.address; - $.each(parse_format, function(key, format) - { - row.push(parse_field(format, address)); - }); - parsed[index] = { - label: row.join(", "), - results: row, - value: address[field_name] - }; - }); - return parsed; - }; - }; - - var init = function(options) { - - var default_params = function(id, key, language) - { - return function() { - var result = { - format: 'json', - limit: 5, - addressdetails: 1, - countrycodes: options.country_codes, - 'accept-language' : language || navigator.language - }; - result[key || id] = $("#"+id).val(); - return result; - } - - }; - - $.each(options.fields, function(key, value) - { - var handle_field_completion = handle_auto_completion(value.dependencies); - - $("#" + key).autocomplete({ - source: function (request, response) { - var params = default_params(key, value.response && value.response.field, options.language); - var request_params = {q: request.term}; - $.each(options.extra_params, function(key, param) { - request_params[key] = typeof param == "function" ? param() : param; - }); - - $.ajax({ - type: "GET", - url: url, - dataType: "json", - data: $.extend(request_params, params()), - success: function(data) { - response($.map(data, function(item) { - return (create_parser(key, (value.response && value.response.format) || value.dependencies))(data) - })) - } - }); - }, - minChars:3, - delay:500, - appendTo: '.modal-content', - select: handle_field_completion - }); - - }); - }; - - var nominatim = { - - init : init - - }; - - window['nominatim'] = nominatim; - -})(jQuery);;/* - * Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io) - * and Contributors (http://phpjs.org/authors) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -function phpjsDate(format, timestamp) { - // discuss at: http://phpjs.org/functions/date/ - // original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) - // original by: gettimeofday - // parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html) - // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // improved by: MeEtc (http://yass.meetcweb.com) - // improved by: Brad Touesnard - // improved by: Tim Wiel - // improved by: Bryan Elliott - // improved by: David Randall - // improved by: Theriault - // improved by: Theriault - // improved by: Brett Zamir (http://brett-zamir.me) - // improved by: Theriault - // improved by: Thomas Beaucourt (http://www.webapp.fr) - // improved by: JT - // improved by: Theriault - // improved by: Rafal Kukawski (http://blog.kukawski.pl) - // improved by: Theriault - // input by: Brett Zamir (http://brett-zamir.me) - // input by: majak - // input by: Alex - // input by: Martin - // input by: Alex Wilson - // input by: Haravikk - // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // bugfixed by: majak - // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // bugfixed by: Brett Zamir (http://brett-zamir.me) - // bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122) - // bugfixed by: Chris (http://www.devotis.nl/) - // note: Uses global: php_js to store the default timezone - // note: Although the function potentially allows timezone info (see notes), it currently does not set - // note: per a timezone specified by date_default_timezone_set(). Implementers might use - // note: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function - // note: in order to adjust the dates in this function (or our other date functions!) accordingly - // example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); - // returns 1: '09:09:40 m is month' - // example 2: date('F j, Y, g:i a', 1062462400); - // returns 2: 'September 2, 2003, 2:26 am' - // example 3: date('Y W o', 1062462400); - // returns 3: '2003 36 2003' - // example 4: x = date('Y m d', (new Date()).getTime()/1000); - // example 4: (x+'').length == 10 // 2009 01 09 - // returns 4: true - // example 5: date('W', 1104534000); - // returns 5: '53' - // example 6: date('B t', 1104534000); - // returns 6: '999 31' - // example 7: date('W U', 1293750000.82); // 2010-12-31 - // returns 7: '52 1293750000' - // example 8: date('W', 1293836400); // 2011-01-01 - // returns 8: '52' - // example 9: date('W Y-m-d', 1293974054); // 2011-01-02 - // returns 9: '52 2011-01-02' - - var that = this; - var jsdate, f; - // Keep this here (works, but for code commented-out below for file size reasons) - // var tal= []; - var txt_words = [ - 'Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur', - 'January', 'February', 'March', 'April', 'May', 'June', - 'July', 'August', 'September', 'October', 'November', 'December' - ]; - // trailing backslash -> (dropped) - // a backslash followed by any character (including backslash) -> the character - // empty string -> empty string - var formatChr = /\\?(.?)/gi; - var formatChrCb = function(t, s) { - return f[t] ? f[t]() : s; - }; - var _pad = function(n, c) { - n = String(n); - while (n.length < c) { - n = '0' + n; - } - return n; - }; - f = { - // Day - d : function() { - // Day of month w/leading 0; 01..31 - return _pad(f.j(), 2); - }, - D : function() { - // Shorthand day name; Mon...Sun - return f.l() - .slice(0, 3); - }, - j : function() { - // Day of month; 1..31 - return jsdate.getDate(); - }, - l : function() { - // Full day name; Monday...Sunday - return txt_words[f.w()] + 'day'; - }, - N : function() { - // ISO-8601 day of week; 1[Mon]..7[Sun] - return f.w() || 7; - }, - S : function() { - // Ordinal suffix for day of month; st, nd, rd, th - var j = f.j(); - var i = j % 10; - if (i <= 3 && parseInt((j % 100) / 10, 10) == 1) { - i = 0; - } - return ['st', 'nd', 'rd'][i - 1] || 'th'; - }, - w : function() { - // Day of week; 0[Sun]..6[Sat] - return jsdate.getDay(); - }, - z : function() { - // Day of year; 0..365 - var a = new Date(f.Y(), f.n() - 1, f.j()); - var b = new Date(f.Y(), 0, 1); - return Math.round((a - b) / 864e5); - }, - - // Week - W : function() { - // ISO-8601 week number - var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3); - var b = new Date(a.getFullYear(), 0, 4); - return _pad(1 + Math.round((a - b) / 864e5 / 7), 2); - }, - - // Month - F : function() { - // Full month name; January...December - return txt_words[6 + f.n()]; - }, - m : function() { - // Month w/leading 0; 01...12 - return _pad(f.n(), 2); - }, - M : function() { - // Shorthand month name; Jan...Dec - return f.F() - .slice(0, 3); - }, - n : function() { - // Month; 1...12 - return jsdate.getMonth() + 1; - }, - t : function() { - // Days in month; 28...31 - return (new Date(f.Y(), f.n(), 0)) - .getDate(); - }, - - // Year - L : function() { - // Is leap year?; 0 or 1 - var j = f.Y(); - return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0; - }, - o : function() { - // ISO-8601 year - var n = f.n(); - var W = f.W(); - var Y = f.Y(); - return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0); - }, - Y : function() { - // Full year; e.g. 1980...2010 - return jsdate.getFullYear(); - }, - y : function() { - // Last two digits of year; 00...99 - return f.Y() - .toString() - .slice(-2); - }, - - // Time - a : function() { - // am or pm - return jsdate.getHours() > 11 ? 'pm' : 'am'; - }, - A : function() { - // AM or PM - return f.a() - .toUpperCase(); - }, - B : function() { - // Swatch Internet time; 000..999 - var H = jsdate.getUTCHours() * 36e2; - // Hours - var i = jsdate.getUTCMinutes() * 60; - // Minutes - // Seconds - var s = jsdate.getUTCSeconds(); - return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3); - }, - g : function() { - // 12-Hours; 1..12 - return f.G() % 12 || 12; - }, - G : function() { - // 24-Hours; 0..23 - return jsdate.getHours(); - }, - h : function() { - // 12-Hours w/leading 0; 01..12 - return _pad(f.g(), 2); - }, - H : function() { - // 24-Hours w/leading 0; 00..23 - return _pad(f.G(), 2); - }, - i : function() { - // Minutes w/leading 0; 00..59 - return _pad(jsdate.getMinutes(), 2); - }, - s : function() { - // Seconds w/leading 0; 00..59 - return _pad(jsdate.getSeconds(), 2); - }, - u : function() { - // Microseconds; 000000-999000 - return _pad(jsdate.getMilliseconds() * 1000, 6); - }, - - // Timezone - e : function() { - // Timezone identifier; e.g. Atlantic/Azores, ... - // The following works, but requires inclusion of the very large - // timezone_abbreviations_list() function. - /* return that.date_default_timezone_get(); - */ - throw 'Not supported (see source code of date() for timezone on how to add support)'; - }, - I : function() { - // DST observed?; 0 or 1 - // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. - // If they are not equal, then DST is observed. - var a = new Date(f.Y(), 0); - // Jan 1 - var c = Date.UTC(f.Y(), 0); - // Jan 1 UTC - var b = new Date(f.Y(), 6); - // Jul 1 - // Jul 1 UTC - var d = Date.UTC(f.Y(), 6); - return ((a - c) !== (b - d)) ? 1 : 0; - }, - O : function() { - // Difference to GMT in hour format; e.g. +0200 - var tzo = jsdate.getTimezoneOffset(); - var a = Math.abs(tzo); - return (tzo > 0 ? '-' : '+') + _pad(Math.floor(a / 60) * 100 + a % 60, 4); - }, - P : function() { - // Difference to GMT w/colon; e.g. +02:00 - var O = f.O(); - return (O.substr(0, 3) + ':' + O.substr(3, 2)); - }, - T : function() { - // Timezone abbreviation; e.g. EST, MDT, ... - // The following works, but requires inclusion of the very - // large timezone_abbreviations_list() function. - /* var abbr, i, os, _default; - if (!tal.length) { - tal = that.timezone_abbreviations_list(); - } - if (that.php_js && that.php_js.default_timezone) { - _default = that.php_js.default_timezone; - for (abbr in tal) { - for (i = 0; i < tal[abbr].length; i++) { - if (tal[abbr][i].timezone_id === _default) { - return abbr.toUpperCase(); - } - } - } - } - for (abbr in tal) { - for (i = 0; i < tal[abbr].length; i++) { - os = -jsdate.getTimezoneOffset() * 60; - if (tal[abbr][i].offset === os) { - return abbr.toUpperCase(); - } - } - } - */ - return 'UTC'; - }, - Z : function() { - // Timezone offset in seconds (-43200...50400) - return -jsdate.getTimezoneOffset() * 60; - }, - - // Full Date/Time - c : function() { - // ISO-8601 date. - return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb); - }, - r : function() { - // RFC 2822 - return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); - }, - U : function() { - // Seconds since UNIX epoch - return jsdate / 1000 | 0; - } - }; - this.date = function(format, timestamp) { - that = this; - jsdate = (timestamp === undefined ? new Date() : // Not provided - (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() - new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) - ); - return format.replace(formatChr, formatChrCb); - }; - return this.date(format, timestamp); -} \ No newline at end of file diff --git a/dist/opensourcepos.min.css b/dist/opensourcepos.min.css deleted file mode 100644 index 0bb126523..000000000 --- a/dist/opensourcepos.min.css +++ /dev/null @@ -1,18 +0,0 @@ -.daterangepicker.single .calendar,.daterangepicker.single .ranges,.ranges{float:none}.daterangepicker{position:absolute;color:inherit;background:#fff;border-radius:4px;width:278px;padding:4px;margin-top:1px;top:100px;left:20px}.daterangepicker:after,.daterangepicker:before{position:absolute;display:inline-block;content:''}.daterangepicker:before{top:-7px;border-right:7px solid transparent;border-left:7px solid transparent;border-bottom:7px solid #ccc}.daterangepicker:after{top:-6px;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent}.daterangepicker.opensleft:before{right:9px}.daterangepicker.opensleft:after{right:10px}.daterangepicker.openscenter:after,.daterangepicker.openscenter:before{left:0;right:0;width:0;margin-left:auto;margin-right:auto}.daterangepicker.opensright:before{left:9px}.daterangepicker.opensright:after{left:10px}.daterangepicker.dropup{margin-top:-5px}.daterangepicker.dropup:before{top:initial;bottom:-7px;border-bottom:initial;border-top:7px solid #ccc}.daterangepicker.dropup:after{top:initial;bottom:-6px;border-bottom:initial;border-top:6px solid #fff}.daterangepicker.dropdown-menu{max-width:none;z-index:3001}.daterangepicker.show-calendar .calendar{display:block}.daterangepicker .calendar{display:none;max-width:270px;margin:4px}.daterangepicker .calendar.single .calendar-table{border:none}.daterangepicker .calendar td,.daterangepicker .calendar th{white-space:nowrap;text-align:center;min-width:32px}.daterangepicker .calendar-table{border:1px solid #fff;padding:4px;border-radius:4px;background:#fff}.daterangepicker table{width:100%;margin:0}.daterangepicker td,.daterangepicker th{text-align:center;width:20px;height:20px;border-radius:4px;border:1px solid transparent;white-space:nowrap;cursor:pointer}.daterangepicker td.available:hover,.daterangepicker th.available:hover{background:#eee}.daterangepicker td.week,.daterangepicker th.week{font-size:80%;color:#ccc}.daterangepicker td.off,.daterangepicker td.off.end-date,.daterangepicker td.off.in-range,.daterangepicker td.off.start-date{background-color:#fff;border-color:transparent;color:#999}.daterangepicker td.in-range{background-color:#ebf4f8;border-color:transparent;color:#000;border-radius:0}.daterangepicker td.start-date{border-radius:4px 0 0 4px}.daterangepicker td.end-date{border-radius:0 4px 4px 0}.daterangepicker td.start-date.end-date{border-radius:4px}.daterangepicker td.active,.daterangepicker td.active:hover{background-color:#357ebd;border-color:transparent;color:#fff}.daterangepicker th.month{width:auto}.daterangepicker option.disabled,.daterangepicker td.disabled{color:#999;cursor:not-allowed;text-decoration:line-through}.daterangepicker select.monthselect,.daterangepicker select.yearselect{font-size:12px;padding:1px;height:auto;margin:0;cursor:default}.daterangepicker select.monthselect{margin-right:2%;width:56%}.daterangepicker select.yearselect{width:40%}.daterangepicker select.ampmselect,.daterangepicker select.hourselect,.daterangepicker select.minuteselect,.daterangepicker select.secondselect{width:50px;margin-bottom:0}.daterangepicker .input-mini{border:1px solid #ccc;border-radius:4px;color:#555;height:30px;line-height:30px;display:block;vertical-align:middle;margin:0 0 5px;padding:0 6px 0 28px;width:100%}.daterangepicker .input-mini.active{border:1px solid #08c;border-radius:4px}.daterangepicker .daterangepicker_input{position:relative}.daterangepicker .daterangepicker_input i{position:absolute;left:8px;top:8px}.daterangepicker.rtl .input-mini{padding-right:28px;padding-left:6px}.daterangepicker.rtl .daterangepicker_input i{left:auto;right:8px}.daterangepicker .calendar-time{text-align:center;margin:5px auto;line-height:30px;position:relative;padding-left:28px}.daterangepicker .calendar-time select.disabled{color:#ccc;cursor:not-allowed}.ranges{font-size:11px;margin:4px;text-align:left}.ranges ul{list-style:none;margin:0 auto;padding:0;width:100%}.ranges li{font-size:13px;background:#f5f5f5;border:1px solid #f5f5f5;border-radius:4px;color:#08c;padding:3px 12px;margin-bottom:8px;cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li.disabled a,.bootstrap-select.btn-group.disabled,.bootstrap-select.btn-group>.disabled{cursor:not-allowed}.ranges li.active,.ranges li:hover{background:#08c;border:1px solid #08c;color:#fff}@media (min-width:564px){.daterangepicker.ltr .calendar.right .calendar-table,.daterangepicker.rtl .calendar.left .calendar-table{border-left:none;border-top-left-radius:0;border-bottom-left-radius:0}.daterangepicker.ltr .calendar.left .calendar-table,.daterangepicker.rtl .calendar.right .calendar-table{border-right:none;border-top-right-radius:0;border-bottom-right-radius:0}.daterangepicker{width:auto}.daterangepicker .ranges ul{width:160px}.daterangepicker.single .ranges ul{width:100%}.daterangepicker.single .calendar.left{clear:none}.daterangepicker.single.ltr .calendar,.daterangepicker.single.ltr .ranges{float:left}.daterangepicker.single.rtl .calendar,.daterangepicker.single.rtl .ranges{float:right}.daterangepicker.ltr{direction:ltr;text-align:left}.daterangepicker.ltr .calendar.left{clear:left;margin-right:0}.daterangepicker.ltr .calendar.right{margin-left:0}.daterangepicker.ltr .calendar.left .calendar-table,.daterangepicker.ltr .left .daterangepicker_input{padding-right:12px}.daterangepicker.ltr .calendar,.daterangepicker.ltr .ranges{float:left}.daterangepicker.rtl{direction:rtl;text-align:right}.daterangepicker.rtl .calendar.left{clear:right;margin-left:0}.daterangepicker.rtl .calendar.right{margin-right:0}.daterangepicker.rtl .calendar.left .calendar-table,.daterangepicker.rtl .left .daterangepicker_input{padding-left:12px}.daterangepicker.rtl .calendar,.daterangepicker.rtl .ranges{text-align:right;float:right}}@media (min-width:730px){.daterangepicker .ranges{width:auto}.daterangepicker.ltr .ranges{float:left}.daterangepicker.rtl .ranges{float:right}.daterangepicker .calendar.left{clear:none!important}}/*! - * Bootstrap-select v1.10.0 (http://silviomoreto.github.io/bootstrap-select) - * - * Copyright 2013-2016 bootstrap-select - * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE) - */select.bs-select-hidden,select.selectpicker{display:none!important}.bootstrap-select{width:220px\9}.bootstrap-select>.dropdown-toggle{width:100%;padding-right:25px;z-index:1}.bootstrap-select>select{position:absolute!important;bottom:0;left:50%;display:block!important;width:.5px!important;height:100%!important;padding:0!important;opacity:0!important;border:none}.bootstrap-select>select.mobile-device{top:0;left:0;display:block!important;width:100%!important;z-index:2}.error .bootstrap-select .dropdown-toggle,.has-error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select.btn-group[class*=col-] .dropdown-toggle,.bootstrap-select.form-control:not([class*=col-]),.form-inline .bootstrap-select.btn-group .form-control{width:100%}.bootstrap-select .dropdown-toggle:focus{outline:#333 dotted thin!important;outline:-webkit-focus-ring-color auto 5px!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none}.bootstrap-select.form-control.input-group-btn{z-index:auto}.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.btn-group.dropdown-menu-right,.bootstrap-select.btn-group[class*=col-].dropdown-menu-right,.row .bootstrap-select.btn-group[class*=col-].dropdown-menu-right{float:right}.form-group .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group{margin-bottom:0}.form-group-lg .bootstrap-select.btn-group.form-control,.form-group-sm .bootstrap-select.btn-group.form-control{padding:0}.bootstrap-select.btn-group.disabled:focus,.bootstrap-select.btn-group>.disabled:focus{outline:0!important}.bootstrap-select.btn-group.bs-container{position:absolute}.bootstrap-select.btn-group.bs-container .dropdown-menu{z-index:1060}.bootstrap-select.btn-group .dropdown-toggle .filter-option{display:inline-block;overflow:hidden;width:100%;text-align:left}.fixed-table-container .bs-checkbox,.fixed-table-container .no-records-found{text-align:center}.bootstrap-select.btn-group .dropdown-toggle .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;float:none;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li.active small{color:#fff}.bootstrap-select.btn-group .dropdown-menu li a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bootstrap-select.btn-group .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select.btn-group .dropdown-menu li a span.check-mark{display:none}.bootstrap-select.btn-group .dropdown-menu li a span.text{display:inline-block}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px;white-space:nowrap}.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option{position:static}.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{position:absolute;display:inline-block;right:15px;margin-top:5px}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle{z-index:1061}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid rgba(204,204,204,.2);border-bottom:0}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before{display:block}.bs-actionsbox,.bs-donebutton,.bs-searchbox{padding:4px 8px}.bs-actionsbox{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-donebutton,.bs-donebutton .btn-group button,.fixed-table-container table{width:100%}.bs-donebutton{float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.fixed-table-body thead th .th-inner,.table td,.table th{box-sizing:border-box}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox .form-control{margin-bottom:0;width:100%;float:none}.bootstrap-table .table{margin-bottom:0!important;border-bottom:1px solid #ddd;border-collapse:collapse!important;border-radius:1px}.bootstrap-table .table:not(.table-condensed),.bootstrap-table .table:not(.table-condensed)>tbody>tr>td,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.bootstrap-dialog.type-default .modal-header,.fixed-table-loading{background-color:#fff}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.btn-file,.fileinput .btn,.fileinput .thumbnail,.fileinput-filename{vertical-align:middle}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}.ct-golden-section:before,.ct-major-eleventh:before,.ct-major-second:before,.ct-major-seventh:before,.ct-major-sixth:before,.ct-major-tenth:before,.ct-major-third:before,.ct-major-twelfth:before,.ct-minor-second:before,.ct-minor-seventh:before,.ct-minor-third:before,.ct-octave:before,.ct-perfect-fifth:before,.ct-perfect-fourth:before,.ct-square:before{content:"";height:0}.bootstrap-dialog .modal-header{border-top-left-radius:4px;border-top-right-radius:4px}.bootstrap-dialog .bootstrap-dialog-title{color:#fff;display:inline-block;font-size:16px}.bootstrap-dialog .bootstrap-dialog-message{font-size:14px}.bootstrap-dialog .bootstrap-dialog-button-icon{margin-right:3px}.bootstrap-dialog .bootstrap-dialog-close-button{font-size:20px;float:right;opacity:.9;filter:alpha(opacity=90)}.bootstrap-dialog .bootstrap-dialog-close-button:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100)}.bootstrap-dialog.type-default .bootstrap-dialog-title{color:#333}.bootstrap-dialog.type-info .modal-header{background-color:#5bc0de}.bootstrap-dialog.type-primary .modal-header{background-color:#337ab7}.bootstrap-dialog.type-success .modal-header{background-color:#5cb85c}.bootstrap-dialog.type-warning .modal-header{background-color:#f0ad4e}.bootstrap-dialog.type-danger .modal-header{background-color:#d9534f}.bootstrap-dialog.size-large .bootstrap-dialog-title{font-size:24px}.bootstrap-dialog.size-large .bootstrap-dialog-close-button{font-size:30px}.bootstrap-dialog.size-large .bootstrap-dialog-message,.navmenu-brand{font-size:18px}.bootstrap-dialog .icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(359deg)}}.ct-double-octave:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{line-height:1}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{fill:none;stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;width:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;width:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;width:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;width:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;width:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;width:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;width:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;width:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;width:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;width:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;width:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;width:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;width:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;width:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;width:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.chartist-tooltip:before,.ct-double-octave:before{content:"";width:0;height:0}.ct-double-octave:before{display:block;float:left;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}.btn-label,.chartist-tooltip,.fileinput,.fileinput .thumbnail{display:inline-block}.chartist-tooltip{position:absolute;opacity:0;min-width:5em;padding:.5em;background:#F4C63D;color:#453D3F;font-family:Oxygen,Helvetica,Arial,sans-serif;font-weight:700;text-align:center;pointer-events:none;z-index:1;-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;-o-transition:opacity .2s linear;transition:opacity .2s linear}.chartist-tooltip:before{position:absolute;top:100%;left:50%;margin-left:-15px;border:15px solid transparent;border-top-color:#F4C63D}.nav-tabs-right,.row>.nav-tabs-left+.tab-content{border-left:1px solid #ddd}.chartist-tooltip.tooltip-show{opacity:1}/*! - * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap) - * Copyright 2012-2014 Arnold Daniels - * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE) - */.container-smooth{max-width:1170px}@media (min-width:1px){.container-smooth{width:auto}}.btn-labeled{padding-top:0;padding-bottom:0}.btn-label{position:relative;left:-12px;padding:6px 12px;background:0 0;background:rgba(0,0,0,.15);border-radius:3px 0 0 3px}.btn-label.btn-label-right{right:-12px;left:auto;border-radius:0 3px 3px 0}.btn-lg .btn-label{left:-16px;padding:10px 16px;border-radius:5px 0 0 5px}.btn-lg .btn-label.btn-label-right{right:-16px;left:auto;border-radius:0 5px 5px 0}.btn-sm .btn-label{left:-10px;padding:5px 10px;border-radius:2px 0 0 2px}.btn-sm .btn-label.btn-label-right{right:-10px;left:auto;border-radius:0 2px 2px 0}.btn-xs .btn-label{left:-5px;padding:1px 5px;border-radius:2px 0 0 2px}.btn-xs .btn-label.btn-label-right{right:-5px;left:auto;border-radius:0 2px 2px 0}.nav-tabs-bottom{border-top:1px solid #ddd;border-bottom:0}.nav-tabs-bottom>li{margin-top:-1px;margin-bottom:0}.nav-tabs-bottom>li>a{border-radius:0 0 4px 4px}.nav-tabs-bottom>li.active>a,.nav-tabs-bottom>li.active>a:focus,.nav-tabs-bottom>li.active>a:hover,.nav-tabs-bottom>li>a:focus,.nav-tabs-bottom>li>a:hover{border:1px solid #ddd;border-top-color:transparent}.nav-tabs-left{border-right:1px solid #ddd;border-bottom:0}.nav-tabs-left>li{float:none;margin-right:-1px;margin-bottom:0}.nav-tabs-left>li>a{margin-right:0;margin-bottom:2px;border-radius:4px 0 0 4px}.nav-tabs-left>li.active>a,.nav-tabs-left>li.active>a:focus,.nav-tabs-left>li.active>a:hover,.nav-tabs-left>li>a:focus,.nav-tabs-left>li>a:hover{border:1px solid #ddd;border-right-color:transparent}.row>.nav-tabs-left{position:relative;z-index:1;padding-right:0;padding-left:15px;margin-right:-1px}.nav-tabs-right{border-bottom:0}.nav-tabs-right>li{float:none;margin-bottom:0;margin-left:-1px}.nav-tabs-right>li>a{margin-bottom:2px;margin-left:0;border-radius:0 4px 4px 0}.nav-tabs-right>li.active>a,.nav-tabs-right>li.active>a:focus,.nav-tabs-right>li.active>a:hover,.nav-tabs-right>li>a:focus,.nav-tabs-right>li>a:hover{border:1px solid #ddd;border-left-color:transparent}.row>.nav-tabs-right{padding-right:15px;padding-left:0}.navbar-offcanvas,.navmenu{width:300px;height:auto;border-style:solid;border-width:1px;border-radius:4px}.navbar-offcanvas,.navmenu-fixed-left,.navmenu-fixed-right{position:fixed;top:0;bottom:0;z-index:1030;overflow-y:auto;border-radius:0}.navbar-offcanvas.navmenu-fixed-left,.navmenu-fixed-left{right:auto;left:0;border-width:0 1px 0 0}.navbar-offcanvas,.navmenu-fixed-right{right:0;left:auto;border-width:0 0 0 1px}.navmenu-nav{margin-bottom:10px}.navmenu-nav.dropdown-menu{position:static;float:none;padding-top:0;margin:0;border:none;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.navbar-offcanvas .navbar-nav{margin:0}@media (min-width:768px){.navbar-offcanvas{width:auto;border-top:0;box-shadow:none}.navbar-offcanvas.offcanvas{position:static;display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-offcanvas .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-offcanvas .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-offcanvas .navmenu-brand{display:none}}.navmenu-brand{display:block;padding:10px 15px;margin:10px 0;line-height:20px}.navmenu-brand:focus,.navmenu-brand:hover{text-decoration:none}.navbar-default .navbar-offcanvas,.navmenu-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-offcanvas .navmenu-brand,.navmenu-default .navmenu-brand{color:#777}.navbar-default .navbar-offcanvas .navmenu-brand:focus,.navbar-default .navbar-offcanvas .navmenu-brand:hover,.navmenu-default .navmenu-brand:focus,.navmenu-default .navmenu-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-offcanvas .navmenu-text,.navmenu-default .navmenu-text{color:#777}.navbar-default .navbar-offcanvas .navmenu-nav>.dropdown>a:focus .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.dropdown>a:hover .caret,.navmenu-default .navmenu-nav>.dropdown>a:focus .caret,.navmenu-default .navmenu-nav>.dropdown>a:hover .caret{border-top-color:#333;border-bottom-color:#333}.navbar-default .navbar-offcanvas .navmenu-nav>.open>a,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:hover,.navmenu-default .navmenu-nav>.open>a,.navmenu-default .navmenu-nav>.open>a:focus,.navmenu-default .navmenu-nav>.open>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-offcanvas .navmenu-nav>.open>a .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:focus .caret,.navbar-default .navbar-offcanvas .navmenu-nav>.open>a:hover .caret,.navmenu-default .navmenu-nav>.open>a .caret,.navmenu-default .navmenu-nav>.open>a:focus .caret,.navmenu-default .navmenu-nav>.open>a:hover .caret{border-top-color:#555;border-bottom-color:#555}.navbar-default .navbar-offcanvas .navmenu-nav>.dropdown>a .caret,.navmenu-default .navmenu-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}.navbar-inverse .navbar-offcanvas .navmenu-nav>.dropdown>a:focus .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.dropdown>a:hover .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:focus .caret,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:hover .caret,.navmenu-inverse .navmenu-nav>.dropdown>a:focus .caret,.navmenu-inverse .navmenu-nav>.dropdown>a:hover .caret,.navmenu-inverse .navmenu-nav>.open>a .caret,.navmenu-inverse .navmenu-nav>.open>a:focus .caret,.navmenu-inverse .navmenu-nav>.open>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu,.navmenu-default .navmenu-nav.dropdown-menu{background-color:#e7e7e7}.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.divider,.navmenu-default .navmenu-nav.dropdown-menu>.divider{background-color:#f8f8f8}.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:hover,.navmenu-default .navmenu-nav.dropdown-menu>.active>a,.navmenu-default .navmenu-nav.dropdown-menu>.active>a:focus,.navmenu-default .navmenu-nav.dropdown-menu>.active>a:hover{background-color:#d7d7d7}.navbar-default .navbar-offcanvas .navmenu-nav>li>a,.navmenu-default .navmenu-nav>li>a{color:#777}.navbar-default .navbar-offcanvas .navmenu-nav>li>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>li>a:hover,.navmenu-default .navmenu-nav>li>a:focus,.navmenu-default .navmenu-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-offcanvas .navmenu-nav>.active>a,.navbar-default .navbar-offcanvas .navmenu-nav>.active>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>.active>a:hover,.navmenu-default .navmenu-nav>.active>a,.navmenu-default .navmenu-nav>.active>a:focus,.navmenu-default .navmenu-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-offcanvas .navmenu-nav>.disabled>a,.navbar-default .navbar-offcanvas .navmenu-nav>.disabled>a:focus,.navbar-default .navbar-offcanvas .navmenu-nav>.disabled>a:hover,.navmenu-default .navmenu-nav>.disabled>a,.navmenu-default .navmenu-nav>.disabled>a:focus,.navmenu-default .navmenu-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-inverse .navbar-offcanvas,.navmenu-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-offcanvas .navmenu-brand,.navmenu-inverse .navmenu-brand{color:#999}.navbar-inverse .navbar-offcanvas .navmenu-brand:focus,.navbar-inverse .navbar-offcanvas .navmenu-brand:hover,.navmenu-inverse .navmenu-brand:focus,.navmenu-inverse .navmenu-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-offcanvas .navmenu-text,.navmenu-inverse .navmenu-text{color:#999}.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>.open>a:hover,.navmenu-inverse .navmenu-nav>.open>a,.navmenu-inverse .navmenu-nav>.open>a:focus,.navmenu-inverse .navmenu-nav>.open>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-offcanvas .navmenu-nav>.dropdown>a .caret,.navmenu-inverse .navmenu-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu,.navmenu-inverse .navmenu-nav.dropdown-menu{background-color:#080808}.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.divider,.navmenu-inverse .navmenu-nav.dropdown-menu>.divider{background-color:#222}.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu>.active>a:hover,.navmenu-inverse .navmenu-nav.dropdown-menu>.active>a,.navmenu-inverse .navmenu-nav.dropdown-menu>.active>a:focus,.navmenu-inverse .navmenu-nav.dropdown-menu>.active>a:hover{background-color:#000}.navbar-inverse .navbar-offcanvas .navmenu-nav>li>a,.navmenu-inverse .navmenu-nav>li>a{color:#999}.navbar-inverse .navbar-offcanvas .navmenu-nav>li>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>li>a:hover,.navmenu-inverse .navmenu-nav>li>a:focus,.navmenu-inverse .navmenu-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-offcanvas .navmenu-nav>.active>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>.active>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>.active>a:hover,.navmenu-inverse .navmenu-nav>.active>a,.navmenu-inverse .navmenu-nav>.active>a:focus,.navmenu-inverse .navmenu-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-offcanvas .navmenu-nav>.disabled>a,.navbar-inverse .navbar-offcanvas .navmenu-nav>.disabled>a:focus,.navbar-inverse .navbar-offcanvas .navmenu-nav>.disabled>a:hover,.navmenu-inverse .navmenu-nav>.disabled>a,.navmenu-inverse .navmenu-nav>.disabled>a:focus,.navmenu-inverse .navmenu-nav>.disabled>a:hover{color:#444;background-color:transparent}.alert-fixed-bottom,.alert-fixed-top{position:fixed;left:0;z-index:1035;width:100%;margin:0;border-radius:0}.alert-fixed-top{top:0;border-width:0 0 1px}@media (min-width:992px){.alert-fixed-bottom,.alert-fixed-top{left:50%;width:992px;margin-left:-496px}.alert-fixed-top{border-width:0 1px 1px;border-bottom-right-radius:4px;border-bottom-left-radius:4px}}.alert-fixed-bottom{bottom:0;border-width:1px 0 0}@media (min-width:992px){.alert-fixed-bottom{border-width:1px 1px 0;border-top-left-radius:4px;border-top-right-radius:4px}}.offcanvas{display:none}.offcanvas.in{display:block}@media (max-width:767px){.offcanvas-xs{display:none}.offcanvas-xs.in{display:block}}@media (max-width:991px){.offcanvas-sm{display:none}.offcanvas-sm.in{display:block}}@media (max-width:1199px){.offcanvas-md{display:none}.offcanvas-md.in{display:block}}.offcanvas-lg{display:none}.offcanvas-lg.in{display:block}.canvas-sliding{-webkit-transition:top .35s,left .35s,bottom .35s,right .35s;transition:top .35s,left .35s,bottom .35s,right .35s}.offcanvas-clone{position:absolute!important;top:auto!important;right:0!important;bottom:0!important;left:auto!important;width:0!important;height:0!important;padding:0!important;margin:0!important;overflow:hidden!important;border:none!important;opacity:0!important}#block2,#logo,#page-wrap textarea,.btn-file,.fileinput-filename{overflow:hidden}.table .rowlink td:not(.rowlink-skip),.table.rowlink td:not(.rowlink-skip){cursor:pointer}.table .rowlink td:not(.rowlink-skip) a,.table.rowlink td:not(.rowlink-skip) a{font:inherit;color:inherit;text-decoration:inherit}.delete,a.none{text-decoration:none}.table-hover .rowlink tr:hover td,.table-hover.rowlink tr:hover td{background-color:#cfcfcf}.btn-file{position:relative}.btn-file>input{position:absolute;top:0;right:0;width:100%;height:100%;margin:0;font-size:23px;cursor:pointer;filter:alpha(opacity=0);opacity:0;direction:ltr}.fileinput{margin-bottom:9px}.fileinput .form-control{display:inline-block;padding-top:7px;padding-bottom:5px;margin-bottom:0;vertical-align:middle;cursor:text}.fileinput .thumbnail{margin-bottom:5px;overflow:hidden;text-align:center}.fileinput .thumbnail>img{max-height:100%}#logo,#logo img{max-height:150px}.fileinput-exists .fileinput-new,.fileinput-new .fileinput-exists{display:none}.fileinput-inline .fileinput-controls{display:inline}.fileinput-filename{display:inline-block}.form-control .fileinput-filename{vertical-align:bottom}.fileinput.input-group{display:table}.fileinput.input-group>*{position:relative;z-index:2}.fileinput.input-group>.btn-file{z-index:1}.fileinput-new .input-group .btn-file,.fileinput-new.input-group .btn-file{border-radius:0 4px 4px 0}.fileinput-new .input-group .btn-file.btn-sm,.fileinput-new .input-group .btn-file.btn-xs,.fileinput-new.input-group .btn-file.btn-sm,.fileinput-new.input-group .btn-file.btn-xs{border-radius:0 3px 3px 0}.fileinput-new .input-group .btn-file.btn-lg,.fileinput-new.input-group .btn-file.btn-lg{border-radius:0 6px 6px 0}.form-group.has-warning .fileinput .fileinput-preview{color:#8a6d3b}.form-group.has-warning .fileinput .thumbnail{border-color:#faebcc}.form-group.has-error .fileinput .fileinput-preview{color:#a94442}.form-group.has-error .fileinput .thumbnail{border-color:#ebccd1}.form-group.has-success .fileinput .fileinput-preview{color:#3c763d}.form-group.has-success .fileinput .thumbnail{border-color:#d6e9c6}.input-group-addon:not(:first-child){border-left:0}[class*=" datetimepicker-dropdown"]:after,[class*=" datetimepicker-dropdown-top"]:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent}/*! - * Datetimepicker for Bootstrap - * - * Copyright 2012 Stefan Petre - * Improvements by Andrew Rowls - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - */.datetimepicker{padding:4px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;direction:ltr}.datetimepicker-inline{width:220px}.datetimepicker.datetimepicker-rtl{direction:rtl}.datetimepicker.datetimepicker-rtl table tr td span{float:right}.datetimepicker-dropdown,.datetimepicker-dropdown-left{top:0;left:0}[class*=" datetimepicker-dropdown"]:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute}[class*=" datetimepicker-dropdown"]:after{border-bottom:6px solid #fff;position:absolute}[class*=" datetimepicker-dropdown-top"]:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);border-bottom:0}[class*=" datetimepicker-dropdown-top"]:after{border-top:6px solid #fff;border-bottom:0}.datetimepicker-dropdown-bottom-left:before{top:-7px;right:6px}.datetimepicker-dropdown-bottom-left:after{top:-6px;right:7px}.datetimepicker-dropdown-bottom-right:before{top:-7px;left:6px}.datetimepicker-dropdown-bottom-right:after{top:-6px;left:7px}.datetimepicker-dropdown-top-left:before{bottom:-7px;right:6px}.datetimepicker-dropdown-top-left:after{bottom:-6px;right:7px}.datetimepicker-dropdown-top-right:before{bottom:-7px;left:6px}.datetimepicker-dropdown-top-right:after{bottom:-6px;left:7px}.datetimepicker>div{display:none}.datetimepicker.days div.datetimepicker-days,.datetimepicker.hours div.datetimepicker-hours,.datetimepicker.minutes div.datetimepicker-minutes,.datetimepicker.months div.datetimepicker-months,.datetimepicker.years div.datetimepicker-years{display:block}.datetimepicker table{margin:0}.datetimepicker td,.datetimepicker th{text-align:center;width:20px;height:20px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border:0}.table-striped .datetimepicker table tr td,.table-striped .datetimepicker table tr th{background-color:transparent}.datetimepicker table tr td.day:hover,.datetimepicker table tr td.hour:hover,.datetimepicker table tr td.minute:hover{background:#eee;cursor:pointer}.datetimepicker table tr td.new,.datetimepicker table tr td.old{color:#999}.datetimepicker table tr td.disabled,.datetimepicker table tr td.disabled:hover{background:0;color:#999;cursor:default}.datetimepicker table tr td.today,.datetimepicker table tr td.today.disabled,.datetimepicker table tr td.today.disabled:hover,.datetimepicker table tr td.today:hover{background-color:#fde19a;background-image:-moz-linear-gradient(top,#fdd49a,#fdf59a);background-image:-ms-linear-gradient(top,#fdd49a,#fdf59a);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdd49a),to(#fdf59a));background-image:-webkit-linear-gradient(top,#fdd49a,#fdf59a);background-image:-o-linear-gradient(top,#fdd49a,#fdf59a);background-image:linear-gradient(top,#fdd49a,#fdf59a);background-repeat:repeat-x;border-color:#fdf59a #fdf59a #fbed50;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.datetimepicker table tr td.today.active,.datetimepicker table tr td.today.disabled,.datetimepicker table tr td.today.disabled.active,.datetimepicker table tr td.today.disabled.disabled,.datetimepicker table tr td.today.disabled:active,.datetimepicker table tr td.today.disabled:hover,.datetimepicker table tr td.today.disabled:hover.active,.datetimepicker table tr td.today.disabled:hover.disabled,.datetimepicker table tr td.today.disabled:hover:active,.datetimepicker table tr td.today.disabled:hover:hover,.datetimepicker table tr td.today.disabled:hover[disabled],.datetimepicker table tr td.today.disabled[disabled],.datetimepicker table tr td.today:active,.datetimepicker table tr td.today:hover,.datetimepicker table tr td.today:hover.active,.datetimepicker table tr td.today:hover.disabled,.datetimepicker table tr td.today:hover:active,.datetimepicker table tr td.today:hover:hover,.datetimepicker table tr td.today:hover[disabled],.datetimepicker table tr td.today[disabled]{background-color:#fdf59a}.datetimepicker table tr td.today.active,.datetimepicker table tr td.today.disabled.active,.datetimepicker table tr td.today.disabled:active,.datetimepicker table tr td.today.disabled:hover.active,.datetimepicker table tr td.today.disabled:hover:active,.datetimepicker table tr td.today:active,.datetimepicker table tr td.today:hover.active,.datetimepicker table tr td.today:hover:active{background-color:#fbf069}.datetimepicker table tr td.active,.datetimepicker table tr td.active.disabled,.datetimepicker table tr td.active.disabled:hover,.datetimepicker table tr td.active:hover{background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-ms-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(top,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datetimepicker table tr td.active.active,.datetimepicker table tr td.active.disabled,.datetimepicker table tr td.active.disabled.active,.datetimepicker table tr td.active.disabled.disabled,.datetimepicker table tr td.active.disabled:active,.datetimepicker table tr td.active.disabled:hover,.datetimepicker table tr td.active.disabled:hover.active,.datetimepicker table tr td.active.disabled:hover.disabled,.datetimepicker table tr td.active.disabled:hover:active,.datetimepicker table tr td.active.disabled:hover:hover,.datetimepicker table tr td.active.disabled:hover[disabled],.datetimepicker table tr td.active.disabled[disabled],.datetimepicker table tr td.active:active,.datetimepicker table tr td.active:hover,.datetimepicker table tr td.active:hover.active,.datetimepicker table tr td.active:hover.disabled,.datetimepicker table tr td.active:hover:active,.datetimepicker table tr td.active:hover:hover,.datetimepicker table tr td.active:hover[disabled],.datetimepicker table tr td.active[disabled]{background-color:#04c}.datetimepicker table tr td.active.active,.datetimepicker table tr td.active.disabled.active,.datetimepicker table tr td.active.disabled:active,.datetimepicker table tr td.active.disabled:hover.active,.datetimepicker table tr td.active.disabled:hover:active,.datetimepicker table tr td.active:active,.datetimepicker table tr td.active:hover.active,.datetimepicker table tr td.active:hover:active{background-color:#039}.datetimepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.datetimepicker .datetimepicker-hours span{height:26px;line-height:26px}.datetimepicker .datetimepicker-hours table tr td span.hour_am,.datetimepicker .datetimepicker-hours table tr td span.hour_pm{width:14.6%}.datetimepicker .datetimepicker-hours fieldset legend,.datetimepicker .datetimepicker-minutes fieldset legend{margin-bottom:inherit;line-height:30px}.datetimepicker .datetimepicker-minutes span{height:26px;line-height:26px}.datetimepicker table tr td span:hover{background:#eee}.datetimepicker table tr td span.disabled,.datetimepicker table tr td span.disabled:hover{background:0;color:#999;cursor:default}.datetimepicker table tr td span.active,.datetimepicker table tr td span.active.disabled,.datetimepicker table tr td span.active.disabled:hover,.datetimepicker table tr td span.active:hover{background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-ms-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(top,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datetimepicker table tr td span.active.active,.datetimepicker table tr td span.active.disabled,.datetimepicker table tr td span.active.disabled.active,.datetimepicker table tr td span.active.disabled.disabled,.datetimepicker table tr td span.active.disabled:active,.datetimepicker table tr td span.active.disabled:hover,.datetimepicker table tr td span.active.disabled:hover.active,.datetimepicker table tr td span.active.disabled:hover.disabled,.datetimepicker table tr td span.active.disabled:hover:active,.datetimepicker table tr td span.active.disabled:hover:hover,.datetimepicker table tr td span.active.disabled:hover[disabled],.datetimepicker table tr td span.active.disabled[disabled],.datetimepicker table tr td span.active:active,.datetimepicker table tr td span.active:hover,.datetimepicker table tr td span.active:hover.active,.datetimepicker table tr td span.active:hover.disabled,.datetimepicker table tr td span.active:hover:active,.datetimepicker table tr td span.active:hover:hover,.datetimepicker table tr td span.active:hover[disabled],.datetimepicker table tr td span.active[disabled]{background-color:#04c}.datetimepicker table tr td span.active.active,.datetimepicker table tr td span.active.disabled.active,.datetimepicker table tr td span.active.disabled:active,.datetimepicker table tr td span.active.disabled:hover.active,.datetimepicker table tr td span.active.disabled:hover:active,.datetimepicker table tr td span.active:active,.datetimepicker table tr td span.active:hover.active,.datetimepicker table tr td span.active:hover:active{background-color:#039}.datetimepicker table tr td span.old{color:#999}.datetimepicker th.switch{width:145px}.datetimepicker th span.glyphicon{pointer-events:none}.datetimepicker tfoot th,.datetimepicker thead tr:first-child th{cursor:pointer}.datetimepicker tfoot th:hover,.datetimepicker thead tr:first-child th:hover{background:#eee}.input-append.date .add-on i,.input-group.date .input-group-addon span,.input-prepend.date .add-on i{cursor:pointer;width:14px;height:14px}@font-face{font-family:SansationLight;src:url(../fonts/SansationLight.eot);src:local('SansationLight'),url(../fonts/SansationLight.woff) format('woff'),url(../fonts/SansationLight.ttf) format('truetype')}.font_SansationLight{font-family:SansationLight!important}@font-face{font-family:Arial;src:url(../fonts/Arial.eot);src:local('Arial'),url(../fonts/Arial.woff) format('woff'),url(../fonts/Arial.ttf) format('truetype')}.font_Arial{font-family:Arial!important}@font-face{font-family:JUNEBUG;src:url(../fonts/JUNEBUG.eot);src:local('JUNEBUG'),url(../fonts/JUNEBUG.woff) format('woff'),url(../fonts/JUNEBUG.ttf) format('truetype')}.font_JUNEBUG{font-family:JUNEBUG!important}@font-face{font-family:b-de-bonita-shadow;src:url(../fonts/b-de-bonita-shadow.eot);src:local('JUNEBUG'),url(../fonts/b-de-bonita-shadow.woff) format('woff'),url(../fonts/b-de-bonita-shadow.ttf) format('truetype')}.font_b-de-bonita-shadow{font-family:b-de-bonita-shadow!important}.ui-autocomplete{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;background-color:#fff;border-color:#ccc;border-color:rgba(0,0,0,.15);border-style:solid;border-width:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.175);-moz-box-shadow:0 5px 10px rgba(0,0,0,.175);box-shadow:0 5px 10px rgba(0,0,0,.175);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}#logo,.delete-wpr{position:relative}.ui-autocomplete .ui-menu-item>a.ui-corner-all{display:block;padding:3px 15px;clear:both;font-weight:400;line-height:18px;color:#7b8a8b;white-space:nowrap}#header,.delete{font-weight:700}.ui-autocomplete .ui-menu-item>a.ui-corner-all.ui-state-active,.ui-autocomplete .ui-menu-item>a.ui-corner-all.ui-state-hover{color:#fff;text-decoration:none;background-color:#f5f5f5;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;background-image:none}*{margin:0;padding:0}#page-wrap{width:100%;margin:0 auto;max-width:800px}#page-wrap textarea{border:0;font-size:14px;resize:none}#page-wrap table{border-collapse:collapse}#page-wrap table td,#page-wrap table th{border:1px solid #000;padding:5px}#page-wrap table td{padding:5px}#header{margin:20px 0;background:#222;text-align:center;color:#fff;font-size:2em;letter-spacing:4px;padding:10px 0}#logo{text-align:right;margin-top:15px;float:left;border:1px solid #fff}#logo img{max-width:150px}#logoctr{display:none}#logo.edit #logoctr,#logo:hover #logoctr{display:block;text-align:right;line-height:25px;background:#eee;padding:0 5px}#logohelp{text-align:left;display:none;font-style:italic;padding:10px 5px}#logohelp input{margin-bottom:5px}.edit #logohelp{display:block}.edit #cancel-logo,.edit #save-logo{display:inline}#cancel-logo,#save-logo,.edit #change-logo,.edit #delete-logo,.edit #image{display:none}#customer-title{height:100px;float:right;margin-top:40px}#customer-title textarea{width:150px}#block2{width:100%}#company-title{float:left}#meta{margin-top:1px;width:300px;float:right}#meta td{text-align:right}#meta td.meta-head{text-align:left;background:#eee}#meta td textarea{width:100%;height:20px;text-align:right}#items{clear:both;width:100%;margin:30px 0 0;border:1px solid #000}#items th{background:#eee;text-align:center}#items textarea{width:80px;height:20px}#items tr.item-row td{border:0;vertical-align:top}#items td.description{width:300px}#items td.item-name{width:175px}#items td.description textarea,#items td.item-name textarea{width:100%}#items td.total-line{border-right:0;text-align:right}#config_wrapper,#feedback_bar,#footer,#home_module_list,#item_kit_items td,#item_kit_items th,#items_count_details td,#items_count_details th,#page_subtitle,#receipt_header,#receipt_wrapper #barcode,#required_fields_message,#sale_return_policy,#terms,#terms textarea,.navbar .menu-icon{text-align:center}#items td.total-value{border-left:0;padding:10px}#items td.total-value textarea{height:20px;background:0 0}#items td.total-line textarea{height:20px;width:150px;background:0 0}#items td.balance{background:#eee}#items td.blank{border:0}#items td.blank-bottom{border:1px}#terms{margin:20px 0 0}#terms h5{text-transform:uppercase;font-size:13px;letter-spacing:10px;border-bottom:1px solid #000;padding:0 0 8px;margin:0 0 8px}#terms textarea{width:100%}.delete{display:block;color:#000;position:absolute;background:#EEE;padding:0 3px;border:1px solid;top:-6px;left:-22px;font-family:Verdana;font-size:12px}#footer,#home_module_list,#receipt_items,#receipt_items td,#title_bar{position:relative}body,html{height:100%}.topbar{color:#eee;font-size:12px;background:#182735;padding:.2em}.navbar{border-radius:0}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#2C3E50;background-color:#FFF}.alert{margin-bottom:.1em;padding:10px;width:99%}.jumbotron.push-spaces{margin:0}.navbar .menu-icon{font-size:12px}.navbar .menu-icon img{width:24px}.wrapper{font-size:14px}#title_bar{width:100%;height:3em}#page_title{font-size:22px;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:400}#company_name,#employee_permission_info p,#info_provided_by,#page_subtitle,.discount,.error_message_box{font-weight:700}#page_subtitle{margin-bottom:.5em;font-size:16px}#feedback_bar{position:fixed;bottom:0;left:0;width:100%;z-index:1;line-height:3.3}#home_module_list{padding:2em 0}.module_item{min-width:7em;display:inline-block;text-align:center}.module_item a{display:block}#config_info{text-align:left}#config_info .wide{width:30%}#footer{margin-top:5em;font-size:11px;color:#777;clear:both}a.rollover img{padding:3px}#filters.btn-group{vertical-align:none}button.btn.dropdown-toggle.btn-sm{background-color:#fff;color:#000;border:2px solid #dce4ec}#add_item_form,#overall_sale{background-color:#BBB}#mode_form,#payment_details{background-color:#DDD}.dropdown-menu{font-size:13px}label.required{color:red}@media (min-width:768px){.navbar-nav>li>a{padding:10px 10px 9px}.modal-dlg .modal-dialog{width:500px}.modal-dlg-wide .modal-dialog{width:750px}}.modal-body{max-height:calc(100vh - 212px);overflow-y:auto}@media print{table.innertable a,table.report a{color:#000;text-decoration:none}.no-print,.no-print *{display:none!important}#receipt_wrapper,#table{font-size:75%}#footer,#menubar,.topbar{display:none}#sale_return_policy{width:100%;text-align:center}#receipt_items td{white-space:nowrap}table.innertable{display:table}table.report a.expand{visibility:hidden}.print_show{display:block!important}.print_hide{display:none!important}.fixed-table-container{border:none}.fixed-table-container thead th .sortable{padding-right:10px}}#payment_details,#payment_totals,#sale_totals{border-top:1px solid #000}#required_fields_message{width:100%;margin-bottom:3px;font-style:italic}.error_message_box{margin-bottom:7px;margin-left:20px;color:red}#company_phone,#receipt_items{margin-bottom:15px}#receipt_items td,#receipt_items tr,#sale_time{margin-bottom:5px}#customer_basic_info,#employee_basic_info,#employee_login_info,#employee_permission_info,#item_basic_info,#item_number_info,#permission_list li,#sale_basic_info,#supplier_basic_info{padding:5px}#info_provided_by{display:none}#permission_list{list-style:none}#permission_list ul li{padding-left:20px;padding-bottom:0;list-style:none}#permission_list input{top:3px}#employee_permission_info span.small{font-style:italic;font-size:80%}#items_count_details{font-size:80%}#item_kit_items,#items_count_details,#receipt_wrapper{width:100%}#item_kit_items thead tr,#items_count_details thead tr{background-color:#CCC}#item_kit_items th,#items_count_details th{font-weight:700}#company_name{font-size:150%}#company_name img{max-width:150px;max-height:150px}#receipt_items{border-collapse:collapse;margin-top:15px;width:100%}#receipt_items td{padding:3px}#sale_return_policy{width:80%;margin:0 auto}#receipt_wrapper #barcode{margin-top:10px}.total-value{text-align:right}#register_wrapper{float:left;width:70%;font-size:13px}#add_item_form,#mode_form{margin:0}#add_item_form .panel-body,#mode_form .panel-body{padding:.7em;margin:0}#add_item_form ul,#mode_form ul{list-style:none;padding:0;margin:0}#add_item_form ul li,#mode_form ul li{margin-left:1em}.first_li{margin-left:.2em!important}#add_item_form ul.dropdown-menu.inner,#mode_form ul.dropdown-menu.inner{margin-left:-1em!important}#register{padding:0;border-collapse:collapse}#register th{background-color:#999;padding:5px;text-align:center;color:#FFF}#register td{background-color:#EEE;padding:3px;text-align:center}#overall_sale{width:29%;float:left;margin-left:.1em;padding-bottom:1em;padding-top:1em;font-size:13px;text-align:center}#overall_sale .panel-body{padding-top:0;padding-bottom:0}#overall_sale .form-group{margin:0}#overall_sale .btn{margin-top:.5em;margin-bottom:.5em}#buttons_sale,#payment_details,#suspended_sales_table,.sales_table_100{width:100%}#payment_details{float:left;margin-top:.2em;padding:.5em;text-align:left;clear:both}#report_list li ul li{margin-left:35px}#report_date_range_complex,#report_date_range_simple{margin-bottom:10px}.report{font-size:.85em}#report_summary{margin:2em 0 auto;text-align:center}#chart_report_summary{text-align:center;margin-top:-100px}.ct-label.ct-horizontal{-webkit-transform:rotate(-60deg);-moz-transform:rotate(-60deg);-ms-transform:rotate(-60deg);-o-transform:rotate(-60deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3)}.ct-label{fill:rgba(0,0,0,1);color:rgba(0,0,0,1);font-size:1.2rem}.ct-tooltip-point{fill-opacity:1!important;stroke-width:0;stroke:red;transition:all .2s linear}.ct-tooltip-point:hover{r:7;stroke-opacity:.2;stroke-width:20px} \ No newline at end of file diff --git a/dist/opensourcepos.min.js b/dist/opensourcepos.min.js deleted file mode 100644 index 936655212..000000000 --- a/dist/opensourcepos.min.js +++ /dev/null @@ -1,35 +0,0 @@ -/*! opensourcepos 26-05-2016 */ -function set_feedback(a,b,c){a?($("#feedback_bar").removeClass().addClass(b).html(a).css("opacity","1"),c||$("#feedback_bar").fadeTo(5e3,1).fadeTo("fast",0)):$("#feedback_bar").css("opacity","0")}function phpjsDate(a,b){var c,d,e=this,f=["Sun","Mon","Tues","Wednes","Thurs","Fri","Satur","January","February","March","April","May","June","July","August","September","October","November","December"],g=/\\?(.?)/gi,h=function(a,b){return d[a]?d[a]():b},i=function(a,b){for(a=String(a);a.length=b&&1==parseInt(a%100/10,10)&&(b=0),["st","nd","rd"][b-1]||"th"},w:function(){return c.getDay()},z:function(){var a=new Date(d.Y(),d.n()-1,d.j()),b=new Date(d.Y(),0,1);return Math.round((a-b)/864e5)},W:function(){var a=new Date(d.Y(),d.n()-1,d.j()-d.N()+3),b=new Date(a.getFullYear(),0,4);return i(1+Math.round((a-b)/864e5/7),2)},F:function(){return f[6+d.n()]},m:function(){return i(d.n(),2)},M:function(){return d.F().slice(0,3)},n:function(){return c.getMonth()+1},t:function(){return new Date(d.Y(),d.n(),0).getDate()},L:function(){var a=d.Y();return a%4===0&a%100!==0|a%400===0},o:function(){var a=d.n(),b=d.W(),c=d.Y();return c+(12===a&&9>b?1:1===a&&b>9?-1:0)},Y:function(){return c.getFullYear()},y:function(){return d.Y().toString().slice(-2)},a:function(){return c.getHours()>11?"pm":"am"},A:function(){return d.a().toUpperCase()},B:function(){var a=3600*c.getUTCHours(),b=60*c.getUTCMinutes(),d=c.getUTCSeconds();return i(Math.floor((a+b+d+3600)/86.4)%1e3,3)},g:function(){return d.G()%12||12},G:function(){return c.getHours()},h:function(){return i(d.g(),2)},H:function(){return i(d.G(),2)},i:function(){return i(c.getMinutes(),2)},s:function(){return i(c.getSeconds(),2)},u:function(){return i(1e3*c.getMilliseconds(),6)},e:function(){throw"Not supported (see source code of date() for timezone on how to add support)"},I:function(){var a=new Date(d.Y(),0),b=Date.UTC(d.Y(),0),c=new Date(d.Y(),6),e=Date.UTC(d.Y(),6);return a-b!==c-e?1:0},O:function(){var a=c.getTimezoneOffset(),b=Math.abs(a);return(a>0?"-":"+")+i(100*Math.floor(b/60)+b%60,4)},P:function(){var a=d.O();return a.substr(0,3)+":"+a.substr(3,2)},T:function(){return"UTC"},Z:function(){return 60*-c.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(g,h)},r:function(){return"D, d M Y H:i:s O".replace(g,h)},U:function(){return c/1e3|0}},this.date=function(a,b){return e=this,c=void 0===b?new Date:new Date(b instanceof Date?b:1e3*b),a.replace(g,h)},this.date(a,b)}if(function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=!!a&&"length"in a&&a.length,c=na.type(a);return"function"===c||na.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(na.isFunction(b))return na.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return na.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(xa.test(b))return na.filter(b,a,c);b=na.filter(b,a)}return na.grep(a,function(a){return na.inArray(a,b)>-1!==c})}function e(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}function f(a){var b={};return na.each(a.match(Da)||[],function(a,c){b[c]=!0}),b}function g(){da.addEventListener?(da.removeEventListener("DOMContentLoaded",h),a.removeEventListener("load",h)):(da.detachEvent("onreadystatechange",h),a.detachEvent("onload",h))}function h(){(da.addEventListener||"load"===a.event.type||"complete"===da.readyState)&&(g(),na.ready())}function i(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(Ia,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:Ha.test(c)?na.parseJSON(c):c}catch(e){}na.data(a,b,c)}else c=void 0}return c}function j(a){var b;for(b in a)if(("data"!==b||!na.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function k(a,b,c,d){if(Ga(a)){var e,f,g=na.expando,h=a.nodeType,i=h?na.cache:a,j=h?a[g]:a[g]&&g;if(j&&i[j]&&(d||i[j].data)||void 0!==c||"string"!=typeof b)return j||(j=h?a[g]=ca.pop()||na.guid++:g),i[j]||(i[j]=h?{}:{toJSON:na.noop}),("object"==typeof b||"function"==typeof b)&&(d?i[j]=na.extend(i[j],b):i[j].data=na.extend(i[j].data,b)),f=i[j],d||(f.data||(f.data={}),f=f.data),void 0!==c&&(f[na.camelCase(b)]=c),"string"==typeof b?(e=f[b],null==e&&(e=f[na.camelCase(b)])):e=f,e}}function l(a,b,c){if(Ga(a)){var d,e,f=a.nodeType,g=f?na.cache:a,h=f?a[na.expando]:na.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){na.isArray(b)?b=b.concat(na.map(b,na.camelCase)):b in d?b=[b]:(b=na.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;for(;e--;)delete d[b[e]];if(c?!j(d):!na.isEmptyObject(d))return}(c||(delete g[h].data,j(g[h])))&&(f?na.cleanData([a],!0):la.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}function m(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return na.css(a,b,"")},i=h(),j=c&&c[3]||(na.cssNumber[b]?"":"px"),k=(na.cssNumber[b]||"px"!==j&&+i)&&Ka.exec(na.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,na.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}function n(a){var b=Sa.split("|"),c=a.createDocumentFragment();if(c.createElement)for(;b.length;)c.createElement(b.pop());return c}function o(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||na.nodeName(d,b)?f.push(d):na.merge(f,o(d,b));return void 0===b||b&&na.nodeName(a,b)?na.merge([a],f):f}function p(a,b){for(var c,d=0;null!=(c=a[d]);d++)na._data(c,"globalEval",!b||na._data(b[d],"globalEval"))}function q(a){Oa.test(a.type)&&(a.defaultChecked=a.checked)}function r(a,b,c,d,e){for(var f,g,h,i,j,k,l,m=a.length,r=n(b),s=[],t=0;m>t;t++)if(g=a[t],g||0===g)if("object"===na.type(g))na.merge(s,g.nodeType?[g]:g);else if(Ua.test(g)){for(i=i||r.appendChild(b.createElement("div")),j=(Pa.exec(g)||["",""])[1].toLowerCase(),l=Ta[j]||Ta._default,i.innerHTML=l[1]+na.htmlPrefilter(g)+l[2],f=l[0];f--;)i=i.lastChild;if(!la.leadingWhitespace&&Ra.test(g)&&s.push(b.createTextNode(Ra.exec(g)[0])),!la.tbody)for(g="table"!==j||Va.test(g)?""!==l[1]||Va.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;f--;)na.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k);for(na.merge(s,i.childNodes),i.textContent="";i.firstChild;)i.removeChild(i.firstChild);i=r.lastChild}else s.push(b.createTextNode(g));for(i&&r.removeChild(i),la.appendChecked||na.grep(o(s,"input"),q),t=0;g=s[t++];)if(d&&na.inArray(g,d)>-1)e&&e.push(g);else if(h=na.contains(g.ownerDocument,g),i=o(r.appendChild(g),"script"),h&&p(i),c)for(f=0;g=i[f++];)Qa.test(g.type||"")&&c.push(g);return i=null,r}function s(){return!0}function t(){return!1}function u(){try{return da.activeElement}catch(a){}}function v(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)v(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=t;else if(!e)return a;return 1===f&&(g=e,e=function(a){return na().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=na.guid++)),a.each(function(){na.event.add(this,b,e,d,c)})}function w(a,b){return na.nodeName(a,"table")&&na.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function x(a){return a.type=(null!==na.find.attr(a,"type"))+"/"+a.type,a}function y(a){var b=eb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function z(a,b){if(1===b.nodeType&&na.hasData(a)){var c,d,e,f=na._data(a),g=na._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)na.event.add(b,c,h[c][d])}g.data&&(g.data=na.extend({},g.data))}}function A(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!la.noCloneEvent&&b[na.expando]){e=na._data(b);for(d in e.events)na.removeEvent(b,d,e.handle);b.removeAttribute(na.expando)}"script"===c&&b.text!==a.text?(x(b).text=a.text,y(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),la.html5Clone&&a.innerHTML&&!na.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Oa.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function B(a,b,c,d){b=fa.apply([],b);var e,f,g,h,i,j,k=0,l=a.length,m=l-1,n=b[0],p=na.isFunction(n);if(p||l>1&&"string"==typeof n&&!la.checkClone&&db.test(n))return a.each(function(e){var f=a.eq(e);p&&(b[0]=n.call(this,e,f.html())),B(f,b,c,d)});if(l&&(j=r(b,a[0].ownerDocument,!1,a,d),e=j.firstChild,1===j.childNodes.length&&(j=e),e||d)){for(h=na.map(o(j,"script"),x),g=h.length;l>k;k++)f=j,k!==m&&(f=na.clone(f,!0,!0),g&&na.merge(h,o(f,"script"))),c.call(a[k],f,k);if(g)for(i=h[h.length-1].ownerDocument,na.map(h,y),k=0;g>k;k++)f=h[k],Qa.test(f.type||"")&&!na._data(f,"globalEval")&&na.contains(i,f)&&(f.src?na._evalUrl&&na._evalUrl(f.src):na.globalEval((f.text||f.textContent||f.innerHTML||"").replace(fb,"")));j=e=null}return a}function C(a,b,c){for(var d,e=b?na.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||na.cleanData(o(d)),d.parentNode&&(c&&na.contains(d.ownerDocument,d)&&p(o(d,"script")),d.parentNode.removeChild(d));return a}function D(a,b){var c=na(b.createElement(a)).appendTo(b.body),d=na.css(c[0],"display");return c.detach(),d}function E(a){var b=da,c=jb[a];return c||(c=D(a,b),"none"!==c&&c||(ib=(ib||na("':''),v=a(d.theme?'':''),d.theme&&q?(x='"):d.theme?(x='"):x=q?'':'',w=a(x),r&&(d.theme?(w.css(p),w.addClass("ui-widget-content")):w.css(f)),d.theme||v.css(d.overlayCSS),v.css("position",q?"fixed":"absolute"),(k||d.forceIframe)&&u.css("opacity",0);var z=[u,v,w],A=a(q?"body":b);a.each(z,function(){this.appendTo(A)}),d.theme&&d.draggable&&a.fn.draggable&&w.draggable({handle:".ui-dialog-titlebar",cancel:"li"});var B=m&&(!a.support.boxModel||a("object,embed",q?null:b).length>0);if(l||B){if(q&&d.allowBodyStretch&&a.support.boxModel&&a("html,body").css("height","100%"),(l||!a.support.boxModel)&&!q)var C=i(b,"borderTopWidth"),D=i(b,"borderLeftWidth"),E=C?"(0 - "+C+")":0,F=D?"(0 - "+D+")":0;a.each(z,function(a,b){var c=b[0].style;if(c.position="absolute",2>a)q?c.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:"+d.quirksmodeOffsetHack+') + "px"'):c.setExpression("height",'this.parentNode.offsetHeight + "px"'),q?c.setExpression("width",'jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):c.setExpression("width",'this.parentNode.offsetWidth + "px"'),F&&c.setExpression("left",F),E&&c.setExpression("top",E);else if(d.centerY)q&&c.setExpression("top",'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'),c.marginTop=0;else if(!d.centerY&&q){var e=d.css&&d.css.top?parseInt(d.css.top,10):0,f="((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "+e+') + "px"';c.setExpression("top",f)}})}if(r&&(d.theme?w.find(".ui-widget-content").append(r):w.append(r),(r.jquery||r.nodeType)&&a(r).show()),(k||d.forceIframe)&&d.showOverlay&&u.show(),d.fadeIn){var G=d.onBlock?d.onBlock:j,H=d.showOverlay&&!r?G:j,I=r?G:j;d.showOverlay&&v._fadeIn(d.fadeIn,H),r&&w._fadeIn(d.fadeIn,I)}else d.showOverlay&&v.show(),r&&w.show(),d.onBlock&&d.onBlock.bind(w)();if(e(1,b,d),q?(n=w[0],o=a(d.focusableElements,n),d.focusInput&&setTimeout(g,20)):h(w[0],d.centerX,d.centerY),d.timeout){var J=setTimeout(function(){q?a.unblockUI(d):a(b).unblock(d)},d.timeout);a(b).data("blockUI.timeout",J)}}}function c(b,c){var f,g=b==window,h=a(b),i=h.data("blockUI.history"),j=h.data("blockUI.timeout");j&&(clearTimeout(j),h.removeData("blockUI.timeout")),c=a.extend({},a.blockUI.defaults,c||{}),e(0,b,c),null===c.onUnblock&&(c.onUnblock=h.data("blockUI.onUnblock"),h.removeData("blockUI.onUnblock"));var k;k=g?a("body").children().filter(".blockUI").add("body > .blockUI"):h.find(">.blockUI"),c.cursorReset&&(k.length>1&&(k[1].style.cursor=c.cursorReset),k.length>2&&(k[2].style.cursor=c.cursorReset)),g&&(n=o=null),c.fadeOut?(f=k.length,k.stop().fadeOut(c.fadeOut,function(){0===--f&&d(k,i,c,b)})):d(k,i,c,b)}function d(b,c,d,e){var f=a(e);if(!f.data("blockUI.isBlocked")){b.each(function(){this.parentNode&&this.parentNode.removeChild(this)}),c&&c.el&&(c.el.style.display=c.display,c.el.style.position=c.position,c.el.style.cursor="default",c.parent&&c.parent.appendChild(c.el),f.removeData("blockUI.history")),f.data("blockUI.static")&&f.css("position","static"),"function"==typeof d.onUnblock&&d.onUnblock(e,d);var g=a(document.body),h=g.width(),i=g[0].style.width;g.width(h-1).width(h),g[0].style.width=i}}function e(b,c,d){var e=c==window,g=a(c);if((b||(!e||n)&&(e||g.data("blockUI.isBlocked")))&&(g.data("blockUI.isBlocked",b),e&&d.bindEvents&&(!b||d.showOverlay))){var h="mousedown mouseup keydown keypress keyup touchstart touchend touchmove";b?a(document).bind(h,d,f):a(document).unbind(h,f)}}function f(b){if("keydown"===b.type&&b.keyCode&&9==b.keyCode&&n&&b.data.constrainTabKey){var c=o,d=!b.shiftKey&&b.target===c[c.length-1],e=b.shiftKey&&b.target===c[0];if(d||e)return setTimeout(function(){g(e)},10),!1}var f=b.data,h=a(b.target);return h.hasClass("blockOverlay")&&f.onOverlayClick&&f.onOverlayClick(b),h.parents("div."+f.blockMsgClass).length>0?!0:0===h.parents().children().filter("div.blockUI").length}function g(a){if(o){var b=o[a===!0?o.length-1:0];b&&b.focus()}}function h(a,b,c){var d=a.parentNode,e=a.style,f=(d.offsetWidth-a.offsetWidth)/2-i(d,"borderLeftWidth"),g=(d.offsetHeight-a.offsetHeight)/2-i(d,"borderTopWidth");b&&(e.left=f>0?f+"px":"0"),c&&(e.top=g>0?g+"px":"0")}function i(b,c){return parseInt(a.css(b,c),10)||0}a.fn._fadeIn=a.fn.fadeIn;var j=a.noop||function(){},k=/MSIE/.test(navigator.userAgent),l=/MSIE 6.0/.test(navigator.userAgent)&&!/MSIE 8.0/.test(navigator.userAgent),m=(document.documentMode||0,a.isFunction(document.createElement("div").style.setExpression));a.blockUI=function(a){b(window,a)},a.unblockUI=function(a){c(window,a)},a.growlUI=function(b,c,d,e){var f=a('
');b&&f.append("

"+b+"

"),c&&f.append("

"+c+"

"),void 0===d&&(d=3e3);var g=function(b){b=b||{},a.blockUI({message:f,fadeIn:"undefined"!=typeof b.fadeIn?b.fadeIn:700,fadeOut:"undefined"!=typeof b.fadeOut?b.fadeOut:1e3,timeout:"undefined"!=typeof b.timeout?b.timeout:d,centerY:!1,showOverlay:!1,onUnblock:e,css:a.blockUI.defaults.growlCSS})};g();f.css("opacity");f.mouseover(function(){g({fadeIn:0,timeout:3e4});var b=a(".blockMsg");b.stop(),b.fadeTo(300,1)}).mouseout(function(){a(".blockMsg").fadeOut(1e3)})},a.fn.block=function(c){if(this[0]===window)return a.blockUI(c),this;var d=a.extend({},a.blockUI.defaults,c||{});return this.each(function(){var b=a(this);d.ignoreIfBlocked&&b.data("blockUI.isBlocked")||b.unblock({fadeOut:0})}),this.each(function(){"static"==a.css(this,"position")&&(this.style.position="relative",a(this).data("blockUI.static",!0)),this.style.zoom=1,b(this,c)})},a.fn.unblock=function(b){return this[0]===window?(a.unblockUI(b),this):this.each(function(){c(this,b)})},a.blockUI.version=2.7,a.blockUI.defaults={message:"

Please wait...

",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1};var n=null,o=[]}"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],a):a(jQuery)}(),function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return md.apply(null,arguments)}function b(a){md=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)return!1;return!0}function f(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function g(a,b){var c,d=[];for(c=0;c0)for(c in od)d=od[c],e=b[d],o(e)||(a[d]=e);return a}function q(b){p(this,b),this._d=new Date(null!=b._d?b._d.getTime():0/0),pd===!1&&(pd=!0,a.updateOffset(this),pd=!1)}function r(a){return a instanceof q||null!=a&&null!=a._isAMomentObject}function s(a){return 0>a?Math.ceil(a)||0:Math.floor(a)}function t(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=s(b)),c}function u(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&t(a[d])!==t(b[d]))&&g++;return g+f}function v(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function w(b,c){var d=!0;return i(function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,b),d){for(var e,f=[],g=0;g0?"future":"past"];return y(c)?c(b):c.replace(/%s/i,b)}function I(a,b){var c=a.toLowerCase();zd[c]=zd[c+"s"]=zd[b]=a}function J(a){return"string"==typeof a?zd[a]||zd[a.toLowerCase()]:void 0}function K(a){var b,c,d={};for(c in a)h(a,c)&&(b=J(c),b&&(d[b]=a[c]));return d}function L(a,b){Ad[a]=b}function M(a){var b=[];for(var c in a)b.push({unit:c,priority:Ad[c]});return b.sort(function(a,b){return a.priority-b.priority}),b}function N(b,c){return function(d){return null!=d?(P(this,b,d),a.updateOffset(this,c),this):O(this,b)}}function O(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():0/0}function P(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function Q(a){return a=J(a),y(this[a])?this[a]():this}function R(a,b){if("object"==typeof a){a=K(a);for(var c=M(a),d=0;d=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function T(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Ed[a]=e),b&&(Ed[b[0]]=function(){return S(e.apply(this,arguments),b[1],b[2])}),c&&(Ed[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function U(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function V(a){var b,c,d=a.match(Bd);for(b=0,c=d.length;c>b;b++)d[b]=Ed[d[b]]?Ed[d[b]]:U(d[b]);return function(b){var e,f="";for(e=0;c>e;e++)f+=d[e]instanceof Function?d[e].call(b,a):d[e];return f}}function W(a,b){return a.isValid()?(b=X(b,a.localeData()),Dd[b]=Dd[b]||V(b),Dd[b](a)):a.localeData().invalidDate()}function X(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Cd.lastIndex=0;d>=0&&Cd.test(a);)a=a.replace(Cd,c),Cd.lastIndex=0,d-=1;return a}function Y(a,b,c){Wd[a]=y(b)?b:function(a){return a&&c?c:b}}function Z(a,b){return h(Wd,a)?Wd[a](b._strict,b._locale):new RegExp($(a))}function $(a){return _(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function _(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function aa(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=t(a)}),c=0;cd;++d)f=j([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=sd.call(this._shortMonthsParse,g),-1!==e?e:null):(e=sd.call(this._longMonthsParse,g),-1!==e?e:null):"MMM"===b?(e=sd.call(this._shortMonthsParse,g),-1!==e?e:(e=sd.call(this._longMonthsParse,g),-1!==e?e:null)):(e=sd.call(this._longMonthsParse,g),-1!==e?e:(e=sd.call(this._shortMonthsParse,g),-1!==e?e:null))}function ha(a,b,c){var d,e,f;if(this._monthsParseExact)return ga.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=j([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function ia(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=t(b);else if(b=a.localeData().monthsParse(b),"number"!=typeof b)return a;return c=Math.min(a.date(),da(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ja(b){return null!=b?(ia(this,b),a.updateOffset(this,!0),this):O(this,"Month")}function ka(){return da(this.year(),this.month())}function la(a){return this._monthsParseExact?(h(this,"_monthsRegex")||na.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=ie),this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex)}function ma(a){return this._monthsParseExact?(h(this,"_monthsRegex")||na.call(this),a?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=je),this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex)}function na(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=j([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=_(d[b]),e[b]=_(e[b]);for(b=0;24>b;b++)f[b]=_(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function oa(a){return pa(a)?366:365}function pa(a){return a%4===0&&a%100!==0||a%400===0}function qa(){return pa(this.year())}function ra(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function sa(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ta(a,b,c){var d=7+b-c,e=(7+sa(a,0,d).getUTCDay()-b)%7;return-e+d-1}function ua(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ta(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=oa(f)+j):j>oa(a)?(f=a+1,g=j-oa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function va(a,b,c){var d,e,f=ta(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+wa(e,b,c)):g>wa(a.year(),b,c)?(d=g-wa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function wa(a,b,c){var d=ta(a,b,c),e=ta(a+1,b,c);return(oa(a)-d+e)/7}function xa(a){return va(a,this._week.dow,this._week.doy).week}function ya(){return this._week.dow}function za(){return this._week.doy}function Aa(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ba(a){var b=va(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Ca(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Da(a,b){return"string"==typeof a?b.weekdaysParse(a)%7||7:isNaN(a)?null:a}function Ea(a,b){return a?c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]:this._weekdays}function Fa(a){return a?this._weekdaysShort[a.day()]:this._weekdaysShort}function Ga(a){return a?this._weekdaysMin[a.day()]:this._weekdaysMin}function Ha(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;7>d;++d)f=j([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=sd.call(this._weekdaysParse,g),-1!==e?e:null):"ddd"===b?(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:null):(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:null):"dddd"===b?(e=sd.call(this._weekdaysParse,g),-1!==e?e:(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:null))):"ddd"===b?(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:(e=sd.call(this._weekdaysParse,g),-1!==e?e:(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:null))):(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:(e=sd.call(this._weekdaysParse,g),-1!==e?e:(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:null)))}function Ia(a,b,c){var d,e,f;if(this._weekdaysParseExact)return Ha.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=j([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function Ja(a){if(!this.isValid())return null!=a?this:0/0;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Ca(a,this.localeData()),this.add(a-b,"d")):b}function Ka(a){if(!this.isValid())return null!=a?this:0/0;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function La(a){if(!this.isValid())return null!=a?this:0/0;if(null!=a){var b=Da(a,this.localeData());return this.day(this.day()%7?b:b-7)}return this.day()||7}function Ma(a){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Pa.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=pe),this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex)}function Na(a){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Pa.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=qe),this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Oa(a){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Pa.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=re),this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Pa(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],h=[],i=[],k=[];for(b=0;7>b;b++)c=j([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),h.push(e),i.push(f),k.push(d),k.push(e),k.push(f);for(g.sort(a),h.sort(a),i.sort(a),k.sort(a),b=0;7>b;b++)h[b]=_(h[b]),i[b]=_(i[b]),k[b]=_(k[b]);this._weekdaysRegex=new RegExp("^("+k.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function Qa(){return this.hours()%12||12}function Ra(){return this.hours()||24}function Sa(a,b){T(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Ta(a,b){return b._meridiemParse}function Ua(a){return"p"===(a+"").toLowerCase().charAt(0)}function Va(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Wa(a){return a?a.toLowerCase().replace("_","-"):a}function Xa(a){for(var b,c,d,e,f=0;f0;){if(d=Ya(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&u(e,c,!0)>=b-1)break;b--}f++}return null}function Ya(a){var b=null;if(!we[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=se._abbr,require("./locale/"+a),Za(b)}catch(c){}return we[a]}function Za(a,b){var c;return a&&(c=o(b)?ab(a):$a(a,b),c&&(se=c)),se._abbr}function $a(a,b){if(null!==b){var c=ve;return b.abbr=a,null!=we[a]?(x("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),c=we[a]._config):null!=b.parentLocale&&(null!=we[b.parentLocale]?c=we[b.parentLocale]._config:x("parentLocaleUndefined","specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/")),we[a]=new B(A(c,b)),Za(a),we[a]}return delete we[a],null}function _a(a,b){if(null!=b){var c,d=ve;null!=we[a]&&(d=we[a]._config),b=A(d,b),c=new B(b),c.parentLocale=we[a],we[a]=c,Za(a)}else null!=we[a]&&(null!=we[a].parentLocale?we[a]=we[a].parentLocale:null!=we[a]&&delete we[a]);return we[a]}function ab(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return se;if(!c(a)){if(b=Ya(a))return b;a=[a]}return Xa(a)}function bb(){return rd(we)}function cb(a){var b,c=a._a;return c&&-2===l(a).overflow&&(b=c[Zd]<0||c[Zd]>11?Zd:c[$d]<1||c[$d]>da(c[Yd],c[Zd])?$d:c[_d]<0||c[_d]>24||24===c[_d]&&(0!==c[ae]||0!==c[be]||0!==c[ce])?_d:c[ae]<0||c[ae]>59?ae:c[be]<0||c[be]>59?be:c[ce]<0||c[ce]>999?ce:-1,l(a)._overflowDayOfYear&&(Yd>b||b>$d)&&(b=$d),l(a)._overflowWeeks&&-1===b&&(b=de),l(a)._overflowWeekday&&-1===b&&(b=ee),l(a).overflow=b),a}function db(a){var b,c,d,e,f,g,h=a._i,i=xe.exec(h)||ye.exec(h);if(i){for(l(a).iso=!0,b=0,c=Ae.length;c>b;b++)if(Ae[b][1].exec(i[1])){e=Ae[b][0],d=Ae[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Be.length;c>b;b++)if(Be[b][1].exec(i[3])){f=(i[2]||" ")+Be[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!ze.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),jb(a)}else a._isValid=!1}function eb(b){var c=Ce.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(db(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function fb(a,b,c){return null!=a?a:null!=b?b:c}function gb(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function hb(a){var b,c,d,e,f=[];if(!a._d){for(d=gb(a),a._w&&null==a._a[$d]&&null==a._a[Zd]&&ib(a),a._dayOfYear&&(e=fb(a._a[Yd],d[Yd]),a._dayOfYear>oa(e)&&(l(a)._overflowDayOfYear=!0),c=sa(e,0,a._dayOfYear),a._a[Zd]=c.getUTCMonth(),a._a[$d]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[_d]&&0===a._a[ae]&&0===a._a[be]&&0===a._a[ce]&&(a._nextDay=!0,a._a[_d]=0),a._d=(a._useUTC?sa:ra).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[_d]=24)}}function ib(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=fb(b.GG,a._a[Yd],va(rb(),1,4).year),d=fb(b.W,1),e=fb(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=fb(b.gg,a._a[Yd],va(rb(),f,g).year),d=fb(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>wa(c,f,g)?l(a)._overflowWeeks=!0:null!=i?l(a)._overflowWeekday=!0:(h=ua(c,d,e,f,g),a._a[Yd]=h.year,a._dayOfYear=h.dayOfYear)}function jb(b){if(b._f===a.ISO_8601)return void db(b);b._a=[],l(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=X(b._f,b._locale).match(Bd)||[],c=0;c0&&l(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Ed[f]?(d?l(b).empty=!1:l(b).unusedTokens.push(f),ca(f,d,b)):b._strict&&!d&&l(b).unusedTokens.push(f);l(b).charsLeftOver=i-j,h.length>0&&l(b).unusedInput.push(h),b._a[_d]<=12&&l(b).bigHour===!0&&b._a[_d]>0&&(l(b).bigHour=void 0),l(b).parsedDateParts=b._a.slice(0),l(b).meridiem=b._meridiem,b._a[_d]=kb(b._locale,b._a[_d],b._meridiem),hb(b),cb(b)}function kb(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function lb(a){var b,c,d,e,f;if(0===a._f.length)return l(a).invalidFormat=!0,void(a._d=new Date(0/0));for(e=0;ef)&&(d=f,c=b));i(a,c||b)}function mb(a){if(!a._d){var b=K(a._i); + +a._a=g([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),hb(a)}}function nb(a){var b=new q(cb(ob(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function ob(a){var b=a._i,d=a._f;return a._locale=a._locale||ab(a._l),null===b||void 0===d&&""===b?n({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),r(b)?new q(cb(b)):(c(d)?lb(a):f(b)?a._d=b:d?jb(a):pb(a),m(a)||(a._d=null),a))}function pb(b){var d=b._i;void 0===d?b._d=new Date(a.now()):f(d)?b._d=new Date(d.valueOf()):"string"==typeof d?eb(b):c(d)?(b._a=g(d.slice(0),function(a){return parseInt(a,10)}),hb(b)):"object"==typeof d?mb(b):"number"==typeof d?b._d=new Date(d):a.createFromInputFallback(b)}function qb(a,b,f,g,h){var i={};return"boolean"==typeof f&&(g=f,f=void 0),(d(a)&&e(a)||c(a)&&0===a.length)&&(a=void 0),i._isAMomentObject=!0,i._useUTC=i._isUTC=h,i._l=f,i._i=a,i._f=b,i._strict=g,nb(i)}function rb(a,b,c,d){return qb(a,b,c,d,!1)}function sb(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return rb();for(d=b[0],e=1;ea?-1*Math.round(-1*a):Math.round(a)}function yb(a,b){T(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+S(~~(a/60),2)+b+S(~~a%60,2)})}function zb(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(Ge)||["-",0,0],f=+(60*e[1])+t(e[2]);return"+"===e[0]?f:-f}function Ab(b,c){var d,e;return c._isUTC?(d=c.clone(),e=(r(b)||f(b)?b.valueOf():rb(b).valueOf())-d.valueOf(),d._d.setTime(d._d.valueOf()+e),a.updateOffset(d,!1),d):rb(b).local()}function Bb(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Cb(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=zb(Td,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Bb(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?Sb(this,Nb(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Bb(this):null!=b?this:0/0}function Db(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Eb(a){return this.utcOffset(0,a)}function Fb(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Bb(this),"m")),this}function Gb(){if(this._tzm)this.utcOffset(this._tzm);else if("string"==typeof this._i){var a=zb(Sd,this._i);0===a?this.utcOffset(0,!0):this.utcOffset(zb(Sd,this._i))}return this}function Hb(a){return this.isValid()?(a=a?rb(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function Ib(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Jb(){if(!o(this._isDSTShifted))return this._isDSTShifted;var a={};if(p(a,this),a=ob(a),a._a){var b=a._isUTC?j(a._a):rb(a._a);this._isDSTShifted=this.isValid()&&u(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Kb(){return this.isValid()?!this._isUTC:!1}function Lb(){return this.isValid()?this._isUTC:!1}function Mb(){return this.isValid()?this._isUTC&&0===this._offset:!1}function Nb(a,b){var c,d,e,f=a,g=null;return wb(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(g=He.exec(a))?(c="-"===g[1]?-1:1,f={y:0,d:t(g[$d])*c,h:t(g[_d])*c,m:t(g[ae])*c,s:t(g[be])*c,ms:t(xb(1e3*g[ce]))*c}):(g=Ie.exec(a))?(c="-"===g[1]?-1:1,f={y:Ob(g[2],c),M:Ob(g[3],c),w:Ob(g[4],c),d:Ob(g[5],c),h:Ob(g[6],c),m:Ob(g[7],c),s:Ob(g[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Qb(rb(f.from),rb(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new vb(f),wb(a)&&h(a,"_locale")&&(d._locale=a._locale),d}function Ob(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function Pb(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Qb(a,b){var c;return a.isValid()&&b.isValid()?(b=Ab(b,a),a.isBefore(b)?c=Pb(a,b):(c=Pb(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function Rb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(x(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Nb(c,d),Sb(this,e,a),this}}function Sb(b,c,d,e){var f=c._milliseconds,g=xb(c._days),h=xb(c._months);b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&P(b,"Date",O(b,"Date")+g*d),h&&ia(b,O(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function Tb(a,b){var c=a.diff(b,"days",!0);return-6>c?"sameElse":-1>c?"lastWeek":0>c?"lastDay":1>c?"sameDay":2>c?"nextDay":7>c?"nextWeek":"sameElse"}function Ub(b,c){var d=b||rb(),e=Ab(d,this).startOf("day"),f=a.calendarFormat(this,e)||"sameElse",g=c&&(y(c[f])?c[f].call(this,d):c[f]);return this.format(g||this.localeData().calendar(f,this,rb(d)))}function Vb(){return new q(this)}function Wb(a,b){var c=r(a)?a:rb(a);return this.isValid()&&c.isValid()?(b=J(o(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function cc(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function dc(){var a=this.clone().utc();return 0f&&(b=f),Dc.call(this,a,b,c,d,e))}function Dc(a,b,c,d,e){var f=ua(a,b,c,d,e),g=sa(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Ec(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Fc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function Gc(a,b){b[ce]=t(1e3*("0."+a))}function Hc(){return this._isUTC?"UTC":""}function Ic(){return this._isUTC?"Coordinated Universal Time":""}function Jc(a){return rb(1e3*a)}function Kc(){return rb.apply(null,arguments).parseZone()}function Lc(a){return a}function Mc(a,b,c,d){var e=ab(),f=j().set(d,b);return e[c](f,a)}function Nc(a,b,c){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return Mc(a,b,c,"month");var d,e=[];for(d=0;12>d;d++)e[d]=Mc(a,d,c,"month");return e}function Oc(a,b,c,d){"boolean"==typeof a?("number"==typeof b&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,"number"==typeof b&&(c=b,b=void 0),b=b||"");var e=ab(),f=a?e._week.dow:0;if(null!=c)return Mc(b,(c+f)%7,d,"day");var g,h=[];for(g=0;7>g;g++)h[g]=Mc(b,(g+f)%7,d,"day");return h}function Pc(a,b){return Nc(a,b,"months")}function Qc(a,b){return Nc(a,b,"monthsShort")}function Rc(a,b,c){return Oc(a,b,c,"weekdays")}function Sc(a,b,c){return Oc(a,b,c,"weekdaysShort")}function Tc(a,b,c){return Oc(a,b,c,"weekdaysMin")}function Uc(){var a=this._data;return this._milliseconds=Ue(this._milliseconds),this._days=Ue(this._days),this._months=Ue(this._months),a.milliseconds=Ue(a.milliseconds),a.seconds=Ue(a.seconds),a.minutes=Ue(a.minutes),a.hours=Ue(a.hours),a.months=Ue(a.months),a.years=Ue(a.years),this}function Vc(a,b,c,d){var e=Nb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Wc(a,b){return Vc(this,a,b,1)}function Xc(a,b){return Vc(this,a,b,-1)}function Yc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Zc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Yc(_c(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=s(f/1e3),i.seconds=a%60,b=s(a/60),i.minutes=b%60,c=s(b/60),i.hours=c%24,g+=s(c/24),e=s($c(g)),h+=e,g-=Yc(_c(e)),d=s(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function $c(a){return 4800*a/146097}function _c(a){return 146097*a/4800}function ad(a){var b,c,d=this._milliseconds;if(a=J(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+$c(b),"month"===a?c:c/12;switch(b=this._days+Math.round(_c(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function bd(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*t(this._months/12)}function cd(a){return function(){return this.as(a)}}function dd(a){return a=J(a),this[a+"s"]()}function ed(a){return function(){return this._data[a]}}function fd(){return s(this.days()/7)}function gd(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function hd(a,b,c){var d=Nb(a).abs(),e=jf(d.as("s")),f=jf(d.as("m")),g=jf(d.as("h")),h=jf(d.as("d")),i=jf(d.as("M")),j=jf(d.as("y")),k=e=f&&["m"]||f=g&&["h"]||g=h&&["d"]||h=i&&["M"]||i=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,gd.apply(null,k)}function id(a){return void 0===a?jf:"function"==typeof a?(jf=a,!0):!1}function jd(a,b){return void 0===kf[a]?!1:void 0===b?kf[a]:(kf[a]=b,!0)}function kd(a){var b=this.localeData(),c=hd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function ld(){var a,b,c,d=lf(this._milliseconds)/1e3,e=lf(this._days),f=lf(this._months);a=s(d/60),b=s(a/60),d%=60,a%=60,c=s(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var md,nd;nd=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;c>d;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var od=a.momentProperties=[],pd=!1,qd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var rd;rd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)h(a,b)&&c.push(b);return c};var sd,td={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},ud={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},vd="Invalid date",wd="%d",xd=/\d{1,2}/,yd={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},zd={},Ad={},Bd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Cd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Dd={},Ed={},Fd=/\d/,Gd=/\d\d/,Hd=/\d{3}/,Id=/\d{4}/,Jd=/[+-]?\d{6}/,Kd=/\d\d?/,Ld=/\d\d\d\d?/,Md=/\d\d\d\d\d\d?/,Nd=/\d{1,3}/,Od=/\d{1,4}/,Pd=/[+-]?\d{1,6}/,Qd=/\d+/,Rd=/[+-]?\d+/,Sd=/Z|[+-]\d\d:?\d\d/gi,Td=/Z|[+-]\d\d(?::?\d\d)?/gi,Ud=/[+-]?\d+(\.\d{1,3})?/,Vd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Wd={},Xd={},Yd=0,Zd=1,$d=2,_d=3,ae=4,be=5,ce=6,de=7,ee=8;sd=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b=a?""+a:"+"+a}),T(0,["YY",2],0,function(){return this.year()%100}),T(0,["YYYY",4],0,"year"),T(0,["YYYYY",5],0,"year"),T(0,["YYYYYY",6,!0],0,"year"),I("year","y"),L("year",1),Y("Y",Rd),Y("YY",Kd,Gd),Y("YYYY",Od,Id),Y("YYYYY",Pd,Jd),Y("YYYYYY",Pd,Jd),aa(["YYYYY","YYYYYY"],Yd),aa("YYYY",function(b,c){c[Yd]=2===b.length?a.parseTwoDigitYear(b):t(b)}),aa("YY",function(b,c){c[Yd]=a.parseTwoDigitYear(b)}),aa("Y",function(a,b){b[Yd]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return t(a)+(t(a)>68?1900:2e3)};var ke=N("FullYear",!0);T("w",["ww",2],"wo","week"),T("W",["WW",2],"Wo","isoWeek"),I("week","w"),I("isoWeek","W"),L("week",5),L("isoWeek",5),Y("w",Kd),Y("ww",Kd,Gd),Y("W",Kd),Y("WW",Kd,Gd),ba(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=t(a)});var le={dow:0,doy:6};T("d",0,"do","day"),T("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),T("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),T("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),T("e",0,0,"weekday"),T("E",0,0,"isoWeekday"),I("day","d"),I("weekday","e"),I("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),Y("d",Kd),Y("e",Kd),Y("E",Kd),Y("dd",function(a,b){return b.weekdaysMinRegex(a)}),Y("ddd",function(a,b){return b.weekdaysShortRegex(a)}),Y("dddd",function(a,b){return b.weekdaysRegex(a)}),ba(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:l(c).invalidWeekday=a}),ba(["d","e","E"],function(a,b,c,d){b[d]=t(a)});var me="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ne="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),oe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),pe=Vd,qe=Vd,re=Vd;T("H",["HH",2],0,"hour"),T("h",["hh",2],0,Qa),T("k",["kk",2],0,Ra),T("hmm",0,0,function(){return""+Qa.apply(this)+S(this.minutes(),2)}),T("hmmss",0,0,function(){return""+Qa.apply(this)+S(this.minutes(),2)+S(this.seconds(),2)}),T("Hmm",0,0,function(){return""+this.hours()+S(this.minutes(),2)}),T("Hmmss",0,0,function(){return""+this.hours()+S(this.minutes(),2)+S(this.seconds(),2)}),Sa("a",!0),Sa("A",!1),I("hour","h"),L("hour",13),Y("a",Ta),Y("A",Ta),Y("H",Kd),Y("h",Kd),Y("HH",Kd,Gd),Y("hh",Kd,Gd),Y("hmm",Ld),Y("hmmss",Md),Y("Hmm",Ld),Y("Hmmss",Md),aa(["H","HH"],_d),aa(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),aa(["h","hh"],function(a,b,c){b[_d]=t(a),l(c).bigHour=!0}),aa("hmm",function(a,b,c){var d=a.length-2;b[_d]=t(a.substr(0,d)),b[ae]=t(a.substr(d)),l(c).bigHour=!0}),aa("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[_d]=t(a.substr(0,d)),b[ae]=t(a.substr(d,2)),b[be]=t(a.substr(e)),l(c).bigHour=!0}),aa("Hmm",function(a,b){var c=a.length-2;b[_d]=t(a.substr(0,c)),b[ae]=t(a.substr(c))}),aa("Hmmss",function(a,b){var c=a.length-4,d=a.length-2;b[_d]=t(a.substr(0,c)),b[ae]=t(a.substr(c,2)),b[be]=t(a.substr(d))});var se,te=/[ap]\.?m?\.?/i,ue=N("Hours",!0),ve={calendar:td,longDateFormat:ud,invalidDate:vd,ordinal:wd,ordinalParse:xd,relativeTime:yd,months:ge,monthsShort:he,week:le,weekdays:me,weekdaysMin:oe,weekdaysShort:ne,meridiemParse:te},we={},xe=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ye=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ze=/Z|[+-]\d\d(?::?\d\d)?/,Ae=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Be=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Ce=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),a.ISO_8601=function(){};var De=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=rb.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:n()}),Ee=w("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=rb.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:n()}),Fe=function(){return Date.now?Date.now():+new Date};yb("Z",":"),yb("ZZ",""),Y("Z",Td),Y("ZZ",Td),aa(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=zb(Td,a)});var Ge=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var He=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ie=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Nb.fn=vb.prototype;var Je=Rb(1,"add"),Ke=Rb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Le=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});T(0,["gg",2],0,function(){return this.weekYear()%100}),T(0,["GG",2],0,function(){return this.isoWeekYear()%100}),xc("gggg","weekYear"),xc("ggggg","weekYear"),xc("GGGG","isoWeekYear"),xc("GGGGG","isoWeekYear"),I("weekYear","gg"),I("isoWeekYear","GG"),L("weekYear",1),L("isoWeekYear",1),Y("G",Rd),Y("g",Rd),Y("GG",Kd,Gd),Y("gg",Kd,Gd),Y("GGGG",Od,Id),Y("gggg",Od,Id),Y("GGGGG",Pd,Jd),Y("ggggg",Pd,Jd),ba(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=t(a)}),ba(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),T("Q",0,"Qo","quarter"),I("quarter","Q"),L("quarter",7),Y("Q",Fd),aa("Q",function(a,b){b[Zd]=3*(t(a)-1)}),T("D",["DD",2],"Do","date"),I("date","D"),L("date",9),Y("D",Kd),Y("DD",Kd,Gd),Y("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),aa(["D","DD"],$d),aa("Do",function(a,b){b[$d]=t(a.match(Kd)[0],10)});var Me=N("Date",!0);T("DDD",["DDDD",3],"DDDo","dayOfYear"),I("dayOfYear","DDD"),L("dayOfYear",4),Y("DDD",Nd),Y("DDDD",Hd),aa(["DDD","DDDD"],function(a,b,c){c._dayOfYear=t(a)}),T("m",["mm",2],0,"minute"),I("minute","m"),L("minute",14),Y("m",Kd),Y("mm",Kd,Gd),aa(["m","mm"],ae);var Ne=N("Minutes",!1);T("s",["ss",2],0,"second"),I("second","s"),L("second",15),Y("s",Kd),Y("ss",Kd,Gd),aa(["s","ss"],be);var Oe=N("Seconds",!1);T("S",0,0,function(){return~~(this.millisecond()/100)}),T(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),T(0,["SSS",3],0,"millisecond"),T(0,["SSSS",4],0,function(){return 10*this.millisecond()}),T(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),T(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),T(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),T(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),T(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),I("millisecond","ms"),L("millisecond",16),Y("S",Nd,Fd),Y("SS",Nd,Gd),Y("SSS",Nd,Hd);var Pe;for(Pe="SSSS";Pe.length<=9;Pe+="S")Y(Pe,Qd);for(Pe="S";Pe.length<=9;Pe+="S")aa(Pe,Gc);var Qe=N("Milliseconds",!1);T("z",0,0,"zoneAbbr"),T("zz",0,0,"zoneName");var Re=q.prototype;Re.add=Je,Re.calendar=Ub,Re.clone=Vb,Re.diff=ac,Re.endOf=mc,Re.format=ec,Re.from=fc,Re.fromNow=gc,Re.to=hc,Re.toNow=ic,Re.get=Q,Re.invalidAt=vc,Re.isAfter=Wb,Re.isBefore=Xb,Re.isBetween=Yb,Re.isSame=Zb,Re.isSameOrAfter=$b,Re.isSameOrBefore=_b,Re.isValid=tc,Re.lang=Le,Re.locale=jc,Re.localeData=kc,Re.max=Ee,Re.min=De,Re.parsingFlags=uc,Re.set=R,Re.startOf=lc,Re.subtract=Ke,Re.toArray=qc,Re.toObject=rc,Re.toDate=pc,Re.toISOString=dc,Re.toJSON=sc,Re.toString=cc,Re.unix=oc,Re.valueOf=nc,Re.creationData=wc,Re.year=ke,Re.isLeapYear=qa,Re.weekYear=yc,Re.isoWeekYear=zc,Re.quarter=Re.quarters=Ec,Re.month=ja,Re.daysInMonth=ka,Re.week=Re.weeks=Aa,Re.isoWeek=Re.isoWeeks=Ba,Re.weeksInYear=Bc,Re.isoWeeksInYear=Ac,Re.date=Me,Re.day=Re.days=Ja,Re.weekday=Ka,Re.isoWeekday=La,Re.dayOfYear=Fc,Re.hour=Re.hours=ue,Re.minute=Re.minutes=Ne,Re.second=Re.seconds=Oe,Re.millisecond=Re.milliseconds=Qe,Re.utcOffset=Cb,Re.utc=Eb,Re.local=Fb,Re.parseZone=Gb,Re.hasAlignedHourOffset=Hb,Re.isDST=Ib,Re.isLocal=Kb,Re.isUtcOffset=Lb,Re.isUtc=Mb,Re.isUTC=Mb,Re.zoneAbbr=Hc,Re.zoneName=Ic,Re.dates=w("dates accessor is deprecated. Use date instead.",Me),Re.months=w("months accessor is deprecated. Use month instead",ja),Re.years=w("years accessor is deprecated. Use year instead",ke),Re.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Db),Re.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Jb);var Se=Re,Te=B.prototype;Te.calendar=C,Te.longDateFormat=D,Te.invalidDate=E,Te.ordinal=F,Te.preparse=Lc,Te.postformat=Lc,Te.relativeTime=G,Te.pastFuture=H,Te.set=z,Te.months=ea,Te.monthsShort=fa,Te.monthsParse=ha,Te.monthsRegex=ma,Te.monthsShortRegex=la,Te.week=xa,Te.firstDayOfYear=za,Te.firstDayOfWeek=ya,Te.weekdays=Ea,Te.weekdaysMin=Ga,Te.weekdaysShort=Fa,Te.weekdaysParse=Ia,Te.weekdaysRegex=Ma,Te.weekdaysShortRegex=Na,Te.weekdaysMinRegex=Oa,Te.isPM=Ua,Te.meridiem=Va,Za("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===t(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=w("moment.lang is deprecated. Use moment.locale instead.",Za),a.langData=w("moment.langData is deprecated. Use moment.localeData instead.",ab);var Ue=Math.abs,Ve=cd("ms"),We=cd("s"),Xe=cd("m"),Ye=cd("h"),Ze=cd("d"),$e=cd("w"),_e=cd("M"),af=cd("y"),bf=ed("milliseconds"),cf=ed("seconds"),df=ed("minutes"),ef=ed("hours"),ff=ed("days"),gf=ed("months"),hf=ed("years"),jf=Math.round,kf={s:45,m:45,h:22,d:26,M:11},lf=Math.abs,mf=vb.prototype;mf.abs=Uc,mf.add=Wc,mf.subtract=Xc,mf.as=ad,mf.asMilliseconds=Ve,mf.asSeconds=We,mf.asMinutes=Xe,mf.asHours=Ye,mf.asDays=Ze,mf.asWeeks=$e,mf.asMonths=_e,mf.asYears=af,mf.valueOf=bd,mf._bubble=Zc,mf.get=dd,mf.milliseconds=bf,mf.seconds=cf,mf.minutes=df,mf.hours=ef,mf.days=ff,mf.weeks=fd,mf.months=gf,mf.years=hf,mf.humanize=kd,mf.toISOString=ld,mf.toString=ld,mf.toJSON=ld,mf.locale=jc,mf.localeData=kc,mf.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ld),mf.lang=Le,T("X",0,0,"unix"),T("x",0,0,"valueOf"),Y("x",Rd),Y("X",Ud),aa("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),aa("x",function(a,b,c){c._d=new Date(t(a))}),a.version="2.15.1",b(rb),a.fn=Se,a.min=tb,a.max=ub,a.now=Fe,a.utc=j,a.unix=Jc,a.months=Pc,a.isDate=f,a.locale=Za,a.invalid=n,a.duration=Nb,a.isMoment=r,a.weekdays=Rc,a.parseZone=Kc,a.localeData=ab,a.isDuration=wb,a.monthsShort=Qc,a.weekdaysMin=Tc,a.defineLocale=$a,a.updateLocale=_a,a.locales=bb,a.weekdaysShort=Sc,a.normalizeUnits=J,a.relativeTimeRounding=id,a.relativeTimeThreshold=jd,a.calendarFormat=Tb,a.prototype=Se;var nf=a;return nf}),function(a,b){if("function"==typeof define&&define.amd)define(["moment","jquery"],function(c,d){return a.daterangepicker=b(c,d)});else if("object"==typeof module&&module.exports){var c="undefined"!=typeof window?window.jQuery:void 0;c||(c=require("jquery"),c.fn||(c.fn={})),module.exports=b(require("moment"),c)}else a.daterangepicker=b(a.moment,a.jQuery)}(this,function(a,b){var c=function(c,d,e){if(this.parentEl="body",this.element=b(c),this.startDate=a().startOf("day"),this.endDate=a().endOf("day"),this.minDate=!1,this.maxDate=!1,this.dateLimit=!1,this.autoApply=!1,this.singleDatePicker=!1,this.showDropdowns=!1,this.showWeekNumbers=!1,this.showISOWeekNumbers=!1,this.showCustomRangeLabel=!0,this.timePicker=!1,this.timePicker24Hour=!1,this.timePickerIncrement=1,this.timePickerSeconds=!1,this.linkedCalendars=!0,this.autoUpdateInput=!0,this.alwaysShowCalendars=!1,this.ranges={},this.opens="right",this.element.hasClass("pull-right")&&(this.opens="left"),this.drops="down",this.element.hasClass("dropup")&&(this.drops="up"),this.buttonClasses="btn btn-sm",this.applyClass="btn-success",this.cancelClass="btn-default",this.locale={direction:"ltr",format:"MM/DD/YYYY",separator:" - ",applyLabel:"Apply",cancelLabel:"Cancel",weekLabel:"W",customRangeLabel:"Custom Range",daysOfWeek:a.weekdaysMin(),monthNames:a.monthsShort(),firstDay:a.localeData().firstDayOfWeek()},this.callback=function(){},this.isShowing=!1,this.leftCalendar={},this.rightCalendar={},("object"!=typeof d||null===d)&&(d={}),d=b.extend(this.element.data(),d),"string"==typeof d.template||d.template instanceof b||(d.template=''),this.parentEl=b(d.parentEl&&b(d.parentEl).length?d.parentEl:this.parentEl),this.container=b(d.template).appendTo(this.parentEl),"object"==typeof d.locale&&("string"==typeof d.locale.direction&&(this.locale.direction=d.locale.direction),"string"==typeof d.locale.format&&(this.locale.format=d.locale.format),"string"==typeof d.locale.separator&&(this.locale.separator=d.locale.separator),"object"==typeof d.locale.daysOfWeek&&(this.locale.daysOfWeek=d.locale.daysOfWeek.slice()),"object"==typeof d.locale.monthNames&&(this.locale.monthNames=d.locale.monthNames.slice()),"number"==typeof d.locale.firstDay&&(this.locale.firstDay=d.locale.firstDay),"string"==typeof d.locale.applyLabel&&(this.locale.applyLabel=d.locale.applyLabel),"string"==typeof d.locale.cancelLabel&&(this.locale.cancelLabel=d.locale.cancelLabel),"string"==typeof d.locale.weekLabel&&(this.locale.weekLabel=d.locale.weekLabel),"string"==typeof d.locale.customRangeLabel&&(this.locale.customRangeLabel=d.locale.customRangeLabel)),this.container.addClass(this.locale.direction),"string"==typeof d.startDate&&(this.startDate=a(d.startDate,this.locale.format)),"string"==typeof d.endDate&&(this.endDate=a(d.endDate,this.locale.format)),"string"==typeof d.minDate&&(this.minDate=a(d.minDate,this.locale.format)),"string"==typeof d.maxDate&&(this.maxDate=a(d.maxDate,this.locale.format)),"object"==typeof d.startDate&&(this.startDate=a(d.startDate)),"object"==typeof d.endDate&&(this.endDate=a(d.endDate)),"object"==typeof d.minDate&&(this.minDate=a(d.minDate)),"object"==typeof d.maxDate&&(this.maxDate=a(d.maxDate)),this.minDate&&this.startDate.isBefore(this.minDate)&&(this.startDate=this.minDate.clone()),this.maxDate&&this.endDate.isAfter(this.maxDate)&&(this.endDate=this.maxDate.clone()),"string"==typeof d.applyClass&&(this.applyClass=d.applyClass), +"string"==typeof d.cancelClass&&(this.cancelClass=d.cancelClass),"object"==typeof d.dateLimit&&(this.dateLimit=d.dateLimit),"string"==typeof d.opens&&(this.opens=d.opens),"string"==typeof d.drops&&(this.drops=d.drops),"boolean"==typeof d.showWeekNumbers&&(this.showWeekNumbers=d.showWeekNumbers),"boolean"==typeof d.showISOWeekNumbers&&(this.showISOWeekNumbers=d.showISOWeekNumbers),"string"==typeof d.buttonClasses&&(this.buttonClasses=d.buttonClasses),"object"==typeof d.buttonClasses&&(this.buttonClasses=d.buttonClasses.join(" ")),"boolean"==typeof d.showDropdowns&&(this.showDropdowns=d.showDropdowns),"boolean"==typeof d.showCustomRangeLabel&&(this.showCustomRangeLabel=d.showCustomRangeLabel),"boolean"==typeof d.singleDatePicker&&(this.singleDatePicker=d.singleDatePicker,this.singleDatePicker&&(this.endDate=this.startDate.clone())),"boolean"==typeof d.timePicker&&(this.timePicker=d.timePicker),"boolean"==typeof d.timePickerSeconds&&(this.timePickerSeconds=d.timePickerSeconds),"number"==typeof d.timePickerIncrement&&(this.timePickerIncrement=d.timePickerIncrement),"boolean"==typeof d.timePicker24Hour&&(this.timePicker24Hour=d.timePicker24Hour),"boolean"==typeof d.autoApply&&(this.autoApply=d.autoApply),"boolean"==typeof d.autoUpdateInput&&(this.autoUpdateInput=d.autoUpdateInput),"boolean"==typeof d.linkedCalendars&&(this.linkedCalendars=d.linkedCalendars),"function"==typeof d.isInvalidDate&&(this.isInvalidDate=d.isInvalidDate),"function"==typeof d.isCustomDate&&(this.isCustomDate=d.isCustomDate),"boolean"==typeof d.alwaysShowCalendars&&(this.alwaysShowCalendars=d.alwaysShowCalendars),0!=this.locale.firstDay)for(var f=this.locale.firstDay;f>0;)this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()),f--;var g,h,i;if("undefined"==typeof d.startDate&&"undefined"==typeof d.endDate&&b(this.element).is("input[type=text]")){var j=b(this.element).val(),k=j.split(this.locale.separator);g=h=null,2==k.length?(g=a(k[0],this.locale.format),h=a(k[1],this.locale.format)):this.singleDatePicker&&""!==j&&(g=a(j,this.locale.format),h=a(j,this.locale.format)),null!==g&&null!==h&&(this.setStartDate(g),this.setEndDate(h))}if("object"==typeof d.ranges){for(i in d.ranges){g="string"==typeof d.ranges[i][0]?a(d.ranges[i][0],this.locale.format):a(d.ranges[i][0]),h="string"==typeof d.ranges[i][1]?a(d.ranges[i][1],this.locale.format):a(d.ranges[i][1]),this.minDate&&g.isBefore(this.minDate)&&(g=this.minDate.clone());var l=this.maxDate;if(this.dateLimit&&l&&g.clone().add(this.dateLimit).isAfter(l)&&(l=g.clone().add(this.dateLimit)),l&&h.isAfter(l)&&(h=l.clone()),!(this.minDate&&h.isBefore(this.minDate,this.timepicker?"minute":"day")||l&&g.isAfter(l,this.timepicker?"minute":"day"))){var m=document.createElement("textarea");m.innerHTML=i;var n=m.value;this.ranges[n]=[g,h]}}var o="
    ";for(i in this.ranges)o+='
  • '+i+"
  • ";this.showCustomRangeLabel&&(o+='
  • '+this.locale.customRangeLabel+"
  • "),o+="
",this.container.find(".ranges").prepend(o)}"function"==typeof e&&(this.callback=e),this.timePicker||(this.startDate=this.startDate.startOf("day"),this.endDate=this.endDate.endOf("day"),this.container.find(".calendar-time").hide()),this.timePicker&&this.autoApply&&(this.autoApply=!1),this.autoApply&&"object"!=typeof d.ranges?this.container.find(".ranges").hide():this.autoApply&&this.container.find(".applyBtn, .cancelBtn").addClass("hide"),this.singleDatePicker&&(this.container.addClass("single"),this.container.find(".calendar.left").addClass("single"),this.container.find(".calendar.left").show(),this.container.find(".calendar.right").hide(),this.container.find(".daterangepicker_input input, .daterangepicker_input > i").hide(),this.timePicker?this.container.find(".ranges ul").hide():this.container.find(".ranges").hide()),("undefined"==typeof d.ranges&&!this.singleDatePicker||this.alwaysShowCalendars)&&this.container.addClass("show-calendar"),this.container.addClass("opens"+this.opens),"undefined"!=typeof d.ranges&&"right"==this.opens&&this.container.find(".ranges").prependTo(this.container.find(".calendar.left").parent()),this.container.find(".applyBtn, .cancelBtn").addClass(this.buttonClasses),this.applyClass.length&&this.container.find(".applyBtn").addClass(this.applyClass),this.cancelClass.length&&this.container.find(".cancelBtn").addClass(this.cancelClass),this.container.find(".applyBtn").html(this.locale.applyLabel),this.container.find(".cancelBtn").html(this.locale.cancelLabel),this.container.find(".calendar").on("click.daterangepicker",".prev",b.proxy(this.clickPrev,this)).on("click.daterangepicker",".next",b.proxy(this.clickNext,this)).on("mousedown.daterangepicker","td.available",b.proxy(this.clickDate,this)).on("mouseenter.daterangepicker","td.available",b.proxy(this.hoverDate,this)).on("mouseleave.daterangepicker","td.available",b.proxy(this.updateFormInputs,this)).on("change.daterangepicker","select.yearselect",b.proxy(this.monthOrYearChanged,this)).on("change.daterangepicker","select.monthselect",b.proxy(this.monthOrYearChanged,this)).on("change.daterangepicker","select.hourselect,select.minuteselect,select.secondselect,select.ampmselect",b.proxy(this.timeChanged,this)).on("click.daterangepicker",".daterangepicker_input input",b.proxy(this.showCalendars,this)).on("focus.daterangepicker",".daterangepicker_input input",b.proxy(this.formInputsFocused,this)).on("blur.daterangepicker",".daterangepicker_input input",b.proxy(this.formInputsBlurred,this)).on("change.daterangepicker",".daterangepicker_input input",b.proxy(this.formInputsChanged,this)),this.container.find(".ranges").on("click.daterangepicker","button.applyBtn",b.proxy(this.clickApply,this)).on("click.daterangepicker","button.cancelBtn",b.proxy(this.clickCancel,this)).on("click.daterangepicker","li",b.proxy(this.clickRange,this)).on("mouseenter.daterangepicker","li",b.proxy(this.hoverRange,this)).on("mouseleave.daterangepicker","li",b.proxy(this.updateFormInputs,this)),this.element.is("input")||this.element.is("button")?this.element.on({"click.daterangepicker":b.proxy(this.show,this),"focus.daterangepicker":b.proxy(this.show,this),"keyup.daterangepicker":b.proxy(this.elementChanged,this),"keydown.daterangepicker":b.proxy(this.keydown,this)}):this.element.on("click.daterangepicker",b.proxy(this.toggle,this)),this.element.is("input")&&!this.singleDatePicker&&this.autoUpdateInput?(this.element.val(this.startDate.format(this.locale.format)+this.locale.separator+this.endDate.format(this.locale.format)),this.element.trigger("change")):this.element.is("input")&&this.autoUpdateInput&&(this.element.val(this.startDate.format(this.locale.format)),this.element.trigger("change"))};return c.prototype={constructor:c,setStartDate:function(b){"string"==typeof b&&(this.startDate=a(b,this.locale.format)),"object"==typeof b&&(this.startDate=a(b)),this.timePicker||(this.startDate=this.startDate.startOf("day")),this.timePicker&&this.timePickerIncrement&&this.startDate.minute(Math.round(this.startDate.minute()/this.timePickerIncrement)*this.timePickerIncrement),this.minDate&&this.startDate.isBefore(this.minDate)&&(this.startDate=this.minDate,this.timePicker&&this.timePickerIncrement&&this.startDate.minute(Math.round(this.startDate.minute()/this.timePickerIncrement)*this.timePickerIncrement)),this.maxDate&&this.startDate.isAfter(this.maxDate)&&(this.startDate=this.maxDate,this.timePicker&&this.timePickerIncrement&&this.startDate.minute(Math.floor(this.startDate.minute()/this.timePickerIncrement)*this.timePickerIncrement)),this.isShowing||this.updateElement(),this.updateMonthsInView()},setEndDate:function(b){"string"==typeof b&&(this.endDate=a(b,this.locale.format)),"object"==typeof b&&(this.endDate=a(b)),this.timePicker||(this.endDate=this.endDate.endOf("day")),this.timePicker&&this.timePickerIncrement&&this.endDate.minute(Math.round(this.endDate.minute()/this.timePickerIncrement)*this.timePickerIncrement),this.endDate.isBefore(this.startDate)&&(this.endDate=this.startDate.clone()),this.maxDate&&this.endDate.isAfter(this.maxDate)&&(this.endDate=this.maxDate),this.dateLimit&&this.startDate.clone().add(this.dateLimit).isBefore(this.endDate)&&(this.endDate=this.startDate.clone().add(this.dateLimit)),this.previousRightTime=this.endDate.clone(),this.isShowing||this.updateElement(),this.updateMonthsInView()},isInvalidDate:function(){return!1},isCustomDate:function(){return!1},updateView:function(){this.timePicker&&(this.renderTimePicker("left"),this.renderTimePicker("right"),this.endDate?this.container.find(".right .calendar-time select").removeAttr("disabled").removeClass("disabled"):this.container.find(".right .calendar-time select").attr("disabled","disabled").addClass("disabled")),this.endDate?(this.container.find('input[name="daterangepicker_end"]').removeClass("active"),this.container.find('input[name="daterangepicker_start"]').addClass("active")):(this.container.find('input[name="daterangepicker_end"]').addClass("active"),this.container.find('input[name="daterangepicker_start"]').removeClass("active")),this.updateMonthsInView(),this.updateCalendars(),this.updateFormInputs()},updateMonthsInView:function(){if(this.endDate){if(!this.singleDatePicker&&this.leftCalendar.month&&this.rightCalendar.month&&(this.startDate.format("YYYY-MM")==this.leftCalendar.month.format("YYYY-MM")||this.startDate.format("YYYY-MM")==this.rightCalendar.month.format("YYYY-MM"))&&(this.endDate.format("YYYY-MM")==this.leftCalendar.month.format("YYYY-MM")||this.endDate.format("YYYY-MM")==this.rightCalendar.month.format("YYYY-MM")))return;this.leftCalendar.month=this.startDate.clone().date(2),this.rightCalendar.month=this.linkedCalendars||this.endDate.month()==this.startDate.month()&&this.endDate.year()==this.startDate.year()?this.startDate.clone().date(2).add(1,"month"):this.endDate.clone().date(2)}else this.leftCalendar.month.format("YYYY-MM")!=this.startDate.format("YYYY-MM")&&this.rightCalendar.month.format("YYYY-MM")!=this.startDate.format("YYYY-MM")&&(this.leftCalendar.month=this.startDate.clone().date(2),this.rightCalendar.month=this.startDate.clone().date(2).add(1,"month"));this.maxDate&&this.linkedCalendars&&!this.singleDatePicker&&this.rightCalendar.month>this.maxDate&&(this.rightCalendar.month=this.maxDate.clone().date(2),this.leftCalendar.month=this.maxDate.clone().date(2).subtract(1,"month"))},updateCalendars:function(){if(this.timePicker){var a,b,c;if(this.endDate){if(a=parseInt(this.container.find(".left .hourselect").val(),10),b=parseInt(this.container.find(".left .minuteselect").val(),10),c=this.timePickerSeconds?parseInt(this.container.find(".left .secondselect").val(),10):0,!this.timePicker24Hour){var d=this.container.find(".left .ampmselect").val();"PM"===d&&12>a&&(a+=12),"AM"===d&&12===a&&(a=0)}}else if(a=parseInt(this.container.find(".right .hourselect").val(),10),b=parseInt(this.container.find(".right .minuteselect").val(),10),c=this.timePickerSeconds?parseInt(this.container.find(".right .secondselect").val(),10):0,!this.timePicker24Hour){var d=this.container.find(".right .ampmselect").val();"PM"===d&&12>a&&(a+=12),"AM"===d&&12===a&&(a=0)}this.leftCalendar.month.hour(a).minute(b).second(c),this.rightCalendar.month.hour(a).minute(b).second(c)}this.renderCalendar("left"),this.renderCalendar("right"),this.container.find(".ranges li").removeClass("active"),null!=this.endDate&&this.calculateChosenLabel()},renderCalendar:function(c){var d="left"==c?this.leftCalendar:this.rightCalendar,e=d.month.month(),f=d.month.year(),g=d.month.hour(),h=d.month.minute(),i=d.month.second(),j=a([f,e]).daysInMonth(),k=a([f,e,1]),l=a([f,e,j]),m=a(k).subtract(1,"month").month(),n=a(k).subtract(1,"month").year(),o=a([n,m]).daysInMonth(),p=k.day(),d=[];d.firstDay=k,d.lastDay=l;for(var q=0;6>q;q++)d[q]=[];var r=o-p+this.locale.firstDay+1;r>o&&(r-=7),p==this.locale.firstDay&&(r=o-6);for(var s,t,u=a([n,m,r,12,h,i]),q=0,s=0,t=0;42>q;q++,s++,u=a(u).add(24,"hour"))q>0&&s%7===0&&(s=0,t++),d[t][s]=u.clone().hour(g).minute(h).second(i),u.hour(12),this.minDate&&d[t][s].format("YYYY-MM-DD")==this.minDate.format("YYYY-MM-DD")&&d[t][s].isBefore(this.minDate)&&"left"==c&&(d[t][s]=this.minDate.clone()),this.maxDate&&d[t][s].format("YYYY-MM-DD")==this.maxDate.format("YYYY-MM-DD")&&d[t][s].isAfter(this.maxDate)&&"right"==c&&(d[t][s]=this.maxDate.clone());"left"==c?this.leftCalendar.calendar=d:this.rightCalendar.calendar=d;var v="left"==c?this.minDate:this.startDate,w=this.maxDate,x=("left"==c?this.startDate:this.endDate,"ltr"==this.locale.direction?{left:"chevron-left",right:"chevron-right"}:{left:"chevron-right",right:"chevron-left"}),y='
';y+="",y+="",(this.showWeekNumbers||this.showISOWeekNumbers)&&(y+=""),y+=v&&!v.isBefore(d.firstDay)||this.linkedCalendars&&"left"!=c?"":'';var z=this.locale.monthNames[d[1][1].month()]+d[1][1].format(" YYYY");if(this.showDropdowns){for(var A=d[1][1].month(),B=d[1][1].year(),C=w&&w.year()||B+5,D=v&&v.year()||B-50,E=B==D,F=B==C,G='";for(var I='",z=G+I}if(y+='",y+=w&&!w.isAfter(d.lastDay)||this.linkedCalendars&&"right"!=c&&!this.singleDatePicker?"":'',y+="",y+="",(this.showWeekNumbers||this.showISOWeekNumbers)&&(y+='"),b.each(this.locale.daysOfWeek,function(a,b){y+=""}),y+="",y+="",y+="",null==this.endDate&&this.dateLimit){var K=this.startDate.clone().add(this.dateLimit).endOf("day");(!w||K.isBefore(w))&&(w=K)}for(var t=0;6>t;t++){y+="",this.showWeekNumbers?y+='":this.showISOWeekNumbers&&(y+='");for(var s=0;7>s;s++){var L=[];d[t][s].isSame(new Date,"day")&&L.push("today"),d[t][s].isoWeekday()>5&&L.push("weekend"),d[t][s].month()!=d[1][1].month()&&L.push("off"),this.minDate&&d[t][s].isBefore(this.minDate,"day")&&L.push("off","disabled"),w&&d[t][s].isAfter(w,"day")&&L.push("off","disabled"),this.isInvalidDate(d[t][s])&&L.push("off","disabled"),d[t][s].format("YYYY-MM-DD")==this.startDate.format("YYYY-MM-DD")&&L.push("active","start-date"),null!=this.endDate&&d[t][s].format("YYYY-MM-DD")==this.endDate.format("YYYY-MM-DD")&&L.push("active","end-date"),null!=this.endDate&&d[t][s]>this.startDate&&d[t][s]'+d[t][s].date()+""}y+=""}y+="",y+="
'+z+"
'+this.locale.weekLabel+""+b+"
'+d[t][0].week()+"'+d[t][0].isoWeek()+"
",this.container.find(".calendar."+c+" .calendar-table").html(y)},renderTimePicker:function(a){if("right"!=a||this.endDate){var b,c,d,e=this.maxDate;if(!this.dateLimit||this.maxDate&&!this.startDate.clone().add(this.dateLimit).isAfter(this.maxDate)||(e=this.startDate.clone().add(this.dateLimit)),"left"==a)c=this.startDate.clone(),d=this.minDate;else if("right"==a){c=this.endDate.clone(),d=this.startDate;var f=this.container.find(".calendar.right .calendar-time div");if(!this.endDate&&""!=f.html()&&(c.hour(f.find(".hourselect option:selected").val()||c.hour()),c.minute(f.find(".minuteselect option:selected").val()||c.minute()),c.second(f.find(".secondselect option:selected").val()||c.second()),!this.timePicker24Hour)){var g=f.find(".ampmselect option:selected").val();"PM"===g&&c.hour()<12&&c.hour(c.hour()+12),"AM"===g&&12===c.hour()&&c.hour(0)}c.isBefore(this.startDate)&&(c=this.startDate.clone()),e&&c.isAfter(e)&&(c=e.clone())}b=' ",b+=': ",this.timePickerSeconds){b+=': "}if(!this.timePicker24Hour){b+='"}this.container.find(".calendar."+a+" .calendar-time div").html(b)}},updateFormInputs:function(){this.container.find("input[name=daterangepicker_start]").is(":focus")||this.container.find("input[name=daterangepicker_end]").is(":focus")||(this.container.find("input[name=daterangepicker_start]").val(this.startDate.format(this.locale.format)),this.endDate&&this.container.find("input[name=daterangepicker_end]").val(this.endDate.format(this.locale.format)),this.singleDatePicker||this.endDate&&(this.startDate.isBefore(this.endDate)||this.startDate.isSame(this.endDate))?this.container.find("button.applyBtn").removeAttr("disabled"):this.container.find("button.applyBtn").attr("disabled","disabled"))},move:function(){var a,c={top:0,left:0},d=b(window).width();this.parentEl.is("body")||(c={top:this.parentEl.offset().top-this.parentEl.scrollTop(),left:this.parentEl.offset().left-this.parentEl.scrollLeft()},d=this.parentEl[0].clientWidth+this.parentEl.offset().left),a="up"==this.drops?this.element.offset().top-this.container.outerHeight()-c.top:this.element.offset().top+this.element.outerHeight()-c.top,this.container["up"==this.drops?"addClass":"removeClass"]("dropup"),"left"==this.opens?(this.container.css({top:a,right:d-this.element.offset().left-this.element.outerWidth(),left:"auto"}),this.container.offset().left<0&&this.container.css({right:"auto",left:9})):"center"==this.opens?(this.container.css({top:a,left:this.element.offset().left-c.left+this.element.outerWidth()/2-this.container.outerWidth()/2,right:"auto"}),this.container.offset().left<0&&this.container.css({right:"auto",left:9})):(this.container.css({top:a,left:this.element.offset().left-c.left,right:"auto"}),this.container.offset().left+this.container.outerWidth()>b(window).width()&&this.container.css({left:"auto",right:0}))},show:function(){this.isShowing||(this._outsideClickProxy=b.proxy(function(a){this.outsideClick(a)},this),b(document).on("mousedown.daterangepicker",this._outsideClickProxy).on("touchend.daterangepicker",this._outsideClickProxy).on("click.daterangepicker","[data-toggle=dropdown]",this._outsideClickProxy).on("focusin.daterangepicker",this._outsideClickProxy),b(window).on("resize.daterangepicker",b.proxy(function(a){this.move(a)},this)),this.oldStartDate=this.startDate.clone(),this.oldEndDate=this.endDate.clone(),this.previousRightTime=this.endDate.clone(),this.updateView(),this.container.show(),this.move(),this.element.trigger("show.daterangepicker",this),this.isShowing=!0)},hide:function(){this.isShowing&&(this.endDate||(this.startDate=this.oldStartDate.clone(),this.endDate=this.oldEndDate.clone()),this.startDate.isSame(this.oldStartDate)&&this.endDate.isSame(this.oldEndDate)||this.callback(this.startDate,this.endDate,this.chosenLabel),this.updateElement(),b(document).off(".daterangepicker"),b(window).off(".daterangepicker"),this.container.hide(),this.element.trigger("hide.daterangepicker",this),this.isShowing=!1)},toggle:function(){this.isShowing?this.hide():this.show()},outsideClick:function(a){var c=b(a.target);"focusin"==a.type||c.closest(this.element).length||c.closest(this.container).length||c.closest(".calendar-table").length||(this.hide(),this.element.trigger("outsideClick.daterangepicker",this))},showCalendars:function(){this.container.addClass("show-calendar"),this.move(),this.element.trigger("showCalendar.daterangepicker",this)},hideCalendars:function(){this.container.removeClass("show-calendar"),this.element.trigger("hideCalendar.daterangepicker",this)},hoverRange:function(a){if(!this.container.find("input[name=daterangepicker_start]").is(":focus")&&!this.container.find("input[name=daterangepicker_end]").is(":focus")){var b=a.target.getAttribute("data-range-key");if(b==this.locale.customRangeLabel)this.updateView();else{var c=this.ranges[b];this.container.find("input[name=daterangepicker_start]").val(c[0].format(this.locale.format)),this.container.find("input[name=daterangepicker_end]").val(c[1].format(this.locale.format))}}},clickRange:function(a){var b=a.target.getAttribute("data-range-key");if(this.chosenLabel=b,b==this.locale.customRangeLabel)this.showCalendars();else{var c=this.ranges[b];this.startDate=c[0],this.endDate=c[1],this.timePicker||(this.startDate.startOf("day"),this.endDate.endOf("day")),this.alwaysShowCalendars||this.hideCalendars(),this.clickApply()}},clickPrev:function(a){var c=b(a.target).parents(".calendar");c.hasClass("left")?(this.leftCalendar.month.subtract(1,"month"),this.linkedCalendars&&this.rightCalendar.month.subtract(1,"month")):this.rightCalendar.month.subtract(1,"month"),this.updateCalendars()},clickNext:function(a){var c=b(a.target).parents(".calendar");c.hasClass("left")?this.leftCalendar.month.add(1,"month"):(this.rightCalendar.month.add(1,"month"),this.linkedCalendars&&this.leftCalendar.month.add(1,"month")),this.updateCalendars()},hoverDate:function(a){if(b(a.target).hasClass("available")){var c=b(a.target).attr("data-title"),d=c.substr(1,1),e=c.substr(3,1),f=b(a.target).parents(".calendar"),g=f.hasClass("left")?this.leftCalendar.calendar[d][e]:this.rightCalendar.calendar[d][e];this.endDate&&!this.container.find("input[name=daterangepicker_start]").is(":focus")?this.container.find("input[name=daterangepicker_start]").val(g.format(this.locale.format)):this.endDate||this.container.find("input[name=daterangepicker_end]").is(":focus")||this.container.find("input[name=daterangepicker_end]").val(g.format(this.locale.format));var h=this.leftCalendar,i=this.rightCalendar,j=this.startDate;this.endDate||this.container.find(".calendar td").each(function(a,c){if(!b(c).hasClass("week")){var d=b(c).attr("data-title"),e=d.substr(1,1),f=d.substr(3,1),k=b(c).parents(".calendar"),l=k.hasClass("left")?h.calendar[e][f]:i.calendar[e][f];l.isAfter(j)&&l.isBefore(g)||l.isSame(g,"day")?b(c).addClass("in-range"):b(c).removeClass("in-range")}})}},clickDate:function(a){if(b(a.target).hasClass("available")){var c=b(a.target).attr("data-title"),d=c.substr(1,1),e=c.substr(3,1),f=b(a.target).parents(".calendar"),g=f.hasClass("left")?this.leftCalendar.calendar[d][e]:this.rightCalendar.calendar[d][e];if(this.endDate||g.isBefore(this.startDate,"day")){if(this.timePicker){var h=parseInt(this.container.find(".left .hourselect").val(),10);if(!this.timePicker24Hour){var i=this.container.find(".left .ampmselect").val();"PM"===i&&12>h&&(h+=12),"AM"===i&&12===h&&(h=0)}var j=parseInt(this.container.find(".left .minuteselect").val(),10),k=this.timePickerSeconds?parseInt(this.container.find(".left .secondselect").val(),10):0;g=g.clone().hour(h).minute(j).second(k)}this.endDate=null,this.setStartDate(g.clone())}else if(!this.endDate&&g.isBefore(this.startDate))this.setEndDate(this.startDate.clone());else{if(this.timePicker){var h=parseInt(this.container.find(".right .hourselect").val(),10);if(!this.timePicker24Hour){var i=this.container.find(".right .ampmselect").val();"PM"===i&&12>h&&(h+=12),"AM"===i&&12===h&&(h=0)}var j=parseInt(this.container.find(".right .minuteselect").val(),10),k=this.timePickerSeconds?parseInt(this.container.find(".right .secondselect").val(),10):0;g=g.clone().hour(h).minute(j).second(k)}this.setEndDate(g.clone()),this.autoApply&&(this.calculateChosenLabel(),this.clickApply())}this.singleDatePicker&&(this.setEndDate(this.startDate),this.timePicker||this.clickApply()),this.updateView(),a.stopPropagation()}},calculateChosenLabel:function(){var a=!0,b=0;for(var c in this.ranges){if(this.timePicker){if(this.startDate.isSame(this.ranges[c][0])&&this.endDate.isSame(this.ranges[c][1])){a=!1,this.chosenLabel=this.container.find(".ranges li:eq("+b+")").addClass("active").html();break}}else if(this.startDate.format("YYYY-MM-DD")==this.ranges[c][0].format("YYYY-MM-DD")&&this.endDate.format("YYYY-MM-DD")==this.ranges[c][1].format("YYYY-MM-DD")){a=!1,this.chosenLabel=this.container.find(".ranges li:eq("+b+")").addClass("active").html();break}b++}a&&this.showCustomRangeLabel&&(this.chosenLabel=this.container.find(".ranges li:last").addClass("active").html(),this.showCalendars())},clickApply:function(){this.hide(),this.element.trigger("apply.daterangepicker",this)},clickCancel:function(){this.startDate=this.oldStartDate,this.endDate=this.oldEndDate,this.hide(),this.element.trigger("cancel.daterangepicker",this)},monthOrYearChanged:function(a){var c=b(a.target).closest(".calendar").hasClass("left"),d=c?"left":"right",e=this.container.find(".calendar."+d),f=parseInt(e.find(".monthselect").val(),10),g=e.find(".yearselect").val();c||(gthis.maxDate.year()||g==this.maxDate.year()&&f>this.maxDate.month())&&(f=this.maxDate.month(),g=this.maxDate.year()),c?(this.leftCalendar.month.month(f).year(g),this.linkedCalendars&&(this.rightCalendar.month=this.leftCalendar.month.clone().add(1,"month"))):(this.rightCalendar.month.month(f).year(g),this.linkedCalendars&&(this.leftCalendar.month=this.rightCalendar.month.clone().subtract(1,"month"))),this.updateCalendars()},timeChanged:function(a){var c=b(a.target).closest(".calendar"),d=c.hasClass("left"),e=parseInt(c.find(".hourselect").val(),10),f=parseInt(c.find(".minuteselect").val(),10),g=this.timePickerSeconds?parseInt(c.find(".secondselect").val(),10):0;if(!this.timePicker24Hour){var h=c.find(".ampmselect").val();"PM"===h&&12>e&&(e+=12),"AM"===h&&12===e&&(e=0)}if(d){var i=this.startDate.clone();i.hour(e),i.minute(f),i.second(g),this.setStartDate(i),this.singleDatePicker?this.endDate=this.startDate.clone():this.endDate&&this.endDate.format("YYYY-MM-DD")==i.format("YYYY-MM-DD")&&this.endDate.isBefore(i)&&this.setEndDate(i.clone())}else if(this.endDate){var j=this.endDate.clone();j.hour(e),j.minute(f),j.second(g),this.setEndDate(j)}this.updateCalendars(),this.updateFormInputs(),this.renderTimePicker("left"),this.renderTimePicker("right")},formInputsChanged:function(c){var d=b(c.target).closest(".calendar").hasClass("right"),e=a(this.container.find('input[name="daterangepicker_start"]').val(),this.locale.format),f=a(this.container.find('input[name="daterangepicker_end"]').val(),this.locale.format);e.isValid()&&f.isValid()&&(d&&f.isBefore(e)&&(e=f.clone()),this.setStartDate(e),this.setEndDate(f),d?this.container.find('input[name="daterangepicker_start"]').val(this.startDate.format(this.locale.format)):this.container.find('input[name="daterangepicker_end"]').val(this.endDate.format(this.locale.format))),this.updateView()},formInputsFocused:function(a){this.container.find('input[name="daterangepicker_start"], input[name="daterangepicker_end"]').removeClass("active"),b(a.target).addClass("active");var c=b(a.target).closest(".calendar").hasClass("right");c&&(this.endDate=null,this.setStartDate(this.startDate.clone()),this.updateView())},formInputsBlurred:function(){if(!this.endDate){var b=this.container.find('input[name="daterangepicker_end"]').val(),c=a(b,this.locale.format);c.isValid()&&(this.setEndDate(c),this.updateView())}},elementChanged:function(){if(this.element.is("input")&&this.element.val().length&&!(this.element.val().length":">",'"':""","'":"'","`":"`"},c="(?:"+Object.keys(b).join("|")+")",d=new RegExp(c),e=new RegExp(c,"g"),f=null==a?"":""+a;return d.test(f)?f.replace(e,function(a){return b[a]}):f}function d(b,c){var d=arguments,e=b,f=c;[].shift.apply(d);var h,i=this.each(function(){var b=a(this);if(b.is("select")){var c=b.data("selectpicker"),i="object"==typeof e&&e;if(c){if(i)for(var j in i)i.hasOwnProperty(j)&&(c.options[j]=i[j])}else{var k=a.extend({},g.DEFAULTS,a.fn.selectpicker.defaults||{},b.data(),i);k.template=a.extend({},g.DEFAULTS.template,a.fn.selectpicker.defaults?a.fn.selectpicker.defaults.template:{},b.data().template,i.template),b.data("selectpicker",c=new g(this,k,f))}"string"==typeof e&&(h=c[e]instanceof Function?c[e].apply(c,d):c.options[e])}});return"undefined"!=typeof h?h:i}String.prototype.includes||!function(){var a={}.toString,b=function(){try{var a={},b=Object.defineProperty,c=b(a,a,a)&&b; + +}catch(d){}return c}(),c="".indexOf,d=function(b){if(null==this)throw new TypeError;var d=String(this);if(b&&"[object RegExp]"==a.call(b))throw new TypeError;var e=d.length,f=String(b),g=f.length,h=arguments.length>1?arguments[1]:void 0,i=h?Number(h):0;i!=i&&(i=0);var j=Math.min(Math.max(i,0),e);return g+j>e?!1:-1!=c.call(d,f,i)};b?b(String.prototype,"includes",{value:d,configurable:!0,writable:!0}):String.prototype.includes=d}(),String.prototype.startsWith||!function(){var a=function(){try{var a={},b=Object.defineProperty,c=b(a,a,a)&&b}catch(d){}return c}(),b={}.toString,c=function(a){if(null==this)throw new TypeError;var c=String(this);if(a&&"[object RegExp]"==b.call(a))throw new TypeError;var d=c.length,e=String(a),f=e.length,g=arguments.length>1?arguments[1]:void 0,h=g?Number(g):0;h!=h&&(h=0);var i=Math.min(Math.max(h,0),d);if(f+i>d)return!1;for(var j=-1;++j'},maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1},g.prototype={constructor:g,init:function(){var b=this,c=this.$element.attr("id");this.$element.addClass("bs-select-hidden"),this.liObj={},this.multiple=this.$element.prop("multiple"),this.autofocus=this.$element.prop("autofocus"),this.$newElement=this.createView(),this.$element.after(this.$newElement).appendTo(this.$newElement),this.$button=this.$newElement.children("button"),this.$menu=this.$newElement.children(".dropdown-menu"),this.$menuInner=this.$menu.children(".inner"),this.$searchbox=this.$menu.find("input"),this.$element.removeClass("bs-select-hidden"),this.options.dropdownAlignRight===!0&&this.$menu.addClass("dropdown-menu-right"),"undefined"!=typeof c&&(this.$button.attr("data-id",c),a('label[for="'+c+'"]').click(function(a){a.preventDefault(),b.$button.focus()})),this.checkDisabled(),this.clickListener(),this.options.liveSearch&&this.liveSearchListener(),this.render(),this.setStyle(),this.setWidth(),this.options.container&&this.selectPosition(),this.$menu.data("this",this),this.$newElement.data("this",this),this.options.mobile&&this.mobile(),this.$newElement.on({"hide.bs.dropdown":function(a){b.$menuInner.attr("aria-expanded",!1),b.$element.trigger("hide.bs.select",a)},"hidden.bs.dropdown":function(a){b.$element.trigger("hidden.bs.select",a)},"show.bs.dropdown":function(a){b.$menuInner.attr("aria-expanded",!0),b.$element.trigger("show.bs.select",a)},"shown.bs.dropdown":function(a){b.$element.trigger("shown.bs.select",a)}}),b.$element[0].hasAttribute("required")&&this.$element.on("invalid",function(){b.$button.addClass("bs-invalid").focus(),b.$element.on({"focus.bs.select":function(){b.$button.focus(),b.$element.off("focus.bs.select")},"shown.bs.select":function(){b.$element.val(b.$element.val()).off("shown.bs.select")},"rendered.bs.select":function(){this.validity.valid&&b.$button.removeClass("bs-invalid"),b.$element.off("rendered.bs.select")}})}),setTimeout(function(){b.$element.trigger("loaded.bs.select")})},createDropdown:function(){var b=this.multiple||this.options.showTick?" show-tick":"",d=this.$element.parent().hasClass("input-group")?" input-group-btn":"",e=this.autofocus?" autofocus":"",f=this.options.header?'
'+this.options.header+"
":"",g=this.options.liveSearch?'':"",h=this.multiple&&this.options.actionsBox?'
":"",i=this.multiple&&this.options.doneButton?'
":"",j='
";return a(j)},createView:function(){var a=this.createDropdown(),b=this.createLi();return a.find("ul")[0].innerHTML=b,a},reloadLi:function(){this.destroyLi();var a=this.createLi();this.$menuInner[0].innerHTML=a},destroyLi:function(){this.$menu.find("li").remove()},createLi:function(){var d=this,e=[],f=0,g=document.createElement("option"),h=-1,i=function(a,b,c,d){return""+a+""},j=function(a,e,f,g){return'
'+a+''};if(this.options.title&&!this.multiple&&(h--,!this.$element.find(".bs-title-option").length)){var k=this.$element[0];g.className="bs-title-option",g.appendChild(document.createTextNode(this.options.title)),g.value="",k.insertBefore(g,k.firstChild);var l=a(k.options[k.selectedIndex]);void 0===l.attr("selected")&&void 0===this.$element.data("selected")&&(g.selected=!0)}return this.$element.find("option").each(function(b){var c=a(this);if(h++,!c.hasClass("bs-title-option")){var g=this.className||"",k=this.style.cssText,l=c.data("content")?c.data("content"):c.html(),m=c.data("tokens")?c.data("tokens"):null,n="undefined"!=typeof c.data("subtext")?''+c.data("subtext")+"":"",o="undefined"!=typeof c.data("icon")?' ':"",p=c.parent(),q="OPTGROUP"===p[0].tagName,r=q&&p[0].disabled,s=this.disabled||r;if(""!==o&&s&&(o=""+o+""),d.options.hideDisabled&&(s&&!q||r))return void h--;if(c.data("content")||(l=o+''+l+n+""),q&&c.data("divider")!==!0){if(d.options.hideDisabled&&s){if(void 0===p.data("allOptionsDisabled")){var t=p.children();p.data("allOptionsDisabled",t.filter(":disabled").length===t.length)}if(p.data("allOptionsDisabled"))return void h--}var u=" "+p[0].className||"";if(0===c.index()){f+=1;var v=p[0].label,w="undefined"!=typeof p.data("subtext")?''+p.data("subtext")+"":"",x=p.data("icon")?' ':"";v=x+''+v+w+"",0!==b&&e.length>0&&(h++,e.push(i("",null,"divider",f+"div"))),h++,e.push(i(v,null,"dropdown-header"+u,f))}if(d.options.hideDisabled&&s)return void h--;e.push(i(j(l,"opt "+g+u,k,m),b,"",f))}else if(c.data("divider")===!0)e.push(i("",b,"divider"));else if(c.data("hidden")===!0)e.push(i(j(l,g,k,m),b,"hidden is-hidden"));else{var y=this.previousElementSibling&&"OPTGROUP"===this.previousElementSibling.tagName;if(!y&&d.options.hideDisabled)for(var z=a(this).prevAll(),A=0;AC;C++){var D=z[C];(D.disabled||a(D).data("hidden")===!0)&&B++}B===A&&(y=!0);break}y&&(h++,e.push(i("",null,"divider",f+"div"))),e.push(i(j(l,g,k,m),b))}d.liObj[b]=h}}),this.multiple||0!==this.$element.find("option:selected").length||this.options.title||this.$element.find("option").eq(0).prop("selected",!0).attr("selected","selected"),e.join("")},findLis:function(){return null==this.$lis&&(this.$lis=this.$menu.find("li")),this.$lis},render:function(b){var c,d=this;b!==!1&&this.$element.find("option").each(function(a){var b=d.findLis().eq(d.liObj[a]);d.setDisabled(a,this.disabled||"OPTGROUP"===this.parentNode.tagName&&this.parentNode.disabled,b),d.setSelected(a,this.selected,b)}),this.togglePlaceholder(),this.tabIndex();var e=this.$element.find("option").map(function(){if(this.selected){if(d.options.hideDisabled&&(this.disabled||"OPTGROUP"===this.parentNode.tagName&&this.parentNode.disabled))return;var b,c=a(this),e=c.data("icon")&&d.options.showIcon?' ':"";return b=d.options.showSubtext&&c.data("subtext")&&!d.multiple?' '+c.data("subtext")+"":"","undefined"!=typeof c.attr("title")?c.attr("title"):c.data("content")&&d.options.showContent?c.data("content"):e+c.html()+b}}).toArray(),f=this.multiple?e.join(this.options.multipleSeparator):e[0];if(this.multiple&&this.options.selectedTextFormat.indexOf("count")>-1){var g=this.options.selectedTextFormat.split(">");if(g.length>1&&e.length>g[1]||1==g.length&&e.length>=2){c=this.options.hideDisabled?", [disabled]":"";var h=this.$element.find("option").not('[data-divider="true"], [data-hidden="true"]'+c).length,i="function"==typeof this.options.countSelectedText?this.options.countSelectedText(e.length,h):this.options.countSelectedText;f=i.replace("{0}",e.length.toString()).replace("{1}",h.toString())}}void 0==this.options.title&&(this.options.title=this.$element.attr("title")),"static"==this.options.selectedTextFormat&&(f=this.options.title),f||(f="undefined"!=typeof this.options.title?this.options.title:this.options.noneSelectedText),this.$button.attr("title",a.trim(f.replace(/<[^>]*>?/g,""))),this.$button.children(".filter-option").html(f),this.$element.trigger("rendered.bs.select")},setStyle:function(a,b){this.$element.attr("class")&&this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi,""));var c=a?a:this.options.style;"add"==b?this.$button.addClass(c):"remove"==b?this.$button.removeClass(c):(this.$button.removeClass(this.options.style),this.$button.addClass(c))},liHeight:function(b){if(b||this.options.size!==!1&&!this.sizeInfo){var c=document.createElement("div"),d=document.createElement("div"),e=document.createElement("ul"),f=document.createElement("li"),g=document.createElement("li"),h=document.createElement("a"),i=document.createElement("span"),j=this.options.header&&this.$menu.find(".popover-title").length>0?this.$menu.find(".popover-title")[0].cloneNode(!0):null,k=this.options.liveSearch?document.createElement("div"):null,l=this.options.actionsBox&&this.multiple&&this.$menu.find(".bs-actionsbox").length>0?this.$menu.find(".bs-actionsbox")[0].cloneNode(!0):null,m=this.options.doneButton&&this.multiple&&this.$menu.find(".bs-donebutton").length>0?this.$menu.find(".bs-donebutton")[0].cloneNode(!0):null;if(i.className="text",c.className=this.$menu[0].parentNode.className+" open",d.className="dropdown-menu open",e.className="dropdown-menu inner",f.className="divider",i.appendChild(document.createTextNode("Inner text")),h.appendChild(i),g.appendChild(h),e.appendChild(g),e.appendChild(f),j&&d.appendChild(j),k){var n=document.createElement("span");k.className="bs-searchbox",n.className="form-control",k.appendChild(n),d.appendChild(k)}l&&d.appendChild(l),d.appendChild(e),m&&d.appendChild(m),c.appendChild(d),document.body.appendChild(c);var o=h.offsetHeight,p=j?j.offsetHeight:0,q=k?k.offsetHeight:0,r=l?l.offsetHeight:0,s=m?m.offsetHeight:0,t=a(f).outerHeight(!0),u="function"==typeof getComputedStyle?getComputedStyle(d):!1,v=u?null:a(d),w={vert:parseInt(u?u.paddingTop:v.css("paddingTop"))+parseInt(u?u.paddingBottom:v.css("paddingBottom"))+parseInt(u?u.borderTopWidth:v.css("borderTopWidth"))+parseInt(u?u.borderBottomWidth:v.css("borderBottomWidth")),horiz:parseInt(u?u.paddingLeft:v.css("paddingLeft"))+parseInt(u?u.paddingRight:v.css("paddingRight"))+parseInt(u?u.borderLeftWidth:v.css("borderLeftWidth"))+parseInt(u?u.borderRightWidth:v.css("borderRightWidth"))},x={vert:w.vert+parseInt(u?u.marginTop:v.css("marginTop"))+parseInt(u?u.marginBottom:v.css("marginBottom"))+2,horiz:w.horiz+parseInt(u?u.marginLeft:v.css("marginLeft"))+parseInt(u?u.marginRight:v.css("marginRight"))+2};document.body.removeChild(c),this.sizeInfo={liHeight:o,headerHeight:p,searchHeight:q,actionsHeight:r,doneButtonHeight:s,dividerHeight:t,menuPadding:w,menuExtras:x}}},setSize:function(){if(this.findLis(),this.liHeight(),this.options.header&&this.$menu.css("padding-top",0),this.options.size!==!1){var b,c,d,e,f,g,h,i,j=this,k=this.$menu,l=this.$menuInner,m=a(window),n=this.$newElement[0].offsetHeight,o=this.$newElement[0].offsetWidth,p=this.sizeInfo.liHeight,q=this.sizeInfo.headerHeight,r=this.sizeInfo.searchHeight,s=this.sizeInfo.actionsHeight,t=this.sizeInfo.doneButtonHeight,u=this.sizeInfo.dividerHeight,v=this.sizeInfo.menuPadding,w=this.sizeInfo.menuExtras,x=this.options.hideDisabled?".disabled":"",y=function(){var b,c=j.$newElement.offset(),d=a(j.options.container);j.options.container&&!d.is("body")?(b=d.offset(),b.top+=parseInt(d.css("borderTopWidth")),b.left+=parseInt(d.css("borderLeftWidth"))):b={top:0,left:0},f=c.top-b.top-m.scrollTop(),g=m.height()-f-n-b.top,h=c.left-b.left-m.scrollLeft(),i=m.width()-h-o-b.left};if(y(),"auto"===this.options.size){var z=function(){var m,n=function(b,c){return function(d){return c?d.classList?d.classList.contains(b):a(d).hasClass(b):!(d.classList?d.classList.contains(b):a(d).hasClass(b))}},u=j.$menuInner[0].getElementsByTagName("li"),x=Array.prototype.filter?Array.prototype.filter.call(u,n("hidden",!1)):j.$lis.not(".hidden"),z=Array.prototype.filter?Array.prototype.filter.call(x,n("dropdown-header",!0)):x.filter(".dropdown-header");y(),b=g-w.vert,c=i-w.horiz,j.options.container?(k.data("height")||k.data("height",k.height()),d=k.data("height"),k.data("width")||k.data("width",k.width()),e=k.data("width")):(d=k.height(),e=k.width()),j.options.dropupAuto&&j.$newElement.toggleClass("dropup",f>g&&b-w.verti&&c-w.horiz3?3*p+w.vert-2:0,k.css({"max-height":b+"px",overflow:"hidden","min-height":m+q+r+s+t+"px"}),l.css({"max-height":b-q-r-s-t-v.vert+"px","overflow-y":"auto","min-height":Math.max(m-v.vert,0)+"px"})};z(),this.$searchbox.off("input.getSize propertychange.getSize").on("input.getSize propertychange.getSize",z),m.off("resize.getSize scroll.getSize").on("resize.getSize scroll.getSize",z)}else if(this.options.size&&"auto"!=this.options.size&&this.$lis.not(x).length>this.options.size){var A=this.$lis.not(".divider").not(x).children().slice(0,this.options.size).last().parent().index(),B=this.$lis.slice(0,A+1).filter(".divider").length;b=p*this.options.size+B*u+v.vert,j.options.container?(k.data("height")||k.data("height",k.height()),d=k.data("height")):d=k.height(),j.options.dropupAuto&&this.$newElement.toggleClass("dropup",f>g&&b-w.vert');var b,c,d,e=this,f=a(this.options.container),g=function(a){e.$bsContainer.addClass(a.attr("class").replace(/form-control|fit-width/gi,"")).toggleClass("dropup",a.hasClass("dropup")),b=a.offset(),f.is("body")?c={top:0,left:0}:(c=f.offset(),c.top+=parseInt(f.css("borderTopWidth"))-f.scrollTop(),c.left+=parseInt(f.css("borderLeftWidth"))-f.scrollLeft()),d=a.hasClass("dropup")?0:a[0].offsetHeight,e.$bsContainer.css({top:b.top-c.top+d,left:b.left-c.left,width:a[0].offsetWidth})};this.$button.on("click",function(){var b=a(this);e.isDisabled()||(g(e.$newElement),e.$bsContainer.appendTo(e.options.container).toggleClass("open",!b.hasClass("open")).append(e.$menu))}),a(window).on("resize scroll",function(){g(e.$newElement)}),this.$element.on("hide.bs.select",function(){e.$menu.data("height",e.$menu.height()),e.$bsContainer.detach()})},setSelected:function(a,b,c){c||(this.togglePlaceholder(),c=this.findLis().eq(this.liObj[a])),c.toggleClass("selected",b).find("a").attr("aria-selected",b)},setDisabled:function(a,b,c){c||(c=this.findLis().eq(this.liObj[a])),b?c.addClass("disabled").children("a").attr("href","#").attr("tabindex",-1).attr("aria-disabled",!0):c.removeClass("disabled").children("a").removeAttr("href").attr("tabindex",0).attr("aria-disabled",!1)},isDisabled:function(){return this.$element[0].disabled},checkDisabled:function(){var a=this;this.isDisabled()?(this.$newElement.addClass("disabled"),this.$button.addClass("disabled").attr("tabindex",-1)):(this.$button.hasClass("disabled")&&(this.$newElement.removeClass("disabled"),this.$button.removeClass("disabled")),-1!=this.$button.attr("tabindex")||this.$element.data("tabindex")||this.$button.removeAttr("tabindex")),this.$button.click(function(){return!a.isDisabled()})},togglePlaceholder:function(){var a=this.$element.val();this.$button.toggleClass("bs-placeholder",null===a||""===a)},tabIndex:function(){this.$element.data("tabindex")!==this.$element.attr("tabindex")&&-98!==this.$element.attr("tabindex")&&"-98"!==this.$element.attr("tabindex")&&(this.$element.data("tabindex",this.$element.attr("tabindex")),this.$button.attr("tabindex",this.$element.data("tabindex"))),this.$element.attr("tabindex",-98)},clickListener:function(){var b=this,c=a(document);this.$newElement.on("touchstart.dropdown",".dropdown-menu",function(a){a.stopPropagation()}),c.data("spaceSelect",!1),this.$button.on("keyup",function(a){/(32)/.test(a.keyCode.toString(10))&&c.data("spaceSelect")&&(a.preventDefault(),c.data("spaceSelect",!1))}),this.$button.on("click",function(){b.setSize()}),this.$element.on("shown.bs.select",function(){if(b.options.liveSearch||b.multiple){if(!b.multiple){var a=b.liObj[b.$element[0].selectedIndex];if("number"!=typeof a||b.options.size===!1)return;var c=b.$lis.eq(a)[0].offsetTop-b.$menuInner[0].offsetTop;c=c-b.$menuInner[0].offsetHeight/2+b.sizeInfo.liHeight/2,b.$menuInner[0].scrollTop=c}}else b.$menuInner.find(".selected a").focus()}),this.$menuInner.on("click","li a",function(c){var d=a(this),e=d.parent().data("originalIndex"),g=b.$element.val(),h=b.$element.prop("selectedIndex"),i=!0;if(b.multiple&&1!==b.options.maxOptions&&c.stopPropagation(),c.preventDefault(),!b.isDisabled()&&!d.parent().hasClass("disabled")){var j=b.$element.find("option"),k=j.eq(e),l=k.prop("selected"),m=k.parent("optgroup"),n=b.options.maxOptions,o=m.data("maxOptions")||!1;if(b.multiple){if(k.prop("selected",!l),b.setSelected(e,!l),d.blur(),n!==!1||o!==!1){var p=n
');t[2]&&(u=u.replace("{var}",t[2][n>1?0:1]),v=v.replace("{var}",t[2][o>1?0:1])),k.prop("selected",!1),b.$menu.append(w),n&&p&&(w.append(a("
"+u+"
")),i=!1,b.$element.trigger("maxReached.bs.select")),o&&q&&(w.append(a("
"+v+"
")),i=!1,b.$element.trigger("maxReachedGrp.bs.select")),setTimeout(function(){b.setSelected(e,!1)},10),w.delay(750).fadeOut(300,function(){a(this).remove()})}}}else j.prop("selected",!1),k.prop("selected",!0),b.$menuInner.find(".selected").removeClass("selected").find("a").attr("aria-selected",!1),b.setSelected(e,!0);!b.multiple||b.multiple&&1===b.options.maxOptions?b.$button.focus():b.options.liveSearch&&b.$searchbox.focus(),i&&(g!=b.$element.val()&&b.multiple||h!=b.$element.prop("selectedIndex")&&!b.multiple)&&(f=[e,k.prop("selected"),l],b.$element.triggerNative("change"))}}),this.$menu.on("click","li.disabled a, .popover-title, .popover-title :not(.close)",function(c){c.currentTarget==this&&(c.preventDefault(),c.stopPropagation(),b.options.liveSearch&&!a(c.target).hasClass("close")?b.$searchbox.focus():b.$button.focus())}),this.$menuInner.on("click",".divider, .dropdown-header",function(a){a.preventDefault(),a.stopPropagation(),b.options.liveSearch?b.$searchbox.focus():b.$button.focus()}),this.$menu.on("click",".popover-title .close",function(){b.$button.click()}),this.$searchbox.on("click",function(a){a.stopPropagation()}),this.$menu.on("click",".actions-btn",function(c){b.options.liveSearch?b.$searchbox.focus():b.$button.focus(),c.preventDefault(),c.stopPropagation(),a(this).hasClass("bs-select-all")?b.selectAll():b.deselectAll()}),this.$element.change(function(){b.render(!1),b.$element.trigger("changed.bs.select",f),f=null})},liveSearchListener:function(){var d=this,e=a('
  • ');this.$button.on("click.dropdown.data-api touchstart.dropdown.data-api",function(){d.$menuInner.find(".active").removeClass("active"),d.$searchbox.val()&&(d.$searchbox.val(""),d.$lis.not(".is-hidden").removeClass("hidden"),e.parent().length&&e.remove()),d.multiple||d.$menuInner.find(".selected").addClass("active"),setTimeout(function(){d.$searchbox.focus()},10)}),this.$searchbox.on("click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api",function(a){a.stopPropagation()}),this.$searchbox.on("input propertychange",function(){if(d.$searchbox.val()){var f=d.$lis.not(".is-hidden").removeClass("hidden").children("a");f=f.not(d.options.liveSearchNormalize?":a"+d._searchStyle()+'("'+b(d.$searchbox.val())+'")':":"+d._searchStyle()+'("'+d.$searchbox.val()+'")'),f.parent().addClass("hidden"),d.$lis.filter(".dropdown-header").each(function(){var b=a(this),c=b.data("optgroup");0===d.$lis.filter("[data-optgroup="+c+"]").not(b).not(".hidden").length&&(b.addClass("hidden"),d.$lis.filter("[data-optgroup="+c+"div]").addClass("hidden"))});var g=d.$lis.not(".hidden");g.each(function(b){var c=a(this);c.hasClass("divider")&&(c.index()===g.first().index()||c.index()===g.last().index()||g.eq(b+1).hasClass("divider"))&&c.addClass("hidden")}),d.$lis.not(".hidden, .no-results").length?e.parent().length&&e.remove():(e.parent().length&&e.remove(),e.html(d.options.noneResultsText.replace("{0}",'"'+c(d.$searchbox.val())+'"')).show(),d.$menuInner.append(e))}else d.$lis.not(".is-hidden").removeClass("hidden"),e.parent().length&&e.remove();d.$lis.filter(".active").removeClass("active"),d.$searchbox.val()&&d.$lis.not(".hidden, .divider, .dropdown-header").eq(0).addClass("active").children("a").focus(),a(this).focus()})},_searchStyle:function(){var a={begins:"ibegins",startsWith:"ibegins"};return a[this.options.liveSearchStyle]||"icontains"},val:function(a){return"undefined"!=typeof a?(this.$element.val(a),this.render(),this.$element):this.$element.val()},changeAll:function(b){if(this.multiple){"undefined"==typeof b&&(b=!0),this.findLis();var c=this.$element.find("option"),d=this.$lis.not(".divider, .dropdown-header, .disabled, .hidden"),e=d.length,f=[];if(b){if(d.filter(".selected").length===d.length)return}else if(0===d.filter(".selected").length)return;d.toggleClass("selected",b);for(var g=0;e>g;g++){var h=d[g].getAttribute("data-original-index");f[f.length]=c.eq(h)[0]}a(f).prop("selected",b),this.render(!1),this.togglePlaceholder(),this.$element.triggerNative("change")}},selectAll:function(){return this.changeAll(!0)},deselectAll:function(){return this.changeAll(!1)},toggle:function(a){a=a||window.event,a&&a.stopPropagation(),this.$button.trigger("click")},keydown:function(c){var d,e,f,g,h,i,j,k,l,m=a(this),n=m.is("input")?m.parent().parent():m.parent(),o=n.data("this"),p=":not(.disabled, .hidden, .dropdown-header, .divider)",q={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"};if(o.options.liveSearch&&(n=m.parent().parent()),o.options.container&&(n=o.$menu),d=a('[role="listbox"] li',n),l=o.$newElement.hasClass("open"),!l&&(c.keyCode>=48&&c.keyCode<=57||c.keyCode>=96&&c.keyCode<=105||c.keyCode>=65&&c.keyCode<=90))return o.options.container?o.$button.trigger("click"):(o.setSize(),o.$menu.parent().addClass("open"),l=!0),void o.$searchbox.focus();if(o.options.liveSearch&&(/(^9$|27)/.test(c.keyCode.toString(10))&&l&&(c.preventDefault(),c.stopPropagation(),o.$button.click().focus()),d=a('[role="listbox"] li'+p,n),m.val()||/(38|40)/.test(c.keyCode.toString(10))||0===d.filter(".active").length&&(d=o.$menuInner.find("li"),d=d.filter(o.options.liveSearchNormalize?":a"+o._searchStyle()+"("+b(q[c.keyCode])+")":":"+o._searchStyle()+"("+q[c.keyCode]+")"))),d.length){if(/(38|40)/.test(c.keyCode.toString(10)))e=d.index(d.find("a").filter(":focus").parent()),g=d.filter(p).first().index(),h=d.filter(p).last().index(),f=d.eq(e).nextAll(p).eq(0).index(),i=d.eq(e).prevAll(p).eq(0).index(),j=d.eq(f).prevAll(p).eq(0).index(),o.options.liveSearch&&(d.each(function(b){a(this).hasClass("disabled")||a(this).data("index",b)}),e=d.index(d.filter(".active")),g=d.first().data("index"),h=d.last().data("index"),f=d.eq(e).nextAll().eq(0).data("index"),i=d.eq(e).prevAll().eq(0).data("index"),j=d.eq(f).prevAll().eq(0).data("index")),k=m.data("prevIndex"),38==c.keyCode?(o.options.liveSearch&&e--,e!=j&&e>i&&(e=i),g>e&&(e=g),e==k&&(e=h)):40==c.keyCode&&(o.options.liveSearch&&e++,-1==e&&(e=0),e!=j&&f>e&&(e=f),e>h&&(e=h),e==k&&(e=g)),m.data("prevIndex",e),o.options.liveSearch?(c.preventDefault(),m.hasClass("dropdown-toggle")||(d.removeClass("active").eq(e).addClass("active").children("a").focus(),m.focus())):d.eq(e).children("a").focus();else if(!m.is("input")){var r,s,t=[];d.each(function(){a(this).hasClass("disabled")||a.trim(a(this).children("a").text().toLowerCase()).substring(0,1)==q[c.keyCode]&&t.push(a(this).index())}),r=a(document).data("keycount"),r++,a(document).data("keycount",r),s=a.trim(a(":focus").text().toLowerCase()).substring(0,1),s!=q[c.keyCode]?(r=1,a(document).data("keycount",r)):r>=t.length&&(a(document).data("keycount",0),r>t.length&&(r=1)),d.eq(t[r-1]).children("a").focus()}if((/(13|32)/.test(c.keyCode.toString(10))||/(^9$)/.test(c.keyCode.toString(10))&&o.options.selectOnTab)&&l){if(/(32)/.test(c.keyCode.toString(10))||c.preventDefault(),o.options.liveSearch)/(32)/.test(c.keyCode.toString(10))||(o.$menuInner.find(".active a").click(),m.focus());else{var u=a(":focus");u.click(),u.focus(),c.preventDefault(),a(document).data("spaceSelect",!0)}a(document).data("keycount",0)}(/(^9$|27)/.test(c.keyCode.toString(10))&&l&&(o.multiple||o.options.liveSearch)||/(27)/.test(c.keyCode.toString(10))&&!l)&&(o.$menu.parent().removeClass("open"),o.options.container&&o.$newElement.removeClass("open"),o.$button.focus())}},mobile:function(){this.$element.addClass("mobile-device")},refresh:function(){this.$lis=null,this.liObj={},this.reloadLi(),this.render(),this.checkDisabled(),this.liHeight(!0),this.setStyle(),this.setWidth(),this.$lis&&this.$searchbox.trigger("propertychange"),this.$element.trigger("refreshed.bs.select")},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.$element.off(".bs.select").removeData("selectpicker").removeClass("bs-select-hidden selectpicker")}};var h=a.fn.selectpicker;a.fn.selectpicker=d,a.fn.selectpicker.Constructor=g,a.fn.selectpicker.noConflict=function(){return a.fn.selectpicker=h,this},a(document).data("keycount",0).on("keydown.bs.select",'.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input',g.prototype.keydown).on("focusin.modal",'.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input',function(a){ +a.stopPropagation()}),a(window).on("load.bs.select.data-api",function(){a(".selectpicker").each(function(){var b=a(this);d.call(b,b.data())})})}(a)}),function(a){"use strict";var b=null,c=function(a){var b=arguments,c=!0,d=1;return a=a.replace(/%s/g,function(){var a=b[d++];return"undefined"==typeof a?(c=!1,""):a}),c?a:""},d=function(b,c,d,e){var f="";return a.each(b,function(a,b){return b[c]===e?(f=b[d],!1):!0}),f},e=function(b,c){var d=-1;return a.each(b,function(a,b){return b.field===c?(d=a,!1):!0}),d},f=function(b){var c,d,e,f=0,g=[];for(c=0;cd;d++)g[c][d]=!1;for(c=0;ce;e++)g[c+e][k]=!0;for(e=0;j>e;e++)g[c][k+e]=!0}},g=function(){if(null===b){var c,d,e=a("

    ").addClass("fixed-table-scroll-inner"),f=a("

    ").addClass("fixed-table-scroll-outer");f.append(e),a("body").append(f),c=e[0].offsetWidth,f.css("overflow","scroll"),d=e[0].offsetWidth,c===d&&(d=f[0].clientWidth),f.remove(),b=c-d}return b},h=function(b,d,e,f){var g=d;if("string"==typeof d){var h=d.split(".");h.length>1?(g=window,a.each(h,function(a,b){g=g[b]})):g=window[d]}return"object"==typeof g?g:"function"==typeof g?g.apply(b,e):!g&&"string"==typeof d&&c.apply(this,[d].concat(e))?c.apply(this,[d].concat(e)):f},i=function(b,c,d){var e=Object.getOwnPropertyNames(b),f=Object.getOwnPropertyNames(c),g="";if(d&&e.length!==f.length)return!1;for(var h=0;h-1&&b[g]!==c[g])return!1;return!0},j=function(a){return"string"==typeof a?a.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/`/g,"`"):a},k=function(b){var c=0;return b.children().each(function(){c0||navigator.userAgent.match(/Trident.*rv\:11\./))},o=function(){Object.keys||(Object.keys=function(){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;return function(e){if("object"!=typeof e&&("function"!=typeof e||null===e))throw new TypeError("Object.keys called on non-object");var f,g,h=[];for(f in e)a.call(e,f)&&h.push(f);if(b)for(g=0;d>g;g++)a.call(e,c[g])&&h.push(c[g]);return h}}())},p=function(b,c){this.options=c,this.$el=a(b),this.$el_=this.$el.clone(),this.timeoutId_=0,this.timeoutFooter_=0,this.init()};p.DEFAULTS={classes:"table table-hover",sortClass:void 0,locale:void 0,height:void 0,undefinedText:"-",sortName:void 0,sortOrder:"asc",sortStable:!1,striped:!1,columns:[[]],data:[],totalField:"total",dataField:"rows",method:"get",url:void 0,ajax:void 0,cache:!0,contentType:"application/json",dataType:"json",ajaxOptions:{},queryParams:function(a){return a},queryParamsType:"limit",responseHandler:function(a){return a},pagination:!1,onlyInfoPagination:!1,paginationLoop:!0,sidePagination:"client",totalRows:0,pageNumber:1,pageSize:10,pageList:[10,25,50,100],paginationHAlign:"right",paginationVAlign:"bottom",paginationDetailHAlign:"left",paginationPreText:"‹",paginationNextText:"›",search:!1,searchOnEnterKey:!1,strictSearch:!1,searchAlign:"right",selectItemName:"btSelectItem",showHeader:!0,showFooter:!1,showColumns:!1,showPaginationSwitch:!1,showRefresh:!1,showToggle:!1,buttonsAlign:"right",smartDisplay:!0,escape:!1,minimumCountColumns:1,idField:void 0,uniqueId:void 0,cardView:!1,detailView:!1,detailFormatter:function(){return""},trimOnSearch:!0,clickToSelect:!1,singleSelect:!1,toolbar:void 0,toolbarAlign:"left",checkboxHeader:!0,sortable:!0,silentSort:!0,maintainSelected:!1,searchTimeOut:500,searchText:"",iconSize:void 0,buttonsClass:"default",iconsPrefix:"glyphicon",icons:{paginationSwitchDown:"glyphicon-collapse-down icon-chevron-down",paginationSwitchUp:"glyphicon-collapse-up icon-chevron-up",refresh:"glyphicon-refresh icon-refresh",toggle:"glyphicon-list-alt icon-list-alt",columns:"glyphicon-th icon-th",detailOpen:"glyphicon-plus icon-plus",detailClose:"glyphicon-minus icon-minus"},customSearch:a.noop,customSort:a.noop,rowStyle:function(){return{}},rowAttributes:function(){return{}},footerStyle:function(){return{}},onAll:function(){return!1},onClickCell:function(){return!1},onDblClickCell:function(){return!1},onClickRow:function(){return!1},onDblClickRow:function(){return!1},onSort:function(){return!1},onCheck:function(){return!1},onUncheck:function(){return!1},onCheckAll:function(){return!1},onUncheckAll:function(){return!1},onCheckSome:function(){return!1},onUncheckSome:function(){return!1},onLoadSuccess:function(){return!1},onLoadError:function(){return!1},onColumnSwitch:function(){return!1},onPageChange:function(){return!1},onSearch:function(){return!1},onToggle:function(){return!1},onPreBody:function(){return!1},onPostBody:function(){return!1},onPostHeader:function(){return!1},onExpandRow:function(){return!1},onCollapseRow:function(){return!1},onRefreshOptions:function(){return!1},onRefresh:function(){return!1},onResetView:function(){return!1}},p.LOCALES={},p.LOCALES["en-US"]=p.LOCALES.en={formatLoadingMessage:function(){return"Loading, please wait..."},formatRecordsPerPage:function(a){return c("%s rows per page",a)},formatShowingRows:function(a,b,d){return c("Showing %s to %s of %s rows",a,b,d)},formatDetailPagination:function(a){return c("Showing %s rows",a)},formatSearch:function(){return"Search"},formatNoMatches:function(){return"No matching records found"},formatPaginationSwitch:function(){return"Hide/Show pagination"},formatRefresh:function(){return"Refresh"},formatToggle:function(){return"Toggle"},formatColumns:function(){return"Columns"},formatAllRows:function(){return"All"}},a.extend(p.DEFAULTS,p.LOCALES["en-US"]),p.COLUMN_DEFAULTS={radio:!1,checkbox:!1,checkboxEnabled:!0,field:void 0,title:void 0,titleTooltip:void 0,"class":void 0,align:void 0,halign:void 0,falign:void 0,valign:void 0,width:void 0,sortable:!1,order:"asc",visible:!0,switchable:!0,clickToSelect:!0,formatter:void 0,footerFormatter:void 0,events:void 0,sorter:void 0,sortName:void 0,cellStyle:void 0,searchable:!0,searchFormatter:!0,cardVisible:!0},p.EVENTS={"all.bs.table":"onAll","click-cell.bs.table":"onClickCell","dbl-click-cell.bs.table":"onDblClickCell","click-row.bs.table":"onClickRow","dbl-click-row.bs.table":"onDblClickRow","sort.bs.table":"onSort","check.bs.table":"onCheck","uncheck.bs.table":"onUncheck","check-all.bs.table":"onCheckAll","uncheck-all.bs.table":"onUncheckAll","check-some.bs.table":"onCheckSome","uncheck-some.bs.table":"onUncheckSome","load-success.bs.table":"onLoadSuccess","load-error.bs.table":"onLoadError","column-switch.bs.table":"onColumnSwitch","page-change.bs.table":"onPageChange","search.bs.table":"onSearch","toggle.bs.table":"onToggle","pre-body.bs.table":"onPreBody","post-body.bs.table":"onPostBody","post-header.bs.table":"onPostHeader","expand-row.bs.table":"onExpandRow","collapse-row.bs.table":"onCollapseRow","refresh-options.bs.table":"onRefreshOptions","reset-view.bs.table":"onResetView","refresh.bs.table":"onRefresh"},p.prototype.init=function(){this.initLocale(),this.initContainer(),this.initTable(),this.initHeader(),this.initData(),this.initHiddenRows(),this.initFooter(),this.initToolbar(),this.initPagination(),this.initBody(),this.initSearchText(),this.initServer()},p.prototype.initLocale=function(){if(this.options.locale){var b=this.options.locale.split(/-|_/);b[0].toLowerCase(),b[1]&&b[1].toUpperCase(),a.fn.bootstrapTable.locales[this.options.locale]?a.extend(this.options,a.fn.bootstrapTable.locales[this.options.locale]):a.fn.bootstrapTable.locales[b.join("-")]?a.extend(this.options,a.fn.bootstrapTable.locales[b.join("-")]):a.fn.bootstrapTable.locales[b[0]]&&a.extend(this.options,a.fn.bootstrapTable.locales[b[0]])}},p.prototype.initContainer=function(){this.$container=a(['
    ','
    ',"top"===this.options.paginationVAlign||"both"===this.options.paginationVAlign?'
    ':"",'
    ','
    ','
    ','
    ',this.options.formatLoadingMessage(),"
    ","
    ",'',"bottom"===this.options.paginationVAlign||"both"===this.options.paginationVAlign?'
    ':"","
    ","
    "].join("")),this.$container.insertAfter(this.$el),this.$tableContainer=this.$container.find(".fixed-table-container"),this.$tableHeader=this.$container.find(".fixed-table-header"),this.$tableBody=this.$container.find(".fixed-table-body"),this.$tableLoading=this.$container.find(".fixed-table-loading"),this.$tableFooter=this.$container.find(".fixed-table-footer"),this.$toolbar=this.$container.find(".fixed-table-toolbar"),this.$pagination=this.$container.find(".fixed-table-pagination"),this.$tableBody.append(this.$el),this.$container.after('
    '),this.$el.addClass(this.options.classes),this.options.striped&&this.$el.addClass("table-striped"),-1!==a.inArray("table-no-bordered",this.options.classes.split(" "))&&this.$tableContainer.addClass("table-no-bordered")},p.prototype.initTable=function(){var b=this,c=[],d=[];if(this.$header=this.$el.find(">thead"),this.$header.length||(this.$header=a("").appendTo(this.$el)),this.$header.find("tr").each(function(){var b=[];a(this).find("th").each(function(){"undefined"!=typeof a(this).data("field")&&a(this).data("field",a(this).data("field")+""),b.push(a.extend({},{title:a(this).html(),"class":a(this).attr("class"),titleTooltip:a(this).attr("title"),rowspan:a(this).attr("rowspan")?+a(this).attr("rowspan"):void 0,colspan:a(this).attr("colspan")?+a(this).attr("colspan"):void 0},a(this).data()))}),c.push(b)}),a.isArray(this.options.columns[0])||(this.options.columns=[this.options.columns]),this.options.columns=a.extend(!0,[],c,this.options.columns),this.columns=[],f(this.options.columns),a.each(this.options.columns,function(c,d){a.each(d,function(d,e){e=a.extend({},p.COLUMN_DEFAULTS,e),"undefined"!=typeof e.fieldIndex&&(b.columns[e.fieldIndex]=e),b.options.columns[c][d]=e})}),!this.options.data.length){var e=[];this.$el.find(">tbody>tr").each(function(c){var f={};f._id=a(this).attr("id"),f._class=a(this).attr("class"),f._data=l(a(this).data()),a(this).find(">td").each(function(d){for(var g,h,i=a(this),j=+i.attr("colspan")||1,k=+i.attr("rowspan")||1;e[c]&&e[c][d];d++);for(g=d;d+j>g;g++)for(h=c;c+k>h;h++)e[h]||(e[h]=[]),e[h][g]=!0;var m=b.columns[d].field;f[m]=a(this).html(),f["_"+m+"_id"]=a(this).attr("id"),f["_"+m+"_class"]=a(this).attr("class"),f["_"+m+"_rowspan"]=a(this).attr("rowspan"),f["_"+m+"_colspan"]=a(this).attr("colspan"),f["_"+m+"_title"]=a(this).attr("title"),f["_"+m+"_data"]=l(a(this).data())}),d.push(f)}),this.options.data=d,d.length&&(this.fromHtml=!0)}},p.prototype.initHeader=function(){var b=this,d={},e=[];this.header={fields:[],styles:[],classes:[],formatters:[],events:[],sorters:[],sortNames:[],cellStyles:[],searchables:[]},a.each(this.options.columns,function(f,g){e.push(""),0===f&&!b.options.cardView&&b.options.detailView&&e.push(c('
    ',b.options.columns.length)),a.each(g,function(a,f){var g="",h="",i="",j="",k=c(' class="%s"',f["class"]),l=(b.options.sortOrder||f.order,"px"),m=f.width;if(void 0===f.width||b.options.cardView||"string"==typeof f.width&&-1!==f.width.indexOf("%")&&(l="%"),f.width&&"string"==typeof f.width&&(m=f.width.replace("%","").replace("px","")),h=c("text-align: %s; ",f.halign?f.halign:f.align),i=c("text-align: %s; ",f.align),j=c("vertical-align: %s; ",f.valign),j+=c("width: %s; ",!f.checkbox&&!f.radio||m?m?m+l:void 0:"36px"),"undefined"!=typeof f.fieldIndex){if(b.header.fields[f.fieldIndex]=f.field,b.header.styles[f.fieldIndex]=i+j,b.header.classes[f.fieldIndex]=k,b.header.formatters[f.fieldIndex]=f.formatter,b.header.events[f.fieldIndex]=f.events,b.header.sorters[f.fieldIndex]=f.sorter,b.header.sortNames[f.fieldIndex]=f.sortName,b.header.cellStyles[f.fieldIndex]=f.cellStyle,b.header.searchables[f.fieldIndex]=f.searchable,!f.visible)return;if(b.options.cardView&&!f.cardVisible)return;d[f.field]=f}e.push(""),e.push(c('
    ',b.options.sortable&&f.sortable?"sortable both":"")),g=f.title,f.checkbox&&(!b.options.singleSelect&&b.options.checkboxHeader&&(g=''),b.header.stateField=f.field),f.radio&&(g="",b.header.stateField=f.field,b.options.singleSelect=!0),e.push(g),e.push("
    "),e.push('
    '),e.push("
    "),e.push("")}),e.push("")}),this.$header.html(e.join("")),this.$header.find("th[data-field]").each(function(){a(this).data(d[a(this).data("field")])}),this.$container.off("click",".th-inner").on("click",".th-inner",function(c){var d=a(this);return b.options.detailView&&d.closest(".bootstrap-table")[0]!==b.$container[0]?!1:void(b.options.sortable&&d.parent().data().sortable&&b.onSort(c))}),this.$header.children().children().off("keypress").on("keypress",function(c){if(b.options.sortable&&a(this).data().sortable){var d=c.keyCode||c.which;13==d&&b.onSort(c)}}),a(window).off("resize.bootstrap-table"),!this.options.showHeader||this.options.cardView?(this.$header.hide(),this.$tableHeader.hide(),this.$tableLoading.css("top",0)):(this.$header.show(),this.$tableHeader.show(),this.$tableLoading.css("top",this.$header.outerHeight()+1),this.getCaret(),a(window).on("resize.bootstrap-table",a.proxy(this.resetWidth,this))),this.$selectAll=this.$header.find('[name="btSelectAll"]'),this.$selectAll.off("click").on("click",function(){var c=a(this).prop("checked");b[c?"checkAll":"uncheckAll"](),b.updateSelected()})},p.prototype.initFooter=function(){!this.options.showFooter||this.options.cardView?this.$tableFooter.hide():this.$tableFooter.show()},p.prototype.initData=function(a,b){this.data="append"===b?this.data.concat(a):"prepend"===b?[].concat(a).concat(this.data):a||this.options.data,this.options.data="append"===b?this.options.data.concat(a):"prepend"===b?[].concat(a).concat(this.options.data):this.data,"server"!==this.options.sidePagination&&this.initSort()},p.prototype.initSort=function(){var b=this,d=this.options.sortName,e="desc"===this.options.sortOrder?-1:1,f=a.inArray(this.options.sortName,this.header.fields),g=0;return this.options.customSort!==a.noop?void this.options.customSort.apply(this,[this.options.sortName,this.options.sortOrder]):void(-1!==f&&(this.options.sortStable&&a.each(this.data,function(a,b){b.hasOwnProperty("_position")||(b._position=a)}),this.data.sort(function(c,g){b.header.sortNames[f]&&(d=b.header.sortNames[f]);var i=m(c,d,b.options.escape),j=m(g,d,b.options.escape),k=h(b.header,b.header.sorters[f],[i,j]);return void 0!==k?e*k:((void 0===i||null===i)&&(i=""),(void 0===j||null===j)&&(j=""),b.options.sortStable&&i===j&&(i=c._position,j=g._position),a.isNumeric(i)&&a.isNumeric(j)?(i=parseFloat(i),j=parseFloat(j),j>i?-1*e:e):i===j?0:("string"!=typeof i&&(i=i.toString()),-1===i.localeCompare(j)?-1*e:e))}),void 0!==this.options.sortClass&&(clearTimeout(g),g=setTimeout(function(){b.$el.removeClass(b.options.sortClass);var a=b.$header.find(c('[data-field="%s"]',b.options.sortName).index()+1);b.$el.find(c("tr td:nth-child(%s)",a)).addClass(b.options.sortClass)},250))))},p.prototype.onSort=function(b){var c="keypress"===b.type?a(b.currentTarget):a(b.currentTarget).parent(),d=this.$header.find("th").eq(c.index());return this.$header.add(this.$header_).find("span.order").remove(),this.options.sortName===c.data("field")?this.options.sortOrder="asc"===this.options.sortOrder?"desc":"asc":(this.options.sortName=c.data("field"),this.options.sortOrder="asc"===c.data("order")?"desc":"asc"),this.trigger("sort",this.options.sortName,this.options.sortOrder),c.add(d).data("order",this.options.sortOrder),this.getCaret(),"server"===this.options.sidePagination?void this.initServer(this.options.silentSort):(this.initSort(),void this.initBody())},p.prototype.initToolbar=function(){var b,d,e=this,f=[],g=0,i=0;this.$toolbar.find(".bs-bars").children().length&&a("body").append(a(this.options.toolbar)),this.$toolbar.html(""),("string"==typeof this.options.toolbar||"object"==typeof this.options.toolbar)&&a(c('
    ',this.options.toolbarAlign)).appendTo(this.$toolbar).append(a(this.options.toolbar)),f=[c('
    ',this.options.buttonsAlign,this.options.buttonsAlign)],"string"==typeof this.options.icons&&(this.options.icons=h(null,this.options.icons)),this.options.showPaginationSwitch&&f.push(c('"),this.options.showRefresh&&f.push(c('"),this.options.showToggle&&f.push(c('"),this.options.showColumns&&(f.push(c('
    ',this.options.formatColumns()),'",'","
    ")),f.push("
    "),(this.showToolbar||f.length>2)&&this.$toolbar.append(f.join("")),this.options.showPaginationSwitch&&this.$toolbar.find('button[name="paginationSwitch"]').off("click").on("click",a.proxy(this.togglePagination,this)),this.options.showRefresh&&this.$toolbar.find('button[name="refresh"]').off("click").on("click",a.proxy(this.refresh,this)),this.options.showToggle&&this.$toolbar.find('button[name="toggle"]').off("click").on("click",function(){e.toggleView()}),this.options.showColumns&&(b=this.$toolbar.find(".keep-open"),i<=this.options.minimumCountColumns&&b.find("input").prop("disabled",!0),b.find("li").off("click").on("click",function(a){a.stopImmediatePropagation()}),b.find("input").off("click").on("click",function(){var b=a(this);e.toggleColumn(a(this).val(),b.prop("checked"),!1),e.trigger("column-switch",a(this).data("field"),b.prop("checked"))})),this.options.search&&(f=[],f.push('"),this.$toolbar.append(f.join("")),d=this.$toolbar.find(".search input"),d.off("keyup drop").on("keyup drop",function(b){e.options.searchOnEnterKey&&13!==b.keyCode||a.inArray(b.keyCode,[37,38,39,40])>-1||(clearTimeout(g),g=setTimeout(function(){e.onSearch(b)},e.options.searchTimeOut))}),n()&&d.off("mouseup").on("mouseup",function(a){clearTimeout(g),g=setTimeout(function(){e.onSearch(a)},e.options.searchTimeOut)}))},p.prototype.onSearch=function(b){var c=a.trim(a(b.currentTarget).val());this.options.trimOnSearch&&a(b.currentTarget).val()!==c&&a(b.currentTarget).val(c),c!==this.searchText&&(this.searchText=c,this.options.searchText=c,this.options.pageNumber=1,this.initSearch(),this.updatePagination(),this.trigger("search",c))},p.prototype.initSearch=function(){var b=this;if("server"!==this.options.sidePagination){if(this.options.customSearch!==a.noop)return void this.options.customSearch.apply(this,[this.searchText]);var c=this.searchText&&(this.options.escape?j(this.searchText):this.searchText).toLowerCase(),d=a.isEmptyObject(this.filterColumns)?null:this.filterColumns;this.data=d?a.grep(this.options.data,function(b){for(var c in d)if(a.isArray(d[c])&&-1===a.inArray(b[c],d[c])||!a.isArray(d[c])&&b[c]!==d[c])return!1;return!0}):this.options.data,this.data=c?a.grep(this.data,function(d,f){for(var g=0;g-1&&(n=!0)}this.totalPages=~~((this.options.totalRows-1)/this.options.pageSize)+1,this.options.totalPages=this.totalPages}if(this.totalPages>0&&this.options.pageNumber>this.totalPages&&(this.options.pageNumber=this.totalPages),this.pageFrom=(this.options.pageNumber-1)*this.options.pageSize+1,this.pageTo=this.options.pageNumber*this.options.pageSize,this.pageTo>this.options.totalRows&&(this.pageTo=this.options.totalRows),m.push('
    ','',this.options.onlyInfoPagination?this.options.formatDetailPagination(this.options.totalRows):this.options.formatShowingRows(this.pageFrom,this.pageTo,this.options.totalRows),""),!this.options.onlyInfoPagination){m.push('');var r=[c('',"top"===this.options.paginationVAlign||"both"===this.options.paginationVAlign?"dropdown":"dropup"),'",'"),m.push(this.options.formatRecordsPerPage(r.join(""))),m.push(""),m.push("
    ",'")}this.$pagination.html(m.join("")),this.options.onlyInfoPagination||(f=this.$pagination.find(".page-list a"),g=this.$pagination.find(".page-first"),h=this.$pagination.find(".page-pre"),i=this.$pagination.find(".page-next"),j=this.$pagination.find(".page-last"),k=this.$pagination.find(".page-number"),this.options.smartDisplay&&(this.totalPages<=1&&this.$pagination.find("div.pagination").hide(),(p.length<2||this.options.totalRows<=p[0])&&this.$pagination.find("span.page-list").hide(),this.$pagination[this.getData().length?"show":"hide"]()),this.options.paginationLoop||(1===this.options.pageNumber&&h.addClass("disabled"),this.options.pageNumber===this.totalPages&&i.addClass("disabled")),n&&(this.options.pageSize=this.options.formatAllRows()),f.off("click").on("click",a.proxy(this.onPageListChange,this)),g.off("click").on("click",a.proxy(this.onPageFirst,this)),h.off("click").on("click",a.proxy(this.onPagePre,this)),i.off("click").on("click",a.proxy(this.onPageNext,this)),j.off("click").on("click",a.proxy(this.onPageLast,this)),k.off("click").on("click",a.proxy(this.onPageNumber,this)))},p.prototype.updatePagination=function(b){b&&a(b.currentTarget).hasClass("disabled")||(this.options.maintainSelected||this.resetRows(),this.initPagination(),"server"===this.options.sidePagination?this.initServer():this.initBody(),this.trigger("page-change",this.options.pageNumber,this.options.pageSize))},p.prototype.onPageListChange=function(b){var c=a(b.currentTarget);c.parent().addClass("active").siblings().removeClass("active"),this.options.pageSize=c.text().toUpperCase()===this.options.formatAllRows().toUpperCase()?this.options.formatAllRows():+c.text(),this.$toolbar.find(".page-size").text(this.options.pageSize),this.updatePagination(b)},p.prototype.onPageFirst=function(a){this.options.pageNumber=1,this.updatePagination(a)},p.prototype.onPagePre=function(a){this.options.pageNumber-1===0?this.options.pageNumber=this.options.totalPages:this.options.pageNumber--,this.updatePagination(a)},p.prototype.onPageNext=function(a){this.options.pageNumber+1>this.options.totalPages?this.options.pageNumber=1:this.options.pageNumber++,this.updatePagination(a)},p.prototype.onPageLast=function(a){this.options.pageNumber=this.totalPages,this.updatePagination(a)},p.prototype.onPageNumber=function(b){this.options.pageNumber!==+a(b.currentTarget).text()&&(this.options.pageNumber=+a(b.currentTarget).text(),this.updatePagination(b))},p.prototype.initBody=function(b){var f=this,g=[],i=this.getData();this.trigger("pre-body",i),this.$body=this.$el.find(">tbody"),this.$body.length||(this.$body=a("").appendTo(this.$el)),this.options.pagination&&"server"!==this.options.sidePagination||(this.pageFrom=1,this.pageTo=i.length);for(var k=this.pageFrom-1;k-1)){if(o=h(this.options,this.options.rowStyle,[n,k],o),o&&o.css)for(l in o.css)p.push(l+": "+o.css[l]);if(r=h(this.options,this.options.rowAttributes,[n,k],r))for(l in r)s.push(c('%s="%s"',l,j(r[l])));n._data&&!a.isEmptyObject(n._data)&&a.each(n._data,function(a,b){"index"!==a&&(q+=c(' data-%s="%s"',a,b))}),g.push(""),this.options.cardView&&g.push(c('
    ',this.header.fields.length)),!this.options.cardView&&this.options.detailView&&g.push("",'',c('',this.options.iconsPrefix,this.options.icons.detailOpen),"",""),a.each(this.header.fields,function(b,e){var i="",j=m(n,e,f.options.escape),l="",q="",r={},s="",t=f.header.classes[b],u="",v="",w="",x="",y=f.columns[b];if(!(f.fromHtml&&"undefined"==typeof j||!y.visible||f.options.cardView&&!y.cardVisible)){if(o=c('style="%s"',p.concat(f.header.styles[b]).join("; ")),n["_"+e+"_id"]&&(s=c(' id="%s"',n["_"+e+"_id"])),n["_"+e+"_class"]&&(t=c(' class="%s"',n["_"+e+"_class"])),n["_"+e+"_rowspan"]&&(v=c(' rowspan="%s"',n["_"+e+"_rowspan"])),n["_"+e+"_colspan"]&&(w=c(' colspan="%s"',n["_"+e+"_colspan"])),n["_"+e+"_title"]&&(x=c(' title="%s"',n["_"+e+"_title"])),r=h(f.header,f.header.cellStyles[b],[j,n,k,e],r),r.classes&&(t=c(' class="%s"',r.classes)),r.css){var z=[];for(var A in r.css)z.push(A+": "+r.css[A]);o=c('style="%s"',z.concat(f.header.styles[b]).join("; "))}l=h(y,f.header.formatters[b],[j,n,k],j),n["_"+e+"_data"]&&!a.isEmptyObject(n["_"+e+"_data"])&&a.each(n["_"+e+"_data"],function(a,b){"index"!==a&&(u+=c(' data-%s="%s"',a,b))}),y.checkbox||y.radio?(q=y.checkbox?"checkbox":q,q=y.radio?"radio":q,i=[c(f.options.cardView?'
    ':'',y["class"]||""),"",f.header.formatters[b]&&"string"==typeof l?l:"",f.options.cardView?"
    ":""].join(""),n[f.header.stateField]=l===!0||l&&l.checked):(l="undefined"==typeof l||null===l?f.options.undefinedText:l,i=f.options.cardView?['
    ',f.options.showHeader?c('%s',o,d(f.columns,"field","title",e)):"",c('%s',l),"
    "].join(""):[c("",s,t,o,u,v,w,x),l,""].join(""),f.options.cardView&&f.options.smartDisplay&&""===l&&(i='
    ')),g.push(i)}}), +this.options.cardView&&g.push("
    "),g.push("")}}g.length||g.push('',c('%s',this.$header.find("th").length,this.options.formatNoMatches()),""),this.$body.html(g.join("")),b||this.scrollTo(0),this.$body.find("> tr[data-index] > td").off("click dblclick").on("click dblclick",function(b){var d=a(this),g=d.parent(),h=f.data[g.data("index")],i=d[0].cellIndex,j=f.getVisibleFields(),k=j[f.options.detailView&&!f.options.cardView?i-1:i],l=f.columns[e(f.columns,k)],n=m(h,k,f.options.escape);if(!d.find(".detail-icon").length&&(f.trigger("click"===b.type?"click-cell":"dbl-click-cell",k,n,h,d),f.trigger("click"===b.type?"click-row":"dbl-click-row",h,g,k),"click"===b.type&&f.options.clickToSelect&&l.clickToSelect)){var o=g.find(c('[name="%s"]',f.options.selectItemName));o.length&&o[0].click()}}),this.$body.find("> tr[data-index] > td > .detail-icon").off("click").on("click",function(){var b=a(this),d=b.parent().parent(),e=d.data("index"),g=i[e];if(d.next().is("tr.detail-view"))b.find("i").attr("class",c("%s %s",f.options.iconsPrefix,f.options.icons.detailOpen)),d.next().remove(),f.trigger("collapse-row",e,g);else{b.find("i").attr("class",c("%s %s",f.options.iconsPrefix,f.options.icons.detailClose)),d.after(c('',d.find("td").length));var j=d.next().find("td"),k=h(f.options,f.options.detailFormatter,[e,g,j],"");1===j.length&&j.append(k),f.trigger("expand-row",e,g,j)}f.resetView()}),this.$selectItem=this.$body.find(c('[name="%s"]',this.options.selectItemName)),this.$selectItem.off("click").on("click",function(b){b.stopImmediatePropagation();var c=a(this),d=c.prop("checked"),e=f.data[c.data("index")];f.options.maintainSelected&&a(this).is(":radio")&&a.each(f.options.data,function(a,b){b[f.header.stateField]=!1}),e[f.header.stateField]=d,f.options.singleSelect&&(f.$selectItem.not(this).each(function(){f.data[a(this).data("index")][f.header.stateField]=!1}),f.$selectItem.filter(":checked").not(this).prop("checked",!1)),f.updateSelected(),f.trigger(d?"check":"uncheck",e,c)}),a.each(this.header.events,function(b,c){if(c){"string"==typeof c&&(c=h(null,c));var d=f.header.fields[b],e=a.inArray(d,f.getVisibleFields());f.options.detailView&&!f.options.cardView&&(e+=1);for(var g in c)f.$body.find(">tr:not(.no-records-found)").each(function(){var b=a(this),h=b.find(f.options.cardView?".card-view":"td").eq(e),i=g.indexOf(" "),j=g.substring(0,i),k=g.substring(i+1),l=c[g];h.find(k).off(j).on(j,function(a){var c=b.data("index"),e=f.data[c],g=e[d];l.apply(this,[a,g,e,c])})})}}),this.updateSelected(),this.resetView(),this.trigger("post-body",i)},p.prototype.initServer=function(b,c,d){var e,f=this,g={},i={searchText:this.searchText,sortName:this.options.sortName,sortOrder:this.options.sortOrder};this.options.pagination&&(i.pageSize=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize,i.pageNumber=this.options.pageNumber),(d||this.options.url||this.options.ajax)&&("limit"===this.options.queryParamsType&&(i={search:i.searchText,sort:i.sortName,order:i.sortOrder},this.options.pagination&&(i.offset=this.options.pageSize===this.options.formatAllRows()?0:this.options.pageSize*(this.options.pageNumber-1),i.limit=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize)),a.isEmptyObject(this.filterColumnsPartial)||(i.filter=JSON.stringify(this.filterColumnsPartial,null)),g=h(this.options,this.options.queryParams,[i],g),a.extend(g,c||{}),g!==!1&&(b||this.$tableLoading.show(),e=a.extend({},h(null,this.options.ajaxOptions),{type:this.options.method,url:d||this.options.url,data:"application/json"===this.options.contentType&&"post"===this.options.method?JSON.stringify(g):g,cache:this.options.cache,contentType:this.options.contentType,dataType:this.options.dataType,success:function(a){a=h(f.options,f.options.responseHandler,[a],a),f.load(a),f.trigger("load-success",a),b||f.$tableLoading.hide()},error:function(a){f.trigger("load-error",a.status,a),b||f.$tableLoading.hide()}}),this.options.ajax?h(this,this.options.ajax,[e],null):(this._xhr&&4!==this._xhr.readyState&&this._xhr.abort(),this._xhr=a.ajax(e))))},p.prototype.initSearchText=function(){if(this.options.search&&""!==this.options.searchText){var a=this.$toolbar.find(".search input");a.val(this.options.searchText),this.onSearch({currentTarget:a})}},p.prototype.getCaret=function(){var b=this;a.each(this.$header.find("th"),function(c,d){a(d).find(".sortable").removeClass("desc asc").addClass(a(d).data("field")===b.options.sortName?b.options.sortOrder:"both")})},p.prototype.updateSelected=function(){var b=this.$selectItem.filter(":enabled").length&&this.$selectItem.filter(":enabled").length===this.$selectItem.filter(":enabled").filter(":checked").length;this.$selectAll.add(this.$selectAll_).prop("checked",b),this.$selectItem.each(function(){a(this).closest("tr")[a(this).prop("checked")?"addClass":"removeClass"]("selected")})},p.prototype.updateRows=function(){var b=this;this.$selectItem.each(function(){b.data[a(this).data("index")][b.header.stateField]=a(this).prop("checked")})},p.prototype.resetRows=function(){var b=this;a.each(this.data,function(a,c){b.$selectAll.prop("checked",!1),b.$selectItem.prop("checked",!1),b.header.stateField&&(c[b.header.stateField]=!1)}),this.initHiddenRows()},p.prototype.trigger=function(b){var c=Array.prototype.slice.call(arguments,1);b+=".bs.table",this.options[p.EVENTS[b]].apply(this.options,c),this.$el.trigger(a.Event(b),c),this.options.onAll(b,c),this.$el.trigger(a.Event("all.bs.table"),[b,c])},p.prototype.resetHeader=function(){clearTimeout(this.timeoutId_),this.timeoutId_=setTimeout(a.proxy(this.fitHeader,this),this.$el.is(":hidden")?100:0)},p.prototype.fitHeader=function(){var b,d,e,f,h=this;if(h.$el.is(":hidden"))return void(h.timeoutId_=setTimeout(a.proxy(h.fitHeader,h),100));if(b=this.$tableBody.get(0),d=b.scrollWidth>b.clientWidth&&b.scrollHeight>b.clientHeight+this.$header.outerHeight()?g():0,this.$el.css("margin-top",-this.$header.outerHeight()),e=a(":focus"),e.length>0){var i=e.parents("th");if(i.length>0){var j=i.attr("data-field");if(void 0!==j){var k=this.$header.find("[data-field='"+j+"']");k.length>0&&k.find(":input").addClass("focus-temp")}}}this.$header_=this.$header.clone(!0,!0),this.$selectAll_=this.$header_.find('[name="btSelectAll"]'),this.$tableHeader.css({"margin-right":d}).find("table").css("width",this.$el.outerWidth()).html("").attr("class",this.$el.attr("class")).append(this.$header_),f=a(".focus-temp:visible:eq(0)"),f.length>0&&(f.focus(),this.$header.find(".focus-temp").removeClass("focus-temp")),this.$header.find("th[data-field]").each(function(){h.$header_.find(c('th[data-field="%s"]',a(this).data("field"))).data(a(this).data())});var l=this.getVisibleFields(),m=this.$header_.find("th");this.$body.find(">tr:first-child:not(.no-records-found) > *").each(function(b){var d=a(this),e=b;h.options.detailView&&!h.options.cardView&&(0===b&&h.$header_.find("th.detail").find(".fht-cell").width(d.innerWidth()),e=b-1);var f=h.$header_.find(c('th[data-field="%s"]',l[e]));f.length>1&&(f=a(m[d[0].cellIndex])),f.find(".fht-cell").width(d.innerWidth())}),this.$tableBody.off("scroll").on("scroll",function(){h.$tableHeader.scrollLeft(a(this).scrollLeft()),h.options.showFooter&&!h.options.cardView&&h.$tableFooter.scrollLeft(a(this).scrollLeft())}),h.trigger("post-header")},p.prototype.resetFooter=function(){var b=this,d=b.getData(),e=[];this.options.showFooter&&!this.options.cardView&&(!this.options.cardView&&this.options.detailView&&e.push('
     
    '),a.each(this.columns,function(a,f){var g,i="",j="",k=[],l={},m=c(' class="%s"',f["class"]);if(f.visible&&(!b.options.cardView||f.cardVisible)){if(i=c("text-align: %s; ",f.falign?f.falign:f.align),j=c("vertical-align: %s; ",f.valign),l=h(null,b.options.footerStyle),l&&l.css)for(g in l.css)k.push(g+": "+l.css[g]);e.push(""),e.push('
    '),e.push(h(f,f.footerFormatter,[d]," ")||" "),e.push("
    "),e.push('
    '),e.push("
    "),e.push("")}}),this.$tableFooter.find("tr").html(e.join("")),this.$tableFooter.show(),clearTimeout(this.timeoutFooter_),this.timeoutFooter_=setTimeout(a.proxy(this.fitFooter,this),this.$el.is(":hidden")?100:0))},p.prototype.fitFooter=function(){var b,c,d;return clearTimeout(this.timeoutFooter_),this.$el.is(":hidden")?void(this.timeoutFooter_=setTimeout(a.proxy(this.fitFooter,this),100)):(c=this.$el.css("width"),d=c>this.$tableBody.width()?g():0,this.$tableFooter.css({"margin-right":d}).find("table").css("width",c).attr("class",this.$el.attr("class")),b=this.$tableFooter.find("td"),void this.$body.find(">tr:first-child:not(.no-records-found) > *").each(function(c){var d=a(this);b.eq(c).find(".fht-cell").width(d.innerWidth())}))},p.prototype.toggleColumn=function(a,b,d){if(-1!==a&&(this.columns[a].visible=b,this.initHeader(),this.initSearch(),this.initPagination(),this.initBody(),this.options.showColumns)){var e=this.$toolbar.find(".keep-open input").prop("disabled",!1);d&&e.filter(c('[value="%s"]',a)).prop("checked",b),e.filter(":checked").length<=this.options.minimumCountColumns&&e.filter(":checked").prop("disabled",!0)}},p.prototype.getVisibleFields=function(){var b=this,c=[];return a.each(this.header.fields,function(a,d){var f=b.columns[e(b.columns,d)];f.visible&&c.push(d)}),c},p.prototype.resetView=function(a){var b=0;if(a&&a.height&&(this.options.height=a.height),this.$selectAll.prop("checked",this.$selectItem.length>0&&this.$selectItem.length===this.$selectItem.filter(":checked").length),this.options.height){var c=k(this.$toolbar),d=k(this.$pagination),e=this.options.height-c-d;this.$tableContainer.css("height",e+"px")}return this.options.cardView?(this.$el.css("margin-top","0"),this.$tableContainer.css("padding-bottom","0"),void this.$tableFooter.hide()):(this.options.showHeader&&this.options.height?(this.$tableHeader.show(),this.resetHeader(),b+=this.$header.outerHeight()):(this.$tableHeader.hide(),this.trigger("post-header")),this.options.showFooter&&(this.resetFooter(),this.options.height&&(b+=this.$tableFooter.outerHeight()+1)),this.getCaret(),this.$tableContainer.css("padding-bottom",b+"px"),void this.trigger("reset-view"))},p.prototype.getData=function(b){return!this.searchText&&a.isEmptyObject(this.filterColumns)&&a.isEmptyObject(this.filterColumnsPartial)?b?this.options.data.slice(this.pageFrom-1,this.pageTo):this.options.data:b?this.data.slice(this.pageFrom-1,this.pageTo):this.data},p.prototype.load=function(b){var c=!1;"server"===this.options.sidePagination?(this.options.totalRows=b[this.options.totalField],c=b.fixedScroll,b=b[this.options.dataField]):a.isArray(b)||(c=b.fixedScroll,b=b.data),this.initData(b),this.initSearch(),this.initPagination(),this.initBody(c)},p.prototype.append=function(a){this.initData(a,"append"),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0)},p.prototype.prepend=function(a){this.initData(a,"prepend"),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0)},p.prototype.remove=function(b){var c,d,e=this.options.data.length;if(b.hasOwnProperty("field")&&b.hasOwnProperty("values")){for(c=e-1;c>=0;c--)d=this.options.data[c],d.hasOwnProperty(b.field)&&-1!==a.inArray(d[b.field],b.values)&&(this.options.data.splice(c,1),"server"===this.options.sidePagination&&(this.options.totalRows-=1));e!==this.options.data.length&&(this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0))}},p.prototype.removeAll=function(){this.options.data.length>0&&(this.options.data.splice(0,this.options.data.length),this.initSearch(),this.initPagination(),this.initBody(!0))},p.prototype.getRowByUniqueId=function(a){var b,c,d,e=this.options.uniqueId,f=this.options.data.length,g=null;for(b=f-1;b>=0;b--){if(c=this.options.data[b],c.hasOwnProperty(e))d=c[e];else{if(!c._data.hasOwnProperty(e))continue;d=c._data[e]}if("string"==typeof d?a=a.toString():"number"==typeof d&&(Number(d)===d&&d%1===0?a=parseInt(a):d===Number(d)&&0!==d&&(a=parseFloat(a))),d===a){g=c;break}}return g},p.prototype.removeByUniqueId=function(a){var b=this.options.data.length,c=this.getRowByUniqueId(a);c&&this.options.data.splice(this.options.data.indexOf(c),1),b!==this.options.data.length&&(this.initSearch(),this.initPagination(),this.initBody(!0))},p.prototype.updateByUniqueId=function(b){var c=this,d=a.isArray(b)?b:[b];a.each(d,function(b,d){var e;d.hasOwnProperty("id")&&d.hasOwnProperty("row")&&(e=a.inArray(c.getRowByUniqueId(d.id),c.options.data),-1!==e&&a.extend(c.options.data[e],d.row))}),this.initSearch(),this.initSort(),this.initBody(!0)},p.prototype.insertRow=function(a){a.hasOwnProperty("index")&&a.hasOwnProperty("row")&&(this.data.splice(a.index,0,a.row),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0))},p.prototype.updateRow=function(b){var c=this,d=a.isArray(b)?b:[b];a.each(d,function(b,d){d.hasOwnProperty("index")&&d.hasOwnProperty("row")&&a.extend(c.options.data[d.index],d.row)}),this.initSearch(),this.initSort(),this.initBody(!0)},p.prototype.initHiddenRows=function(){this.hiddenRows=[]},p.prototype.showRow=function(a){this.toggleRow(a,!0)},p.prototype.hideRow=function(a){this.toggleRow(a,!1)},p.prototype.toggleRow=function(b,c){var d,e;b.hasOwnProperty("index")?d=this.getData()[b.index]:b.hasOwnProperty("uniqueId")&&(d=this.getRowByUniqueId(b.uniqueId)),d&&(e=a.inArray(d,this.hiddenRows),c||-1!==e?c&&e>-1&&this.hiddenRows.splice(e,1):this.hiddenRows.push(d),this.initBody(!0))},p.prototype.getHiddenRows=function(){var b=this,c=this.getData(),d=[];return a.each(c,function(c,e){a.inArray(e,b.hiddenRows)>-1&&d.push(e)}),this.hiddenRows=d,d},p.prototype.mergeCells=function(b){var c,d,e,f=b.index,g=a.inArray(b.field,this.getVisibleFields()),h=b.rowspan||1,i=b.colspan||1,j=this.$body.find(">tr");if(this.options.detailView&&!this.options.cardView&&(g+=1),e=j.eq(f).find(">td").eq(g),!(0>f||0>g||f>=this.data.length)){for(c=f;f+h>c;c++)for(d=g;g+i>d;d++)j.eq(c).find(">td").eq(d).hide();e.attr("rowspan",h).attr("colspan",i).show()}},p.prototype.updateCell=function(a){a.hasOwnProperty("index")&&a.hasOwnProperty("field")&&a.hasOwnProperty("value")&&(this.data[a.index][a.field]=a.value,a.reinit!==!1&&(this.initSort(),this.initBody(!0)))},p.prototype.getOptions=function(){return this.options},p.prototype.getSelections=function(){var b=this;return a.grep(this.options.data,function(a){return a[b.header.stateField]===!0})},p.prototype.getAllSelections=function(){var b=this;return a.grep(this.options.data,function(a){return a[b.header.stateField]})},p.prototype.checkAll=function(){this.checkAll_(!0)},p.prototype.uncheckAll=function(){this.checkAll_(!1)},p.prototype.checkInvert=function(){var b=this,c=b.$selectItem.filter(":enabled"),d=c.filter(":checked");c.each(function(){a(this).prop("checked",!a(this).prop("checked"))}),b.updateRows(),b.updateSelected(),b.trigger("uncheck-some",d),d=b.getSelections(),b.trigger("check-some",d)},p.prototype.checkAll_=function(a){var b;a||(b=this.getSelections()),this.$selectAll.add(this.$selectAll_).prop("checked",a),this.$selectItem.filter(":enabled").prop("checked",a),this.updateRows(),a&&(b=this.getSelections()),this.trigger(a?"check-all":"uncheck-all",b)},p.prototype.check=function(a){this.check_(!0,a)},p.prototype.uncheck=function(a){this.check_(!1,a)},p.prototype.check_=function(a,b){var d=this.$selectItem.filter(c('[data-index="%s"]',b)).prop("checked",a);this.data[b][this.header.stateField]=a,this.updateSelected(),this.trigger(a?"check":"uncheck",this.data[b],d)},p.prototype.checkBy=function(a){this.checkBy_(!0,a)},p.prototype.uncheckBy=function(a){this.checkBy_(!1,a)},p.prototype.checkBy_=function(b,d){if(d.hasOwnProperty("field")&&d.hasOwnProperty("values")){var e=this,f=[];a.each(this.options.data,function(g,h){if(!h.hasOwnProperty(d.field))return!1;if(-1!==a.inArray(h[d.field],d.values)){var i=e.$selectItem.filter(":enabled").filter(c('[data-index="%s"]',g)).prop("checked",b);h[e.header.stateField]=b,f.push(h),e.trigger(b?"check":"uncheck",h,i)}}),this.updateSelected(),this.trigger(b?"check-some":"uncheck-some",f)}},p.prototype.destroy=function(){this.$el.insertBefore(this.$container),a(this.options.toolbar).insertBefore(this.$el),this.$container.next().remove(),this.$container.remove(),this.$el.html(this.$el_.html()).css("margin-top","0").attr("class",this.$el_.attr("class")||"")},p.prototype.showLoading=function(){this.$tableLoading.show()},p.prototype.hideLoading=function(){this.$tableLoading.hide()},p.prototype.togglePagination=function(){this.options.pagination=!this.options.pagination;var a=this.$toolbar.find('button[name="paginationSwitch"] i');this.options.pagination?a.attr("class",this.options.iconsPrefix+" "+this.options.icons.paginationSwitchDown):a.attr("class",this.options.iconsPrefix+" "+this.options.icons.paginationSwitchUp),this.updatePagination()},p.prototype.refresh=function(a){a&&a.url&&(this.options.pageNumber=1),this.initServer(a&&a.silent,a&&a.query,a&&a.url),this.trigger("refresh",a)},p.prototype.resetWidth=function(){this.options.showHeader&&this.options.height&&this.fitHeader(),this.options.showFooter&&this.fitFooter()},p.prototype.showColumn=function(a){this.toggleColumn(e(this.columns,a),!0,!0)},p.prototype.hideColumn=function(a){this.toggleColumn(e(this.columns,a),!1,!0)},p.prototype.getHiddenColumns=function(){return a.grep(this.columns,function(a){return!a.visible})},p.prototype.getVisibleColumns=function(){return a.grep(this.columns,function(a){return a.visible})},p.prototype.toggleAllColumns=function(b){if(a.each(this.columns,function(a){this.columns[a].visible=b}),this.initHeader(),this.initSearch(),this.initPagination(),this.initBody(),this.options.showColumns){var c=this.$toolbar.find(".keep-open input").prop("disabled",!1);c.filter(":checked").length<=this.options.minimumCountColumns&&c.filter(":checked").prop("disabled",!0)}},p.prototype.showAllColumns=function(){this.toggleAllColumns(!0)},p.prototype.hideAllColumns=function(){this.toggleAllColumns(!1)},p.prototype.filterBy=function(b){this.filterColumns=a.isEmptyObject(b)?{}:b,this.options.pageNumber=1,this.initSearch(),this.updatePagination()},p.prototype.scrollTo=function(a){return"string"==typeof a&&(a="bottom"===a?this.$tableBody[0].scrollHeight:0),"number"==typeof a&&this.$tableBody.scrollTop(a),"undefined"==typeof a?this.$tableBody.scrollTop():void 0},p.prototype.getScrollPosition=function(){return this.scrollTo()},p.prototype.selectPage=function(a){a>0&&a<=this.options.totalPages&&(this.options.pageNumber=a,this.updatePagination())},p.prototype.prevPage=function(){this.options.pageNumber>1&&(this.options.pageNumber--,this.updatePagination())},p.prototype.nextPage=function(){this.options.pageNumber tr[data-index="%s"]',b));d.next().is("tr.detail-view")===(a?!1:!0)&&d.find("> td > .detail-icon").click()},p.prototype.expandRow=function(a){this.expandRow_(!0,a)},p.prototype.collapseRow=function(a){this.expandRow_(!1,a)},p.prototype.expandAllRows=function(b){if(b){var d=this.$body.find(c('> tr[data-index="%s"]',0)),e=this,f=null,g=!1,h=-1;if(d.next().is("tr.detail-view")?d.next().next().is("tr.detail-view")||(d.next().find(".detail-icon").click(),g=!0):(d.find("> td > .detail-icon").click(),g=!0),g)try{h=setInterval(function(){f=e.$body.find("tr.detail-view").last().find(".detail-icon"),f.length>0?f.click():clearInterval(h)},1)}catch(i){clearInterval(h)}}else for(var j=this.$body.children(),k=0;k.btn-group"),g=f.find("div.export");if(!g.length){g=a(['
    ','",'","
    "].join("")).appendTo(f);var h=g.find(".dropdown-menu"),i=this.options.exportTypes;if("string"==typeof this.options.exportTypes){var j=this.options.exportTypes.slice(1,-1).replace(/ /g,"").split(",");i=[],a.each(j,function(a,b){i.push(b.slice(1,-1))})}a.each(i,function(a,b){c.hasOwnProperty(b)&&h.append(['
  • ','',c[b],"","
  • "].join(""))}),h.find("li").click(function(){var b=a(this).data("type"),c=function(){d.$el.tableExport(a.extend({},d.options.exportOptions,{type:b,escape:!1}))};if("all"===d.options.exportDataType&&d.options.pagination)d.$el.one("server"===d.options.sidePagination?"post-body.bs.table":"page-change.bs.table",function(){c(),d.togglePagination()}),d.togglePagination();else if("selected"===d.options.exportDataType){var e=d.getData(),f=d.getAllSelections();d.load(f),c(),d.load(e)}else c()})}}}}(jQuery),!function(a){"use strict";var b=function(b,c){b.options.columnsHidden.length>0&&a.each(b.columns,function(d,e){-1!==b.options.columnsHidden.indexOf(e.field)&&e.visible!==c&&b.toggleColumn(a.fn.bootstrapTable.utils.getFieldIndex(b.columns,e.field),c,!0)})},c=function(a){(a.options.height||a.options.showFooter)&&setTimeout(function(){a.resetView.call(a)},1)},d=function(a,b,d){a.options.minHeight?b<=a.options.minWidth&&d<=a.options.minHeight?e(a):b>a.options.minWidth&&d>a.options.minHeight&&f(a):b<=a.options.minWidth?e(a):b>a.options.minWidth&&f(a),c(a)},e=function(a){g(a,!1),b(a,!1)},f=function(a){g(a,!0),b(a,!0)},g=function(a,b){a.options.cardView=b,a.toggleView()},h=function(a,b){var c;return function(){var d=this,e=arguments,f=function(){c=null,a.apply(d,e)};clearTimeout(c),c=setTimeout(f,b)}};a.extend(a.fn.bootstrapTable.defaults,{mobileResponsive:!1,minWidth:562,minHeight:void 0,heightThreshold:100,checkOnInit:!0,columnsHidden:[]});var i=a.fn.bootstrapTable.Constructor,j=i.prototype.init;i.prototype.init=function(){if(j.apply(this,Array.prototype.slice.apply(arguments)),this.options.mobileResponsive&&this.options.minWidth){this.options.minWidth<100&&this.options.resizable&&(console.log("The minWidth when the resizable extension is active should be greater or equal than 100"),this.options.minWidth=100);var b=this,c={width:a(window).width(),height:a(window).height()};if(a(window).on("resize orientationchange",h(function(){var e=a(this).height(),f=a(this).width();(Math.abs(c.height-e)>b.options.heightThreshold||c.width!=f)&&(d(b,f,e),c={width:f,height:e})},200)),this.options.checkOnInit){var e=a(window).height(),f=a(window).width();d(this,f,e),c={width:f,height:e}}}}}(jQuery),"undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");if(+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){ +b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery),!function(a,b){"use strict";"undefined"!=typeof module&&module.exports?module.exports=b(require("jquery"),require("bootstrap")):"function"==typeof define&&define.amd?define("bootstrap-dialog",["jquery","bootstrap"],function(a){return b(a)}):a.BootstrapDialog=b(a.jQuery)}(this,function(a){"use strict";var b=a.fn.modal.Constructor,c=function(a,c){b.call(this,a,c)};c.getModalVersion=function(){var b=null;return b="undefined"==typeof a.fn.modal.Constructor.VERSION?"v3.1":/3\.2\.\d+/.test(a.fn.modal.Constructor.VERSION)?"v3.2":/3\.3\.[1,2]/.test(a.fn.modal.Constructor.VERSION)?"v3.3":"v3.3.4"},c.ORIGINAL_BODY_PADDING=parseInt(a("body").css("padding-right")||0,10),c.METHODS_TO_OVERRIDE={},c.METHODS_TO_OVERRIDE["v3.1"]={},c.METHODS_TO_OVERRIDE["v3.2"]={hide:function(b){if(b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()){this.isShown=!1; + +var c=this.getGlobalOpenedDialogs();0===c.length&&this.$body.removeClass("modal-open"),this.resetScrollbar(),this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal()}}},c.METHODS_TO_OVERRIDE["v3.3"]={setScrollbar:function(){var a=c.ORIGINAL_BODY_PADDING;this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},resetScrollbar:function(){var a=this.getGlobalOpenedDialogs();0===a.length&&this.$body.css("padding-right",c.ORIGINAL_BODY_PADDING)},hideModal:function(){this.$element.hide(),this.backdrop(a.proxy(function(){var a=this.getGlobalOpenedDialogs();0===a.length&&this.$body.removeClass("modal-open"),this.resetAdjustments(),this.resetScrollbar(),this.$element.trigger("hidden.bs.modal")},this))}},c.METHODS_TO_OVERRIDE["v3.3.4"]=a.extend({},c.METHODS_TO_OVERRIDE["v3.3"]),c.prototype={constructor:c,getGlobalOpenedDialogs:function(){var b=[];return a.each(d.dialogs,function(a,c){c.isRealized()&&c.isOpened()&&b.push(c)}),b}},c.prototype=a.extend(c.prototype,b.prototype,c.METHODS_TO_OVERRIDE[c.getModalVersion()]);var d=function(b){this.defaultOptions=a.extend(!0,{id:d.newGuid(),buttons:[],data:{},onshow:null,onshown:null,onhide:null,onhidden:null},d.defaultOptions),this.indexedButtons={},this.registeredButtonHotkeys={},this.draggableData={isMouseDown:!1,mouseOffset:{}},this.realized=!1,this.opened=!1,this.initOptions(b),this.holdThisInstance()};return d.BootstrapDialogModal=c,d.NAMESPACE="bootstrap-dialog",d.TYPE_DEFAULT="type-default",d.TYPE_INFO="type-info",d.TYPE_PRIMARY="type-primary",d.TYPE_SUCCESS="type-success",d.TYPE_WARNING="type-warning",d.TYPE_DANGER="type-danger",d.DEFAULT_TEXTS={},d.DEFAULT_TEXTS[d.TYPE_DEFAULT]="Information",d.DEFAULT_TEXTS[d.TYPE_INFO]="Information",d.DEFAULT_TEXTS[d.TYPE_PRIMARY]="Information",d.DEFAULT_TEXTS[d.TYPE_SUCCESS]="Success",d.DEFAULT_TEXTS[d.TYPE_WARNING]="Warning",d.DEFAULT_TEXTS[d.TYPE_DANGER]="Danger",d.DEFAULT_TEXTS.OK="OK",d.DEFAULT_TEXTS.CANCEL="Cancel",d.DEFAULT_TEXTS.CONFIRM="Confirmation",d.SIZE_NORMAL="size-normal",d.SIZE_SMALL="size-small",d.SIZE_WIDE="size-wide",d.SIZE_LARGE="size-large",d.BUTTON_SIZES={},d.BUTTON_SIZES[d.SIZE_NORMAL]="",d.BUTTON_SIZES[d.SIZE_SMALL]="",d.BUTTON_SIZES[d.SIZE_WIDE]="",d.BUTTON_SIZES[d.SIZE_LARGE]="btn-lg",d.ICON_SPINNER="glyphicon glyphicon-asterisk",d.BUTTONS_ORDER_CANCEL_OK="btns-order-cancel-ok",d.BUTTONS_ORDER_OK_CANCEL="btns-order-ok-cancel",d.defaultOptions={type:d.TYPE_PRIMARY,size:d.SIZE_NORMAL,cssClass:"",title:null,message:null,nl2br:!0,closable:!0,closeByBackdrop:!0,closeByKeyboard:!0,closeIcon:"×",spinicon:d.ICON_SPINNER,autodestroy:!0,draggable:!1,animate:!0,description:"",tabindex:-1,btnsOrder:d.BUTTONS_ORDER_CANCEL_OK},d.configDefaultOptions=function(b){d.defaultOptions=a.extend(!0,d.defaultOptions,b)},d.dialogs={},d.openAll=function(){a.each(d.dialogs,function(a,b){b.open()})},d.closeAll=function(){a.each(d.dialogs,function(a,b){b.close()})},d.getDialog=function(a){var b=null;return"undefined"!=typeof d.dialogs[a]&&(b=d.dialogs[a]),b},d.setDialog=function(a){return d.dialogs[a.getId()]=a,a},d.addDialog=function(a){return d.setDialog(a)},d.moveFocus=function(){var b=null;a.each(d.dialogs,function(a,c){c.isRealized()&&c.isOpened()&&(b=c)}),null!==b&&b.getModal().focus()},d.METHODS_TO_OVERRIDE={},d.METHODS_TO_OVERRIDE["v3.1"]={handleModalBackdropEvent:function(){return this.getModal().on("click",{dialog:this},function(a){a.target===this&&a.data.dialog.isClosable()&&a.data.dialog.canCloseByBackdrop()&&a.data.dialog.close()}),this},updateZIndex:function(){if(this.isOpened()){var b=1040,c=1050,e=0;a.each(d.dialogs,function(a,b){b.isRealized()&&b.isOpened()&&e++});var f=this.getModal(),g=f.data("bs.modal").$backdrop;f.css("z-index",c+20*(e-1)),g.css("z-index",b+20*(e-1))}return this},open:function(){return!this.isRealized()&&this.realize(),this.getModal().modal("show"),this.updateZIndex(),this}},d.METHODS_TO_OVERRIDE["v3.2"]={handleModalBackdropEvent:d.METHODS_TO_OVERRIDE["v3.1"].handleModalBackdropEvent,updateZIndex:d.METHODS_TO_OVERRIDE["v3.1"].updateZIndex,open:d.METHODS_TO_OVERRIDE["v3.1"].open},d.METHODS_TO_OVERRIDE["v3.3"]={},d.METHODS_TO_OVERRIDE["v3.3.4"]=a.extend({},d.METHODS_TO_OVERRIDE["v3.1"]),d.prototype={constructor:d,initOptions:function(b){return this.options=a.extend(!0,this.defaultOptions,b),this},holdThisInstance:function(){return d.addDialog(this),this},initModalStuff:function(){return this.setModal(this.createModal()).setModalDialog(this.createModalDialog()).setModalContent(this.createModalContent()).setModalHeader(this.createModalHeader()).setModalBody(this.createModalBody()).setModalFooter(this.createModalFooter()),this.getModal().append(this.getModalDialog()),this.getModalDialog().append(this.getModalContent()),this.getModalContent().append(this.getModalHeader()).append(this.getModalBody()).append(this.getModalFooter()),this},createModal:function(){var b=a('');return b.prop("id",this.getId()),b.attr("aria-labelledby",this.getId()+"_title"),b},getModal:function(){return this.$modal},setModal:function(a){return this.$modal=a,this},createModalDialog:function(){return a('')},getModalDialog:function(){return this.$modalDialog},setModalDialog:function(a){return this.$modalDialog=a,this},createModalContent:function(){return a('')},getModalContent:function(){return this.$modalContent},setModalContent:function(a){return this.$modalContent=a,this},createModalHeader:function(){return a('')},getModalHeader:function(){return this.$modalHeader},setModalHeader:function(a){return this.$modalHeader=a,this},createModalBody:function(){return a('')},getModalBody:function(){return this.$modalBody},setModalBody:function(a){return this.$modalBody=a,this},createModalFooter:function(){return a('')},getModalFooter:function(){return this.$modalFooter},setModalFooter:function(a){return this.$modalFooter=a,this},createDynamicContent:function(a){var b=null;return b="function"==typeof a?a.call(a,this):a,"string"==typeof b&&(b=this.formatStringContent(b)),b},formatStringContent:function(a){return this.options.nl2br?a.replace(/\r\n/g,"
    ").replace(/[\r\n]/g,"
    "):a},setData:function(a,b){return this.options.data[a]=b,this},getData:function(a){return this.options.data[a]},setId:function(a){return this.options.id=a,this},getId:function(){return this.options.id},getType:function(){return this.options.type},setType:function(a){return this.options.type=a,this.updateType(),this},updateType:function(){if(this.isRealized()){var a=[d.TYPE_DEFAULT,d.TYPE_INFO,d.TYPE_PRIMARY,d.TYPE_SUCCESS,d.TYPE_WARNING,d.TYPE_DANGER];this.getModal().removeClass(a.join(" ")).addClass(this.getType())}return this},getSize:function(){return this.options.size},setSize:function(a){return this.options.size=a,this.updateSize(),this},updateSize:function(){if(this.isRealized()){var b=this;this.getModal().removeClass(d.SIZE_NORMAL).removeClass(d.SIZE_SMALL).removeClass(d.SIZE_WIDE).removeClass(d.SIZE_LARGE),this.getModal().addClass(this.getSize()),this.getModalDialog().removeClass("modal-sm"),this.getSize()===d.SIZE_SMALL&&this.getModalDialog().addClass("modal-sm"),this.getModalDialog().removeClass("modal-lg"),this.getSize()===d.SIZE_WIDE&&this.getModalDialog().addClass("modal-lg"),a.each(this.options.buttons,function(c,d){var e=b.getButton(d.id),f=["btn-lg","btn-sm","btn-xs"],g=!1;if("string"==typeof d.cssClass){var h=d.cssClass.split(" ");a.each(h,function(b,c){-1!==a.inArray(c,f)&&(g=!0)})}g||(e.removeClass(f.join(" ")),e.addClass(b.getButtonSize()))})}return this},getCssClass:function(){return this.options.cssClass},setCssClass:function(a){return this.options.cssClass=a,this},getTitle:function(){return this.options.title},setTitle:function(a){return this.options.title=a,this.updateTitle(),this},updateTitle:function(){if(this.isRealized()){var a=null!==this.getTitle()?this.createDynamicContent(this.getTitle()):this.getDefaultText();this.getModalHeader().find("."+this.getNamespace("title")).html("").append(a).prop("id",this.getId()+"_title")}return this},getMessage:function(){return this.options.message},setMessage:function(a){return this.options.message=a,this.updateMessage(),this},updateMessage:function(){if(this.isRealized()){var a=this.createDynamicContent(this.getMessage());this.getModalBody().find("."+this.getNamespace("message")).html("").append(a)}return this},isClosable:function(){return this.options.closable},setClosable:function(a){return this.options.closable=a,this.updateClosable(),this},setCloseByBackdrop:function(a){return this.options.closeByBackdrop=a,this},canCloseByBackdrop:function(){return this.options.closeByBackdrop},setCloseByKeyboard:function(a){return this.options.closeByKeyboard=a,this},canCloseByKeyboard:function(){return this.options.closeByKeyboard},isAnimate:function(){return this.options.animate},setAnimate:function(a){return this.options.animate=a,this},updateAnimate:function(){return this.isRealized()&&this.getModal().toggleClass("fade",this.isAnimate()),this},getSpinicon:function(){return this.options.spinicon},setSpinicon:function(a){return this.options.spinicon=a,this},addButton:function(a){return this.options.buttons.push(a),this},addButtons:function(b){var c=this;return a.each(b,function(a,b){c.addButton(b)}),this},getButtons:function(){return this.options.buttons},setButtons:function(a){return this.options.buttons=a,this.updateButtons(),this},getButton:function(a){return"undefined"!=typeof this.indexedButtons[a]?this.indexedButtons[a]:null},getButtonSize:function(){return"undefined"!=typeof d.BUTTON_SIZES[this.getSize()]?d.BUTTON_SIZES[this.getSize()]:""},updateButtons:function(){return this.isRealized()&&(0===this.getButtons().length?this.getModalFooter().hide():this.getModalFooter().show().find("."+this.getNamespace("footer")).html("").append(this.createFooterButtons())),this},isAutodestroy:function(){return this.options.autodestroy},setAutodestroy:function(a){this.options.autodestroy=a},getDescription:function(){return this.options.description},setDescription:function(a){return this.options.description=a,this},setTabindex:function(a){return this.options.tabindex=a,this},getTabindex:function(){return this.options.tabindex},updateTabindex:function(){return this.isRealized()&&this.getModal().attr("tabindex",this.getTabindex()),this},getDefaultText:function(){return d.DEFAULT_TEXTS[this.getType()]},getNamespace:function(a){return d.NAMESPACE+"-"+a},createHeaderContent:function(){var b=a("
    ");return b.addClass(this.getNamespace("header")),b.append(this.createTitleContent()),b.prepend(this.createCloseButton()),b},createTitleContent:function(){var b=a("
    ");return b.addClass(this.getNamespace("title")),b},createCloseButton:function(){var b=a("
    ");b.addClass(this.getNamespace("close-button"));var c=a('');return c.append(this.options.closeIcon),b.append(c),b.on("click",{dialog:this},function(a){a.data.dialog.close()}),b},createBodyContent:function(){var b=a("
    ");return b.addClass(this.getNamespace("body")),b.append(this.createMessageContent()),b},createMessageContent:function(){var b=a("
    ");return b.addClass(this.getNamespace("message")),b},createFooterContent:function(){var b=a("
    ");return b.addClass(this.getNamespace("footer")),b},createFooterButtons:function(){var b=this,c=a("
    ");return c.addClass(this.getNamespace("footer-buttons")),this.indexedButtons={},a.each(this.options.buttons,function(a,e){e.id||(e.id=d.newGuid());var f=b.createButton(e);b.indexedButtons[e.id]=f,c.append(f)}),c},createButton:function(b){var c=a('');return c.prop("id",b.id),c.data("button",b),"undefined"!=typeof b.icon&&""!==a.trim(b.icon)&&c.append(this.createButtonIcon(b.icon)),"undefined"!=typeof b.label&&c.append(b.label),c.addClass("undefined"!=typeof b.cssClass&&""!==a.trim(b.cssClass)?b.cssClass:"btn-default"),"undefined"!=typeof b.hotkey&&(this.registeredButtonHotkeys[b.hotkey]=c),c.on("click",{dialog:this,$button:c,button:b},function(a){var b=a.data.dialog,c=a.data.$button,d=c.data("button");return d.autospin&&c.toggleSpin(!0),"function"==typeof d.action?d.action.call(c,b,a):void 0}),this.enhanceButton(c),"undefined"!=typeof b.enabled&&c.toggleEnable(b.enabled),c},enhanceButton:function(a){return a.dialog=this,a.toggleEnable=function(a){var b=this;return"undefined"!=typeof a?b.prop("disabled",!a).toggleClass("disabled",!a):b.prop("disabled",!b.prop("disabled")),b},a.enable=function(){var a=this;return a.toggleEnable(!0),a},a.disable=function(){var a=this;return a.toggleEnable(!1),a},a.toggleSpin=function(b){var c=this,d=c.dialog,e=c.find("."+d.getNamespace("button-icon"));return"undefined"==typeof b&&(b=!(a.find(".icon-spin").length>0)),b?(e.hide(),a.prepend(d.createButtonIcon(d.getSpinicon()).addClass("icon-spin"))):(e.show(),a.find(".icon-spin").remove()),c},a.spin=function(){var a=this;return a.toggleSpin(!0),a},a.stopSpin=function(){var a=this;return a.toggleSpin(!1),a},this},createButtonIcon:function(b){var c=a("");return c.addClass(this.getNamespace("button-icon")).addClass(b),c},enableButtons:function(b){return a.each(this.indexedButtons,function(a,c){c.toggleEnable(b)}),this},updateClosable:function(){return this.isRealized()&&this.getModalHeader().find("."+this.getNamespace("close-button")).toggle(this.isClosable()),this},onShow:function(a){return this.options.onshow=a,this},onShown:function(a){return this.options.onshown=a,this},onHide:function(a){return this.options.onhide=a,this},onHidden:function(a){return this.options.onhidden=a,this},isRealized:function(){return this.realized},setRealized:function(a){return this.realized=a,this},isOpened:function(){return this.opened},setOpened:function(a){return this.opened=a,this},handleModalEvents:function(){return this.getModal().on("show.bs.modal",{dialog:this},function(a){var b=a.data.dialog;if(b.setOpened(!0),b.isModalEvent(a)&&"function"==typeof b.options.onshow){var c=b.options.onshow(b);return c===!1&&b.setOpened(!1),c}}),this.getModal().on("shown.bs.modal",{dialog:this},function(a){var b=a.data.dialog;b.isModalEvent(a)&&"function"==typeof b.options.onshown&&b.options.onshown(b)}),this.getModal().on("hide.bs.modal",{dialog:this},function(a){var b=a.data.dialog;if(b.setOpened(!1),b.isModalEvent(a)&&"function"==typeof b.options.onhide){var c=b.options.onhide(b);return c===!1&&b.setOpened(!0),c}}),this.getModal().on("hidden.bs.modal",{dialog:this},function(b){var c=b.data.dialog;c.isModalEvent(b)&&"function"==typeof c.options.onhidden&&c.options.onhidden(c),c.isAutodestroy()&&(c.setRealized(!1),delete d.dialogs[c.getId()],a(this).remove()),d.moveFocus()}),this.handleModalBackdropEvent(),this.getModal().on("keyup",{dialog:this},function(a){27===a.which&&a.data.dialog.isClosable()&&a.data.dialog.canCloseByKeyboard()&&a.data.dialog.close()}),this.getModal().on("keyup",{dialog:this},function(b){var c=b.data.dialog;if("undefined"!=typeof c.registeredButtonHotkeys[b.which]){var d=a(c.registeredButtonHotkeys[b.which]);!d.prop("disabled")&&d.focus().trigger("click")}}),this},handleModalBackdropEvent:function(){return this.getModal().on("click",{dialog:this},function(b){a(b.target).hasClass("modal-backdrop")&&b.data.dialog.isClosable()&&b.data.dialog.canCloseByBackdrop()&&b.data.dialog.close()}),this},isModalEvent:function(a){return"undefined"!=typeof a.namespace&&"bs.modal"===a.namespace},makeModalDraggable:function(){return this.options.draggable&&(this.getModalHeader().addClass(this.getNamespace("draggable")).on("mousedown",{dialog:this},function(a){var b=a.data.dialog;b.draggableData.isMouseDown=!0;var c=b.getModalDialog().offset();b.draggableData.mouseOffset={top:a.clientY-c.top,left:a.clientX-c.left}}),this.getModal().on("mouseup mouseleave",{dialog:this},function(a){a.data.dialog.draggableData.isMouseDown=!1}),a("body").on("mousemove",{dialog:this},function(a){var b=a.data.dialog;b.draggableData.isMouseDown&&b.getModalDialog().offset({top:a.clientY-b.draggableData.mouseOffset.top,left:a.clientX-b.draggableData.mouseOffset.left})})),this},realize:function(){return this.initModalStuff(),this.getModal().addClass(d.NAMESPACE).addClass(this.getCssClass()),this.updateSize(),this.getDescription()&&this.getModal().attr("aria-describedby",this.getDescription()),this.getModalFooter().append(this.createFooterContent()),this.getModalHeader().append(this.createHeaderContent()),this.getModalBody().append(this.createBodyContent()),this.getModal().data("bs.modal",new c(this.getModal(),{backdrop:"static",keyboard:!1,show:!1})),this.makeModalDraggable(),this.handleModalEvents(),this.setRealized(!0),this.updateButtons(),this.updateType(),this.updateTitle(),this.updateMessage(),this.updateClosable(),this.updateAnimate(),this.updateSize(),this.updateTabindex(),this},open:function(){return!this.isRealized()&&this.realize(),this.getModal().modal("show"),this},close:function(){return!this.isRealized()&&this.realize(),this.getModal().modal("hide"),this}},d.prototype=a.extend(d.prototype,d.METHODS_TO_OVERRIDE[c.getModalVersion()]),d.newGuid=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)})},d.show=function(a){return new d(a).open()},d.alert=function(){var b={},c={type:d.TYPE_PRIMARY,title:null,message:null,closable:!1,draggable:!1,buttonLabel:d.DEFAULT_TEXTS.OK,buttonHotkey:null,callback:null};b="object"==typeof arguments[0]&&arguments[0].constructor==={}.constructor?a.extend(!0,c,arguments[0]):a.extend(!0,c,{message:arguments[0],callback:"undefined"!=typeof arguments[1]?arguments[1]:null});var e=new d(b);return e.setData("callback",b.callback),e.addButton({label:b.buttonLabel,hotkey:b.buttonHotkey,action:function(a){return"function"==typeof a.getData("callback")&&a.getData("callback").call(this,!0)===!1?!1:(a.setData("btnClicked",!0),a.close())}}),e.onHide("function"==typeof e.options.onhide?function(a){var b=!0;return!a.getData("btnClicked")&&a.isClosable()&&"function"==typeof a.getData("callback")&&(b=a.getData("callback")(!1)),b===!1?!1:b=this.onhide(a)}.bind({onhide:e.options.onhide}):function(a){var b=!0;return!a.getData("btnClicked")&&a.isClosable()&&"function"==typeof a.getData("callback")&&(b=a.getData("callback")(!1)),b}),e.open()},d.confirm=function(){var b={},c={type:d.TYPE_PRIMARY,title:null,message:null,closable:!1,draggable:!1,btnCancelLabel:d.DEFAULT_TEXTS.CANCEL,btnCancelClass:null,btnCancelHotkey:null,btnOKLabel:d.DEFAULT_TEXTS.OK,btnOKClass:null,btnOKHotkey:null,btnsOrder:d.defaultOptions.btnsOrder,callback:null};b="object"==typeof arguments[0]&&arguments[0].constructor==={}.constructor?a.extend(!0,c,arguments[0]):a.extend(!0,c,{message:arguments[0],callback:"undefined"!=typeof arguments[1]?arguments[1]:null}),null===b.btnOKClass&&(b.btnOKClass=["btn",b.type.split("-")[1]].join("-"));var e=new d(b);e.setData("callback",b.callback);var f=[{label:b.btnCancelLabel,cssClass:b.btnCancelClass,hotkey:b.btnCancelHotkey,action:function(a){return"function"==typeof a.getData("callback")&&a.getData("callback").call(this,!1)===!1?!1:a.close()}},{label:b.btnOKLabel,cssClass:b.btnOKClass,hotkey:b.btnOKHotkey,action:function(a){return"function"==typeof a.getData("callback")&&a.getData("callback").call(this,!0)===!1?!1:a.close()}}];return b.btnsOrder===d.BUTTONS_ORDER_OK_CANCEL&&f.reverse(),e.addButtons(f),e.open()},d.warning=function(a){return new d({type:d.TYPE_WARNING,message:a}).open()},d.danger=function(a){return new d({type:d.TYPE_DANGER,message:a}).open()},d.success=function(a){return new d({type:d.TYPE_SUCCESS,message:a}).open()},d}),!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.Chartist=b()}):"object"==typeof exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.9.8"};return function(a,b,c){"use strict";c.namespaces={svg:"http://www.w3.org/2000/svg",xmlns:"http://www.w3.org/2000/xmlns/",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",ct:"http://gionkunz.github.com/chartist-js/ct"},c.noop=function(a){return a},c.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},c.extend=function(a){a=a||{};var b=Array.prototype.slice.call(arguments,1);return b.forEach(function(b){for(var d in b)a[d]="object"!=typeof b[d]||null===b[d]||b[d]instanceof Array?b[d]:c.extend({},a[d],b[d])}),a},c.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},c.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},c.quantity=function(a){if("string"==typeof a){var b=/^(\d+)\s*(.*)$/g.exec(a);return{value:+b[1],unit:b[2]||void 0}}return{value:a}},c.querySelector=function(a){return a instanceof Node?a:b.querySelector(a)},c.times=function(a){return Array.apply(null,new Array(a))},c.sum=function(a,b){return a+(b?b:0)},c.mapMultiply=function(a){return function(b){return b*a}},c.mapAdd=function(a){return function(b){return b+a}},c.serialMap=function(a,b){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return c.times(e).forEach(function(c,e){var f=a.map(function(a){return a[e]});d[e]=b.apply(null,f)}),d},c.roundWithPrecision=function(a,b){var d=Math.pow(10,b||c.precision);return Math.round(a*d)/d},c.precision=8,c.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},c.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,b,c.escapingMap[b])},a))},c.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,c.escapingMap[b],b)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(b){}return a},c.createSvg=function(a,b,d,e){var f;return b=b||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS(c.namespaces.xmlns,"ct")}).forEach(function(b){a.removeChild(b)}),f=new c.Svg("svg").attr({width:b,height:d}).addClass(e).attr({style:"width: "+b+"; height: "+d+";"}),a.appendChild(f._node),f},c.normalizeData=function(a){if(a=a||{series:[],labels:[]},a.series=a.series||[],a.labels=a.labels||[],a.series.length>0&&0===a.labels.length){var b,d=c.getDataArray(a);b=d.every(function(a){return a instanceof Array})?Math.max.apply(null,d.map(function(a){return a.length})):d.length,a.labels=c.times(b).map(function(){return""})}return a},c.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;bf.high&&(f.high=c),h&&c0?f.low=0:(f.high=1,f.low=0)),f},c.isNum=function(a){return!isNaN(a)&&isFinite(a)},c.isFalseyButZero=function(a){return!a&&0!==a},c.getNumberOrUndefined=function(a){return isNaN(+a)?void 0:+a},c.getMultiValue=function(a,b){return c.isNum(a)?+a:a?a[b||"y"]||0:0},c.rho=function(a){function b(a,c){return a%c===0?c:b(c,a%c)}function c(a){return a*a+1}if(1===a)return a;var d,e=2,f=2;if(a%2===0)return 2;do e=c(e)%a,f=c(c(f))%a,d=b(Math.abs(e-f),a);while(1===d);return d},c.getBounds=function(a,b,d,e){var f,g,h,i=0,j={high:b.high,low:b.low};j.valueRange=j.high-j.low,j.oom=c.orderOfMagnitude(j.valueRange),j.step=Math.pow(10,j.oom),j.min=Math.floor(j.low/j.step)*j.step,j.max=Math.ceil(j.high/j.step)*j.step,j.range=j.max-j.min,j.numberOfSteps=Math.round(j.range/j.step);var k=c.projectLength(a,j.step,j),l=d>k,m=e?c.rho(j.range):0;if(e&&c.projectLength(a,1,j)>=d)j.step=1;else if(e&&m=d)j.step=m;else for(;;){if(l&&c.projectLength(a,j.step,j)<=d)j.step*=2;else{if(l||!(c.projectLength(a,j.step/2,j)>=d))break;if(j.step/=2,e&&j.step%1!==0){j.step*=2;break}}if(i++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}var n=2.221e-16;for(j.step=Math.max(j.step,n),g=j.min,h=j.max;g+j.step<=j.low;)g+=j.step;for(;h-j.step>=j.high;)h-=j.step;j.min=g,j.max=h,j.range=j.max-j.min;var o=[];for(f=j.min;f<=j.max;f+=j.step){var p=c.roundWithPrecision(f);p!==o[o.length-1]&&o.push(f)}return j.values=o,j},c.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},c.createChartRect=function(a,b,d){var e=!(!b.axisX&&!b.axisY),f=e?b.axisY.offset:0,g=e?b.axisX.offset:0,h=a.width()||c.quantity(b.width).value||0,i=a.height()||c.quantity(b.height).value||0,j=c.normalizePadding(b.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===b.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===b.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},c.createGrid=function(a,b,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",c.extend({type:"grid",axis:d,index:b,group:g,element:k},j))},c.createLabel=function(a,b,d,e,f,g,h,i,j,k,l){var m,n={};if(n[f.units.pos]=a+h[f.units.pos],n[f.counterUnits.pos]=h[f.counterUnits.pos],n[f.units.len]=b,n[f.counterUnits.len]=Math.max(0,g-10),k){var o=''+e[d]+"";m=i.foreignObject(o,c.extend({style:"overflow: visible;"},n))}else m=i.elem("text",n,j.join(" ")).text(e[d]);l.emit("draw",c.extend({type:"label",axis:f,index:d,group:i,element:m,text:e[d]},n))},c.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},c.optionsProvider=function(b,d,e){function f(b){var f=h;if(h=c.extend({},j),d)for(i=0;i=2&&a[h]<=a[h-2]&&(g=!0),g&&(f.push({pathCoordinates:[],valueData:[]}),g=!1),f[f.length-1].pathCoordinates.push(a[h],a[h+1]),f[f.length-1].valueData.push(b[h/2]));return f}}(window,document,a),function(a,b,c){"use strict";c.Interpolation={},c.Interpolation.none=function(a){var b={fillHoles:!1};return a=c.extend({},b,a),function(b,d){for(var e=new c.Svg.Path,f=!0,g=0;g1){var i=[];return h.forEach(function(a){i.push(f(a.pathCoordinates,a.valueData))}),c.Svg.Path.join(i)}if(b=h[0].pathCoordinates,g=h[0].valueData,b.length<=4)return c.Interpolation.none()(b,g);for(var j,k=(new c.Svg.Path).move(b[0],b[1],!1,g[0]),l=0,m=b.length;m-2*!j>l;l+=2){var n=[{x:+b[l-2],y:+b[l-1]},{x:+b[l],y:+b[l+1]},{x:+b[l+2],y:+b[l+3]},{x:+b[l+4],y:+b[l+5]}];j?l?m-4===l?n[3]={x:+b[0],y:+b[1]}:m-2===l&&(n[2]={x:+b[0],y:+b[1]},n[3]={x:+b[2],y:+b[3]}):n[0]={x:+b[m-2],y:+b[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+b[l],y:+b[l+1]}),k.curve(d*(-n[0].x+6*n[1].x+n[2].x)/6+e*n[2].x,d*(-n[0].y+6*n[1].y+n[2].y)/6+e*n[2].y,d*(n[1].x+6*n[2].x-n[3].x)/6+e*n[2].x,d*(n[1].y+6*n[2].y-n[3].y)/6+e*n[2].y,n[2].x,n[2].y,!1,g[(l+2)/2])}return k}return c.Interpolation.none()([])}},c.Interpolation.monotoneCubic=function(a){var b={fillHoles:!1};return a=c.extend({},b,a),function d(b,e){var f=c.splitIntoSegments(b,e,{fillHoles:a.fillHoles,increasingX:!0});if(f.length){if(f.length>1){var g=[];return f.forEach(function(a){g.push(d(a.pathCoordinates,a.valueData))}),c.Svg.Path.join(g)}if(b=f[0].pathCoordinates,e=f[0].valueData,b.length<=4)return c.Interpolation.none()(b,e);var h,i,j=[],k=[],l=b.length/2,m=[],n=[],o=[],p=[];for(h=0;l>h;h++)j[h]=b[2*h],k[h]=b[2*h+1];for(h=0;l-1>h;h++)o[h]=k[h+1]-k[h],p[h]=j[h+1]-j[h],n[h]=o[h]/p[h];for(m[0]=n[0],m[l-1]=n[l-2],h=1;l-1>h;h++)0===n[h]||0===n[h-1]||n[h-1]>0!=n[h]>0?m[h]=0:(m[h]=3*(p[h-1]+p[h])/((2*p[h]+p[h-1])/n[h-1]+(p[h]+2*p[h-1])/n[h]),isFinite(m[h])||(m[h]=0));for(i=(new c.Svg.Path).move(j[0],k[0],!1,e[0]),h=0;l-1>h;h++)i.curve(j[h]+p[h]/3,k[h]+m[h]*p[h]/3,j[h+1]-p[h]/3,k[h+1]-m[h+1]*p[h]/3,j[h+1],k[h+1],!1,e[h+1]);return i}return c.Interpolation.none()([])}},c.Interpolation.step=function(a){var b={postpone:!0,fillHoles:!1};return a=c.extend({},b,a),function(b,d){for(var e,f,g,h=new c.Svg.Path,i=0;i1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(c){var h=i.elem("path",{d:c.stringify()},a.classNames.area,!0);this.eventEmitter.emit("draw",{type:"area",values:b.normalized[g],path:c.clone(),series:f,seriesIndex:g,axisX:d,axisY:e,chartRect:j,index:g,group:i,element:h})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:e.bounds,chartRect:j,axisX:d,axisY:e,svg:this.svg,options:a})}function e(a,b,d,e){c.Line["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Line=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a){this.data=c.normalizeData(this.data);var b,d={raw:this.data,normalized:a.distributeSeries?c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y").map(function(a){return[a]}):c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y")};this.svg=c.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var e=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);if(a.stackBars&&0!==d.normalized.length){var i=c.serialMap(d.normalized,function(){return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+(b&&b.x)||0,y:a.y+(b&&b.y)||0}},{x:0,y:0})});b=c.getHighLow([i],c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y")}else b=c.getHighLow(d.normalized,c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y");b.high=+a.high||(0===a.high?0:b.high),b.low=+a.low||(0===a.low?0:b.low);var j,k,l,m,n,o=c.createChartRect(this.svg,a,f.padding);k=a.distributeSeries&&a.stackBars?d.raw.labels.slice(0,1):d.raw.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new c.AutoScaleAxis(c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})):a.axisX.type.call(c,c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})),l=n=void 0===a.axisY.type?new c.StepAxis(c.Axis.units.y,d,o,{ticks:k}):a.axisY.type.call(c,c.Axis.units.y,d,o,a.axisY)):(l=m=void 0===a.axisX.type?new c.StepAxis(c.Axis.units.x,d,o,{ticks:k}):a.axisX.type.call(c,c.Axis.units.x,d,o,a.axisX),j=n=void 0===a.axisY.type?new c.AutoScaleAxis(c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})):a.axisY.type.call(c,c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),d.raw.series.forEach(function(b,e){var f,h,i=e-(d.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/d.normalized.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/d.normalized[e].length/2,h=g.elem("g"),h.attr({"ct:series-name":b.name,"ct:meta":c.serialize(b.meta)}),h.addClass([a.classNames.series,b.className||a.classNames.series+"-"+c.alphaNumerate(e)].join(" ")),d.normalized[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,d.normalized[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,d.normalized[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,d.normalized[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,d.normalized[e])},l instanceof c.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],!a.stackBars||"accumulate"!==a.stackMode&&a.stackMode?(v[l.counterUnits.pos+"1"]=p,v[l.counterUnits.pos+"2"]=r[l.counterUnits.pos]):(v[l.counterUnits.pos+"1"]=t,v[l.counterUnits.pos+"2"]=q[k]),v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1),s=h.elem("line",v,a.classNames.bar).attr({"ct:value":[g.x,g.y].filter(c.isNum).join(","),"ct:meta":c.getMetaData(b,k)}),this.eventEmitter.emit("draw",c.extend({type:"bar",value:g,index:k,meta:c.getMetaData(b,k),series:b,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function e(a,b,d,e){c.Bar["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,stackMode:"accumulate",horizontalBars:!1,distributeSeries:!1,reverseData:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Bar=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function e(a){this.data=c.normalizeData(this.data);var b,e,f,h,i,j=[],k=a.startAngle,l=c.getDataArray(this.data,a.reverseData);this.svg=c.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=c.createChartRect(this.svg,a,g.padding),f=Math.min(e.width()/2,e.height()/2),i=a.total||l.reduce(function(a,b){return a+b},0);var m=c.quantity(a.donutWidth);"%"===m.unit&&(m.value*=f/100),f-=a.donut?m.value/2:0,h="outside"===a.labelPosition||a.donut?f:"center"===a.labelPosition?0:f/2,h+=a.labelOffset;var n={x:e.x1+e.width()/2,y:e.y2+e.height()/2},o=1===this.data.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;a.showLabel&&(b=this.svg.elem("g",null,null,!0));for(var p=0;p=359.99&&(r=s+359.99);var t=c.polarToCartesian(n.x,n.y,f,s),u=c.polarToCartesian(n.x,n.y,f,r),v=new c.Svg.Path(!a.donut).move(u.x,u.y).arc(f,f,0,r-k>180,0,t.x,t.y);a.donut||v.line(n.x,n.y);var w=j[p].elem("path",{d:v.stringify()},a.donut?a.classNames.sliceDonut:a.classNames.slicePie);if(w.attr({"ct:value":l[p],"ct:meta":c.serialize(q.meta)}),a.donut&&w.attr({style:"stroke-width: "+m.value+"px"}),this.eventEmitter.emit("draw",{type:"slice",value:l[p],totalDataSum:i,index:p,meta:q.meta,series:q,group:j[p],element:w,path:v.clone(),center:n,radius:f,startAngle:k,endAngle:r}),a.showLabel){var x=c.polarToCartesian(n.x,n.y,h,k+(r-k)/2),y=a.labelInterpolationFnc(this.data.labels&&!c.isFalseyButZero(this.data.labels[p])?this.data.labels[p]:l[p],p);if(y||0===y){var z=b.elem("text",{dx:x.x,dy:x.y,"text-anchor":d(n,x,a.labelDirection)},a.classNames.label).text(""+y);this.eventEmitter.emit("draw",{type:"label",index:p,group:b,element:z,text:""+y,x:x.x,y:x.y})}}k=r}this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function f(a,b,d,e){c.Pie["super"].constructor.call(this,a,b,g,c.extend({},g,d),e)}var g={width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:c.noop,labelDirection:"neutral",reverseData:!1,ignoreEmptyValues:!1};c.Pie=c.Base.extend({constructor:f,createChart:e,determineAnchorPosition:d})}(window,document,a),a}),!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.returnExportsGlobal=b()}):"object"==typeof exports?module.exports=b():a["Chartist.plugins.ctAxisTitle"]=b()}(this,function(){return function(a,b,c){"use strict";var d={axisTitle:"",axisClass:"ct-axis-title",offset:{x:0,y:0},textAnchor:"middle",flipText:!1},e={xAxis:d,yAxis:d};c.plugins=c.plugins||{},c.plugins.ctAxisTitle=function(a){return a=c.extend({},e,a),function(b){b.on("created",function(b){if(!a.axisX.axisTitle&&!a.axisY.axisTitle)throw new Error("ctAxisTitle plugin - You must provide at least one axis title");if(!b.axisX&&!b.axisY)throw new Error("ctAxisTitle plugin can only be used on charts that have at least one axis");var d,e,f;if(a.axisX.axisTitle&&b.axisX&&(d=b.axisX.axisLength/2+b.options.axisX.offset+b.options.chartPadding.left,e=b.options.chartPadding.top,"end"===b.options.axisX.position&&(e+=b.axisY.axisLength),f=new c.Svg("text"),f.addClass(a.axisX.axisClass),f.text(a.axisX.axisTitle),f.attr({x:d+a.axisX.offset.x,y:e+a.axisX.offset.y,"text-anchor":a.axisX.textAnchor}),b.svg.append(f,!0)),a.axisY.axisTitle&&b.axisY){d=0,e=b.axisY.axisLength/2+b.options.chartPadding.top,"end"===b.options.axisY.position&&(d=b.axisX.axisLength);var g="rotate("+(a.axisY.flipTitle?-90:90)+", "+d+", "+e+")";f=new c.Svg("text"),f.addClass(a.axisY.axisClass),f.text(a.axisY.axisTitle),f.attr({x:d+a.axisY.offset.x,y:e+a.axisY.offset.y,transform:g,"text-anchor":a.axisY.textAnchor}),b.svg.append(f,!0)}})}}}(window,document,Chartist),Chartist.plugins.ctAxisTitle}),!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.returnExportsGlobal=b()}):"object"==typeof exports?module.exports=b():a["Chartist.plugins.ctBarLabels"]=b()}(this,function(){return function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.returnExportsGlobal=b()}):"object"==typeof exports?module.exports=b():a["Chartist.plugins.ctBarLabels"]=b()}(this,function(){function a(a){if(a.options.horizontalBars&&a.options.axisX&&a.options.axisX.high)return a.options.axisX.high;if(!a.options.horizontalBars&&a.options.axisY&&a.options.axisY.high)return a.options.axisY.high;if(a.options.high)return a.options.high;if(a.data&&a.data.series&&a.data.series.length>0){var b=a.data.series;return b[0].constructor===Array&&(b=b.reduce(function(a,b){return a.concat(b)})),Math.max.apply(null,b)}}function b(a,b,c,d){return a&&b&&c?d/c*100>a?b.aboveLabelClass:b.belowLabelClass:""}function c(a,b,c,d){if(!a)return{};var e=a({high:b,value:c,threshold:d}),f={};return e.labelOffset&&(f.labelOffset=e.labelOffset,e.labelOffset.x&&(f.labelOffset.x=e.labelOffset.x),e.labelOffset.y&&(f.labelOffset.y=e.labelOffset.y)),e.textAnchor&&(f.textAnchor=e.textAnchor),f}return function(d,e,f){"use strict";var g={labelClass:"ct-label",labelInterpolationFnc:f.noop,labelPositionFnc:void 0,showZeroLabels:!1,includeIndexClass:!1,thresholdPercentage:30,thresholdOptions:{belowLabelClass:"ct-label-below",aboveLabelClass:"ct-label-above"}},h={labelOffset:{x:2,y:4},textAnchor:"start"},i={labelOffset:{x:0,y:-2},textAnchor:"middle"};f.plugins=f.plugins||{},f.plugins.ctBarLabels=function(d){return function(e){if(e instanceof f.Bar){d=f.extend({},g,d),d=e.options.horizontalBars?f.extend({},h,d):f.extend({},i,d);var j=a(e);e.on("draw",function(a){if("bar"===a.type){var g=void 0===a.value.x?a.value.y:a.value.x,h=d.includeIndexClass?["ct-bar-label-i-",a.seriesIndex,"-",a.index].join(""):"",i=b(d.thresholdPercentage,d.thresholdOptions,j,g),k=c(d.labelPositionFnc,j,g,d.thresholdPercentage);d=f.extend({},d,k),(d.showZeroLabels||!d.showZeroLabels&&0!=g)&&a.group.elem("text",{x:(d.startAtBase&&e.options.horizontalBars?a.x1:a.x2)+d.labelOffset.x,y:(d.startAtBase&&!e.options.horizontalBars?a.y1:a.y2)+d.labelOffset.y,style:"text-anchor: "+d.textAnchor},[d.labelClass,h,i].join(" ")).text(d.labelInterpolationFnc(g))}})}}},f.plugins.ctBarLabels.InsetLabelsPositionHorizontal=function(a){if(a.high&&a.value&&a.threshold){var b=a.value/a.high*100>a.threshold;return b?{labelOffset:{x:-2,y:4},textAnchor:"end"}:{labelOffset:{x:2,y:4},textAnchor:"start"}}}}(window,document,Chartist),Chartist.plugins.ctBarLabels}),Chartist.plugins.ctBarLabels}),!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.returnExportsGlobal=b()}):"object"==typeof exports?module.exports=b():a["Chartist.plugins.ctPointLabels"]=b()}(this,function(){return function(a,b,c){"use strict";var d={labelClass:"ct-label",labelOffset:{x:0,y:-10},textAnchor:"middle",labelInterpolationFnc:c.noop};c.plugins=c.plugins||{},c.plugins.ctPointLabels=function(a){return a=c.extend({},d,a),function(b){b instanceof c.Line&&b.on("draw",function(b){"point"===b.type&&b.group.elem("text",{x:b.x+a.labelOffset.x,y:b.y+a.labelOffset.y,style:"text-anchor: "+a.textAnchor},a.labelClass).text(a.labelInterpolationFnc(void 0===b.value.x?b.value.y:b.value.x+", "+b.value.y))})}}}(window,document,Chartist),Chartist.plugins.ctPointLabels}),!function(a,b){"function"==typeof define&&define.amd?define(["chartist"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("chartist")):a["Chartist.plugins.tooltips"]=b(Chartist)}(this,function(a){return function(a,b,c){"use strict";function d(a){f(a,"tooltip-show")||(a.className=a.className+" tooltip-show")}function e(a){var b=new RegExp("tooltip-show\\s*","gi");a.className=a.className.replace(b,"").trim()}function f(a,b){return(" "+a.getAttribute("class")+" ").indexOf(" "+b+" ")>-1}function g(a,b){do a=a.nextSibling;while(a&&!f(a,b));return a}function h(a){return a.innerText||a.textContent}var i={currency:void 0,tooltipOffset:{x:0,y:-20},appendToBody:!1,"class":void 0,pointClass:"ct-point"};c.plugins=c.plugins||{},c.plugins.tooltip=function(a){return a=c.extend({},i,a),function(i){function j(a,b,c){m.addEventListener(a,function(a){b&&!f(a.target,b)||c(a)})}function k(b){o=o||n.offsetHeight,p=p||n.offsetWidth,a.appendToBody?(n.style.top=b.pageY-o+a.tooltipOffset.y+"px",n.style.left=b.pageX-p/2+a.tooltipOffset.x+"px"):(n.style.top=(b.layerY||b.offsetY)-o+a.tooltipOffset.y+"px",n.style.left=(b.layerX||b.offsetX)-p/2+a.tooltipOffset.x+"px"); + +}var l=a.pointClass;i instanceof c.Bar?l="ct-bar":i instanceof c.Pie&&(l=i.options.donut?"ct-slice-donut":"ct-slice-pie");var m=i.container,n=m.querySelector(".chartist-tooltip");n||(n=b.createElement("div"),n.className=a["class"]?"chartist-tooltip "+a["class"]:"chartist-tooltip",a.appendToBody?b.body.appendChild(n):m.appendChild(n));var o=n.offsetHeight,p=n.offsetWidth;e(n),j("mouseover",l,function(e){var f=e.target,j="",l=i instanceof c.Pie?f:f.parentNode,m=l?f.parentNode.getAttribute("ct:meta")||f.parentNode.getAttribute("ct:series-name"):"",q=f.getAttribute("ct:meta")||m||"",r=!!q,s=f.getAttribute("ct:value");if(a.transformTooltipTextFnc&&"function"==typeof a.transformTooltipTextFnc&&(s=a.transformTooltipTextFnc(s)),a.tooltipFnc&&"function"==typeof a.tooltipFnc)j=a.tooltipFnc(q,s);else{if(a.metaIsHTML){var t=b.createElement("textarea");t.innerHTML=q,q=t.value}if(q=''+q+"",r)j+=q+"
    ";else if(i instanceof c.Pie){var u=g(f,"ct-label");u&&(j+=h(u)+"
    ")}s&&(a.currency&&(s=a.currency+s.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g,"$1,")),s=''+s+"",j+=s)}j&&(n.innerHTML=j,k(e),d(n),o=n.offsetHeight,p=n.offsetWidth)}),j("mouseout",l,function(){e(n)}),j("mousemove",null,function(a){k(a)})}}}(window,document,a),a.plugins.tooltips}),"undefined"==typeof jQuery)throw new Error("Jasny Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}void 0===a.support.transition&&(a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()}))}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.state=null,this.placement=null,this.options.recalc&&(this.calcClone(),a(window).on("resize",a.proxy(this.recalc,this))),this.options.autohide&&a(document).on("click",a.proxy(this.autohide,this)),this.options.toggle&&this.toggle(),this.options.disablescrolling&&(this.options.disableScrolling=this.options.disablescrolling,delete this.options.disablescrolling)};b.DEFAULTS={toggle:!0,placement:"auto",autohide:!0,recalc:!0,disableScrolling:!0},b.prototype.offset=function(){switch(this.placement){case"left":case"right":return this.$element.outerWidth();case"top":case"bottom":return this.$element.outerHeight()}},b.prototype.calcPlacement=function(){function b(a,b){if("auto"===e.css(b))return a;if("auto"===e.css(a))return b;var c=parseInt(e.css(a),10),d=parseInt(e.css(b),10);return c>d?b:a}if("auto"!==this.options.placement)return void(this.placement=this.options.placement);this.$element.hasClass("in")||this.$element.css("visiblity","hidden !important").addClass("in");var c=a(window).width()/this.$element.width(),d=a(window).height()/this.$element.height(),e=this.$element;this.placement=c>=d?b("left","right"):b("top","bottom"),"hidden !important"===this.$element.css("visibility")&&this.$element.removeClass("in").css("visiblity","")},b.prototype.opposite=function(a){switch(a){case"top":return"bottom";case"left":return"right";case"bottom":return"top";case"right":return"left"}},b.prototype.getCanvasElements=function(){var b=this.options.canvas?a(this.options.canvas):this.$element,c=b.find("*").filter(function(){return"fixed"===a(this).css("position")}).not(this.options.exclude);return b.add(c)},b.prototype.slide=function(b,c,d){if(!a.support.transition){var e={};return e[this.placement]="+="+c,b.animate(e,350,d)}var f=this.placement,g=this.opposite(f);b.each(function(){"auto"!==a(this).css(f)&&a(this).css(f,(parseInt(a(this).css(f),10)||0)+c),"auto"!==a(this).css(g)&&a(this).css(g,(parseInt(a(this).css(g),10)||0)-c)}),this.$element.one(a.support.transition.end,d).emulateTransitionEnd(350)},b.prototype.disableScrolling=function(){var b=a("body").width(),c="padding-"+this.opposite(this.placement);if(void 0===a("body").data("offcanvas-style")&&a("body").data("offcanvas-style",a("body").attr("style")||""),a("body").css("overflow","hidden"),a("body").width()>b){var d=parseInt(a("body").css(c),10)+a("body").width()-b;setTimeout(function(){a("body").css(c,d)},1)}},b.prototype.show=function(){if(!this.state){var b=a.Event("show.bs.offcanvas");if(this.$element.trigger(b),!b.isDefaultPrevented()){this.state="slide-in",this.calcPlacement();var c=this.getCanvasElements(),d=this.placement,e=this.opposite(d),f=this.offset();-1!==c.index(this.$element)&&(a(this.$element).data("offcanvas-style",a(this.$element).attr("style")||""),this.$element.css(d,-1*f),this.$element.css(d)),c.addClass("canvas-sliding").each(function(){void 0===a(this).data("offcanvas-style")&&a(this).data("offcanvas-style",a(this).attr("style")||""),"static"===a(this).css("position")&&a(this).css("position","relative"),"auto"!==a(this).css(d)&&"0px"!==a(this).css(d)||"auto"!==a(this).css(e)&&"0px"!==a(this).css(e)||a(this).css(d,0)}),this.options.disableScrolling&&this.disableScrolling();var g=function(){"slide-in"==this.state&&(this.state="slid",c.removeClass("canvas-sliding").addClass("canvas-slid"),this.$element.trigger("shown.bs.offcanvas"))};setTimeout(a.proxy(function(){this.$element.addClass("in"),this.slide(c,f,a.proxy(g,this))},this),1)}}},b.prototype.hide=function(){if("slid"===this.state){var b=a.Event("hide.bs.offcanvas");if(this.$element.trigger(b),!b.isDefaultPrevented()){this.state="slide-out";var c=a(".canvas-slid"),d=(this.placement,-1*this.offset()),e=function(){"slide-out"==this.state&&(this.state=null,this.placement=null,this.$element.removeClass("in"),c.removeClass("canvas-sliding"),c.add(this.$element).add("body").each(function(){a(this).attr("style",a(this).data("offcanvas-style")).removeData("offcanvas-style")}),this.$element.trigger("hidden.bs.offcanvas"))};c.removeClass("canvas-slid").addClass("canvas-sliding"),setTimeout(a.proxy(function(){this.slide(c,d,a.proxy(e,this))},this),1)}}},b.prototype.toggle=function(){"slide-in"!==this.state&&"slide-out"!==this.state&&this["slid"===this.state?"hide":"show"]()},b.prototype.calcClone=function(){this.$calcClone=this.$element.clone().html("").addClass("offcanvas-clone").removeClass("in").appendTo(a("body"))},b.prototype.recalc=function(){if("none"!==this.$calcClone.css("display")&&("slid"===this.state||"slide-in"===this.state)){this.state=null,this.placement=null;var b=this.getCanvasElements();this.$element.removeClass("in"),b.removeClass("canvas-slid"),b.add(this.$element).add("body").each(function(){a(this).attr("style",a(this).data("offcanvas-style")).removeData("offcanvas-style")})}},b.prototype.autohide=function(b){0===a(b.target).closest(this.$element).length&&this.hide()};var c=a.fn.offcanvas;a.fn.offcanvas=function(c){return this.each(function(){var d=a(this),e=d.data("bs.offcanvas"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.offcanvas",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.offcanvas.Constructor=b,a.fn.offcanvas.noConflict=function(){return a.fn.offcanvas=c,this},a(document).on("click.bs.offcanvas.data-api","[data-toggle=offcanvas]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.offcanvas"),h=g?"toggle":d.data();b.stopPropagation(),g?g.toggle():f.offcanvas(h)})}(window.jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.$element.on("click.bs.rowlink","td:not(.rowlink-skip)",a.proxy(this.click,this))};b.DEFAULTS={target:"a"},b.prototype.click=function(b){var c=a(b.currentTarget).closest("tr").find(this.options.target)[0];if(a(b.target)[0]!==c)if(b.preventDefault(),c.click)c.click();else if(document.createEvent){var d=document.createEvent("MouseEvents");d.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),c.dispatchEvent(d)}};var c=a.fn.rowlink;a.fn.rowlink=function(c){return this.each(function(){var d=a(this),e=d.data("bs.rowlink");e||d.data("bs.rowlink",e=new b(this,c))})},a.fn.rowlink.Constructor=b,a.fn.rowlink.noConflict=function(){return a.fn.rowlink=c,this},a(document).on("click.bs.rowlink.data-api",'[data-link="row"]',function(b){if(0===a(b.target).closest(".rowlink-skip").length){var c=a(this);c.data("bs.rowlink")||(c.rowlink(c.data()),a(b.target).trigger("click.bs.rowlink"))}})}(window.jQuery),+function(a){"use strict";var b=void 0!==window.orientation,c=navigator.userAgent.toLowerCase().indexOf("android")>-1,d="Microsoft Internet Explorer"==window.navigator.appName,e=function(b,d){c||(this.$element=a(b),this.options=a.extend({},e.DEFAULTS,d),this.mask=String(this.options.mask),this.init(),this.listen(),this.checkVal())};e.DEFAULTS={mask:"",placeholder:"_",definitions:{9:"[0-9]",a:"[A-Za-z]",w:"[A-Za-z0-9]","*":"."}},e.prototype.init=function(){var b=this.options.definitions,c=this.mask.length;this.tests=[],this.partialPosition=this.mask.length,this.firstNonMaskPos=null,a.each(this.mask.split(""),a.proxy(function(a,d){"?"==d?(c--,this.partialPosition=a):b[d]?(this.tests.push(new RegExp(b[d])),null===this.firstNonMaskPos&&(this.firstNonMaskPos=this.tests.length-1)):this.tests.push(null)},this)),this.buffer=a.map(this.mask.split(""),a.proxy(function(a){return"?"!=a?b[a]?this.options.placeholder:a:void 0},this)),this.focusText=this.$element.val(),this.$element.data("rawMaskFn",a.proxy(function(){return a.map(this.buffer,function(a,b){return this.tests[b]&&a!=this.options.placeholder?a:null}).join("")},this))},e.prototype.listen=function(){if(!this.$element.attr("readonly")){var b=(d?"paste":"input")+".mask";this.$element.on("unmask.bs.inputmask",a.proxy(this.unmask,this)).on("focus.bs.inputmask",a.proxy(this.focusEvent,this)).on("blur.bs.inputmask",a.proxy(this.blurEvent,this)).on("keydown.bs.inputmask",a.proxy(this.keydownEvent,this)).on("keypress.bs.inputmask",a.proxy(this.keypressEvent,this)).on(b,a.proxy(this.pasteEvent,this))}},e.prototype.caret=function(a,b){if(0!==this.$element.length){if("number"==typeof a)return b="number"==typeof b?b:a,this.$element.each(function(){if(this.setSelectionRange)this.setSelectionRange(a,b);else if(this.createTextRange){var c=this.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select()}});if(this.$element[0].setSelectionRange)a=this.$element[0].selectionStart,b=this.$element[0].selectionEnd;else if(document.selection&&document.selection.createRange){var c=document.selection.createRange();a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length}return{begin:a,end:b}}},e.prototype.seekNext=function(a){for(var b=this.mask.length;++a<=b&&!this.tests[a];);return a},e.prototype.seekPrev=function(a){for(;--a>=0&&!this.tests[a];);return a},e.prototype.shiftL=function(a,b){var c=this.mask.length;if(!(0>a)){for(var d=a,e=this.seekNext(b);c>d;d++)if(this.tests[d]){if(!(c>e&&this.tests[d].test(this.buffer[e])))break;this.buffer[d]=this.buffer[e],this.buffer[e]=this.options.placeholder,e=this.seekNext(e)}this.writeBuffer(),this.caret(Math.max(this.firstNonMaskPos,a))}},e.prototype.shiftR=function(a){for(var b=this.mask.length,c=a,d=this.options.placeholder;b>c;c++)if(this.tests[c]){var e=this.seekNext(c),f=this.buffer[c];if(this.buffer[c]=d,!(b>e&&this.tests[e].test(f)))break;d=f}},e.prototype.unmask=function(){this.$element.unbind(".mask").removeData("inputmask")},e.prototype.focusEvent=function(){this.focusText=this.$element.val();var a=this.mask.length,b=this.checkVal();this.writeBuffer();var c=this,d=function(){b==a?c.caret(0,b):c.caret(b)};d(),setTimeout(d,50)},e.prototype.blurEvent=function(){this.checkVal(),this.$element.val()!==this.focusText&&this.$element.trigger("change")},e.prototype.keydownEvent=function(a){var c=a.which;if(8==c||46==c||b&&127==c){var d=this.caret(),e=d.begin,f=d.end;return f-e===0&&(e=46!=c?this.seekPrev(e):f=this.seekNext(e-1),f=46==c?this.seekNext(f):f),this.clearBuffer(e,f),this.shiftL(e,f-1),!1}return 27==c?(this.$element.val(this.focusText),this.caret(0,this.checkVal()),!1):void 0},e.prototype.keypressEvent=function(a){var b=this.mask.length,c=a.which,d=this.caret();if(a.ctrlKey||a.altKey||a.metaKey||32>c)return!0;if(c){d.end-d.begin!==0&&(this.clearBuffer(d.begin,d.end),this.shiftL(d.begin,d.end-1));var e=this.seekNext(d.begin-1);if(b>e){var f=String.fromCharCode(c);if(this.tests[e].test(f)){this.shiftR(e),this.buffer[e]=f,this.writeBuffer();var g=this.seekNext(e);this.caret(g)}}return!1}},e.prototype.pasteEvent=function(){var a=this;setTimeout(function(){a.caret(a.checkVal(!0))},0)},e.prototype.clearBuffer=function(a,b){for(var c=this.mask.length,d=a;b>d&&c>d;d++)this.tests[d]&&(this.buffer[d]=this.options.placeholder)},e.prototype.writeBuffer=function(){return this.$element.val(this.buffer.join("")).val()},e.prototype.checkVal=function(a){for(var b=this.mask.length,c=this.$element.val(),d=-1,e=0,f=0;b>e;e++)if(this.tests[e]){for(this.buffer[e]=this.options.placeholder;f++c.length)break}else this.buffer[e]==c.charAt(f)&&e!=this.partialPosition&&(f++,d=e);return!a&&d+1=this.partialPosition)&&(this.writeBuffer(),a||this.$element.val(this.$element.val().substring(0,d+1))),this.partialPosition?e:this.firstNonMaskPos};var f=a.fn.inputmask;a.fn.inputmask=function(b){return this.each(function(){var c=a(this),d=c.data("bs.inputmask");d||c.data("bs.inputmask",d=new e(this,b))})},a.fn.inputmask.Constructor=e,a.fn.inputmask.noConflict=function(){return a.fn.inputmask=f,this},a(document).on("focus.bs.inputmask.data-api","[data-mask]",function(){var b=a(this);b.data("bs.inputmask")||b.inputmask(b.data())})}(window.jQuery),+function(a){"use strict";var b="Microsoft Internet Explorer"==window.navigator.appName,c=function(b,c){if(this.$element=a(b),this.$input=this.$element.find(":file"),0!==this.$input.length){this.name=this.$input.attr("name")||c.name,this.$hidden=this.$element.find('input[type=hidden][name="'+this.name+'"]'),0===this.$hidden.length&&(this.$hidden=a('').insertBefore(this.$input)),this.$preview=this.$element.find(".fileinput-preview");var d=this.$preview.css("height");"inline"!==this.$preview.css("display")&&"0px"!==d&&"none"!==d&&this.$preview.css("line-height",d),this.original={exists:this.$element.hasClass("fileinput-exists"),preview:this.$preview.html(),hiddenVal:this.$hidden.val()},this.listen()}};c.prototype.listen=function(){this.$input.on("change.bs.fileinput",a.proxy(this.change,this)),a(this.$input[0].form).on("reset.bs.fileinput",a.proxy(this.reset,this)),this.$element.find('[data-trigger="fileinput"]').on("click.bs.fileinput",a.proxy(this.trigger,this)),this.$element.find('[data-dismiss="fileinput"]').on("click.bs.fileinput",a.proxy(this.clear,this))},c.prototype.change=function(b){var c=void 0===b.target.files?b.target&&b.target.value?[{name:b.target.value.replace(/^.+\\/,"")}]:[]:b.target.files;if(b.stopPropagation(),0===c.length)return void this.clear();this.$hidden.val(""),this.$hidden.attr("name",""),this.$input.attr("name",this.name);var d=c[0];if(this.$preview.length>0&&("undefined"!=typeof d.type?d.type.match(/^image\/(gif|png|jpeg)$/):d.name.match(/\.(gif|png|jpe?g)$/i))&&"undefined"!=typeof FileReader){var e=new FileReader,f=this.$preview,g=this.$element;e.onload=function(b){var e=a("");e[0].src=b.target.result,c[0].result=b.target.result,g.find(".fileinput-filename").text(d.name),"none"!=f.css("max-height")&&e.css("max-height",parseInt(f.css("max-height"),10)-parseInt(f.css("padding-top"),10)-parseInt(f.css("padding-bottom"),10)-parseInt(f.css("border-top"),10)-parseInt(f.css("border-bottom"),10)),f.html(e),g.addClass("fileinput-exists").removeClass("fileinput-new"),g.trigger("change.bs.fileinput",c)},e.readAsDataURL(d)}else this.$element.find(".fileinput-filename").text(d.name),this.$preview.text(d.name),this.$element.addClass("fileinput-exists").removeClass("fileinput-new"),this.$element.trigger("change.bs.fileinput")},c.prototype.clear=function(a){if(a&&a.preventDefault(),this.$hidden.val(""),this.$hidden.attr("name",this.name),this.$input.attr("name",""),b){var c=this.$input.clone(!0);this.$input.after(c),this.$input.remove(),this.$input=c}else this.$input.val("");this.$preview.html(""),this.$element.find(".fileinput-filename").text(""),this.$element.addClass("fileinput-new").removeClass("fileinput-exists"),void 0!==a&&(this.$input.trigger("change"),this.$element.trigger("clear.bs.fileinput"))},c.prototype.reset=function(){this.clear(),this.$hidden.val(this.original.hiddenVal),this.$preview.html(this.original.preview),this.$element.find(".fileinput-filename").text(""),this.original.exists?this.$element.addClass("fileinput-exists").removeClass("fileinput-new"):this.$element.addClass("fileinput-new").removeClass("fileinput-exists"),this.$element.trigger("reset.bs.fileinput")},c.prototype.trigger=function(a){this.$input.trigger("click"),a.preventDefault()};var d=a.fn.fileinput;a.fn.fileinput=function(b){return this.each(function(){var d=a(this),e=d.data("bs.fileinput");e||d.data("bs.fileinput",e=new c(this,b)),"string"==typeof b&&e[b]()})},a.fn.fileinput.Constructor=c,a.fn.fileinput.noConflict=function(){return a.fn.fileinput=d,this},a(document).on("click.fileinput.data-api",'[data-provides="fileinput"]',function(b){var c=a(this);if(!c.data("bs.fileinput")){c.fileinput(c.data());var d=a(b.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');d.length>0&&(b.preventDefault(),d.trigger("click.bs.fileinput"))}})}(window.jQuery),function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("undefined"!=typeof jQuery?jQuery:window.Zepto)}(function(a){"use strict";function b(b){var c=b.data;b.isDefaultPrevented()||(b.preventDefault(),a(b.target).ajaxSubmit(c))}function c(b){var c=b.target,d=a(c);if(!d.is("[type=submit],[type=image]")){var e=d.closest("[type=submit]");if(0===e.length)return;c=e[0]}var f=this;if(f.clk=c,"image"==c.type)if(void 0!==b.offsetX)f.clk_x=b.offsetX,f.clk_y=b.offsetY;else if("function"==typeof a.fn.offset){var g=d.offset();f.clk_x=b.pageX-g.left,f.clk_y=b.pageY-g.top}else f.clk_x=b.pageX-c.offsetLeft,f.clk_y=b.pageY-c.offsetTop;setTimeout(function(){f.clk=f.clk_x=f.clk_y=null},100)}function d(){if(a.fn.ajaxSubmit.debug){var b="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(b):window.opera&&window.opera.postError&&window.opera.postError(b)}}var e={};e.fileapi=void 0!==a("").get(0).files,e.formdata=void 0!==window.FormData;var f=!!a.fn.prop;a.fn.attr2=function(){if(!f)return this.attr.apply(this,arguments);var a=this.prop.apply(this,arguments);return a&&a.jquery||"string"==typeof a?a:this.attr.apply(this,arguments)},a.fn.ajaxSubmit=function(b){function c(c){var d,e,f=a.param(c,b.traditional).split("&"),g=f.length,h=[];for(d=0;g>d;d++)f[d]=f[d].replace(/\+/g," "),e=f[d].split("="),h.push([decodeURIComponent(e[0]),decodeURIComponent(e[1])]);return h}function g(d){for(var e=new FormData,f=0;f').val(m.extraData[j].value).appendTo(x)[0]:a('').val(m.extraData[j]).appendTo(x)[0]);m.iframeTarget||q.appendTo("body"),r.attachEvent?r.attachEvent("onload",h):r.addEventListener("load",h,!1),setTimeout(b,15);try{x.submit()}catch(k){var n=document.createElement("form").submit;n.apply(x)}}finally{x.setAttribute("action",f),c?x.setAttribute("target",c):l.removeAttr("target"),a(g).remove()}}function h(b){if(!s.aborted&&!F){if(E=e(r),E||(d("cannot access response document"),b=A),b===z&&s)return s.abort("timeout"),void y.reject(s,"timeout");if(b==A&&s)return s.abort("server abort"),void y.reject(s,"error","server abort");if(E&&E.location.href!=m.iframeSrc||v){r.detachEvent?r.detachEvent("onload",h):r.removeEventListener("load",h,!1);var c,f="success";try{if(v)throw"timeout";var g="xml"==m.dataType||E.XMLDocument||a.isXMLDoc(E);if(d("isXml="+g),!g&&window.opera&&(null===E.body||!E.body.innerHTML)&&--G)return d("requeing onLoad callback, DOM not available"),void setTimeout(h,250);var i=E.body?E.body:E.documentElement;s.responseText=i?i.innerHTML:null,s.responseXML=E.XMLDocument?E.XMLDocument:E,g&&(m.dataType="xml"),s.getResponseHeader=function(a){var b={"content-type":m.dataType};return b[a.toLowerCase()]},i&&(s.status=Number(i.getAttribute("status"))||s.status,s.statusText=i.getAttribute("statusText")||s.statusText);var j=(m.dataType||"").toLowerCase(),k=/(json|script|text)/.test(j);if(k||m.textarea){var l=E.getElementsByTagName("textarea")[0];if(l)s.responseText=l.value,s.status=Number(l.getAttribute("status"))||s.status,s.statusText=l.getAttribute("statusText")||s.statusText;else if(k){var o=E.getElementsByTagName("pre")[0],p=E.getElementsByTagName("body")[0];o?s.responseText=o.textContent?o.textContent:o.innerText:p&&(s.responseText=p.textContent?p.textContent:p.innerText)}}else"xml"==j&&!s.responseXML&&s.responseText&&(s.responseXML=H(s.responseText));try{D=J(s,j,m)}catch(t){f="parsererror",s.error=c=t||f}}catch(t){d("error caught: ",t),f="error",s.error=c=t||f}s.aborted&&(d("upload aborted"),f=null),s.status&&(f=s.status>=200&&s.status<300||304===s.status?"success":"error"),"success"===f?(m.success&&m.success.call(m.context,D,"success",s),y.resolve(s.responseText,"success",s),n&&a.event.trigger("ajaxSuccess",[s,m])):f&&(void 0===c&&(c=s.statusText),m.error&&m.error.call(m.context,s,f,c),y.reject(s,"error",c),n&&a.event.trigger("ajaxError",[s,m,c])),n&&a.event.trigger("ajaxComplete",[s,m]),n&&!--a.active&&a.event.trigger("ajaxStop"),m.complete&&m.complete.call(m.context,s,f),F=!0,m.timeout&&clearTimeout(w),setTimeout(function(){m.iframeTarget?q.attr("src",m.iframeSrc):q.remove(),s.responseXML=null},100)}}}var j,k,m,n,o,q,r,s,t,u,v,w,x=l[0],y=a.Deferred();if(y.abort=function(a){s.abort(a)},c)for(k=0;k'),q.css({position:"absolute",top:"-1000px",left:"-1000px"})),r=q[0],s={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(b){var c="timeout"===b?"timeout":"aborted";d("aborting upload... "+c),this.aborted=1;try{r.contentWindow.document.execCommand&&r.contentWindow.document.execCommand("Stop")}catch(e){}q.attr("src",m.iframeSrc),s.error=c,m.error&&m.error.call(m.context,s,c,b),n&&a.event.trigger("ajaxError",[s,m,c]),m.complete&&m.complete.call(m.context,s,c)}},n=m.global,n&&0===a.active++&&a.event.trigger("ajaxStart"),n&&a.event.trigger("ajaxSend",[s,m]),m.beforeSend&&m.beforeSend.call(m.context,s,m)===!1)return m.global&&a.active--,y.reject(),y;if(s.aborted)return y.reject(),y;t=x.clk,t&&(u=t.name,u&&!t.disabled&&(m.extraData=m.extraData||{},m.extraData[u]=t.value,"image"==t.type&&(m.extraData[u+".x"]=x.clk_x,m.extraData[u+".y"]=x.clk_y)));var z=1,A=2,B=a("meta[name=csrf-token]").attr("content"),C=a("meta[name=csrf-param]").attr("content");C&&B&&(m.extraData=m.extraData||{},m.extraData[C]=B),m.forceSync?g():setTimeout(g,10);var D,E,F,G=50,H=a.parseXML||function(a,b){return window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml"),b&&b.documentElement&&"parsererror"!=b.documentElement.nodeName?b:null},I=a.parseJSON||function(a){return window.eval("("+a+")")},J=function(b,c,d){var e=b.getResponseHeader("content-type")||"",f="xml"===c||!c&&e.indexOf("xml")>=0,g=f?b.responseXML:b.responseText;return f&&"parsererror"===g.documentElement.nodeName&&a.error&&a.error("parsererror"),d&&d.dataFilter&&(g=d.dataFilter(g,c)),"string"==typeof g&&("json"===c||!c&&e.indexOf("json")>=0?g=I(g):("script"===c||!c&&e.indexOf("javascript")>=0)&&a.globalEval(g)),g};return y}if(!this.length)return d("ajaxSubmit: skipping submit process - no element selected"),this;var i,j,k,l=this;"function"==typeof b?b={success:b}:void 0===b&&(b={}),i=b.type||this.attr2("method"),j=b.url||this.attr2("action"),k="string"==typeof j?a.trim(j):"",k=k||window.location.href||"",k&&(k=(k.match(/^([^#]+)/)||[])[1]),b=a.extend(!0,{url:k,success:a.ajaxSettings.success,type:i||a.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},b);var m={};if(this.trigger("form-pre-serialize",[this,b,m]),m.veto)return d("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(b.beforeSerialize&&b.beforeSerialize(this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var n=b.traditional;void 0===n&&(n=a.ajaxSettings.traditional);var o,p=[],q=this.formToArray(b.semantic,p);if(b.data&&(b.extraData=b.data,o=a.param(b.data,n)),b.beforeSubmit&&b.beforeSubmit(q,this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[q,this,b,m]),m.veto)return d("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var r=a.param(q,n);o&&(r=r?r+"&"+o:o),"GET"==b.type.toUpperCase()?(b.url+=(b.url.indexOf("?")>=0?"&":"?")+r,b.data=null):b.data=r;var s=[];if(b.resetForm&&s.push(function(){l.resetForm()}),b.clearForm&&s.push(function(){l.clearForm(b.includeHidden)}),!b.dataType&&b.target){var t=b.success||function(){};s.push(function(c){var d=b.replaceTarget?"replaceWith":"html";a(b.target)[d](c).each(t,arguments)})}else b.success&&s.push(b.success);if(b.success=function(a,c,d){for(var e=b.context||this,f=0,g=s.length;g>f;f++)s[f].apply(e,[a,c,d||l,l])},b.error){var u=b.error;b.error=function(a,c,d){var e=b.context||this;u.apply(e,[a,c,d,l])}}if(b.complete){var v=b.complete;b.complete=function(a,c){var d=b.context||this;v.apply(d,[a,c,l])}}var w=a("input[type=file]:enabled",this).filter(function(){return""!==a(this).val()}),x=w.length>0,y="multipart/form-data",z=l.attr("enctype")==y||l.attr("encoding")==y,A=e.fileapi&&e.formdata;d("fileAPI :"+A);var B,C=(x||z)&&!A;b.iframe!==!1&&(b.iframe||C)?b.closeKeepAlive?a.get(b.closeKeepAlive,function(){B=h(q)}):B=h(q):B=(x||z)&&A?g(q):a.ajax(b),l.removeData("jqxhr").data("jqxhr",B);for(var D=0;Dh;h++)if(l=g[h],j=l.name,j&&!l.disabled)if(b&&f.clk&&"image"==l.type)f.clk==l&&(d.push({name:j,value:a(l).val(),type:l.type}),d.push({name:j+".x",value:f.clk_x},{name:j+".y",value:f.clk_y}));else if(k=a.fieldValue(l,!0),k&&k.constructor==Array)for(c&&c.push(l),i=0,n=k.length;n>i;i++)d.push({name:j,value:k[i]});else if(e.fileapi&&"file"==l.type){c&&c.push(l);var o=l.files;if(o.length)for(i=0;if;f++)c.push({name:d,value:e[f]});else null!==e&&"undefined"!=typeof e&&c.push({name:this.name,value:e})}}),a.param(c)},a.fn.fieldValue=function(b){for(var c=[],d=0,e=this.length;e>d;d++){var f=this[d],g=a.fieldValue(f,b);null===g||"undefined"==typeof g||g.constructor==Array&&!g.length||(g.constructor==Array?a.merge(c,g):c.push(g))}return c},a.fieldValue=function(b,c){var d=b.name,e=b.type,f=b.tagName.toLowerCase();if(void 0===c&&(c=!0),c&&(!d||b.disabled||"reset"==e||"button"==e||("checkbox"==e||"radio"==e)&&!b.checked||("submit"==e||"image"==e)&&b.form&&b.form.clk!=b||"select"==f&&-1==b.selectedIndex))return null;if("select"==f){var g=b.selectedIndex;if(0>g)return null;for(var h=[],i=b.options,j="select-one"==e,k=j?g+1:i.length,l=j?g:0;k>l;l++){var m=i[l];if(m.selected){var n=m.value;if(n||(n=m.attributes&&m.attributes.value&&!m.attributes.value.specified?m.text:m.value),j)return n;h.push(n)}}return h}return a(b).val()},a.fn.clearForm=function(b){return this.each(function(){a("input,select,textarea",this).clearFields(b)})},a.fn.clearFields=a.fn.clearInputs=function(b){var c=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var d=this.type,e=this.tagName.toLowerCase();c.test(d)||"textarea"==e?this.value="":"checkbox"==d||"radio"==d?this.checked=!1:"select"==e?this.selectedIndex=-1:"file"==d?/MSIE/.test(navigator.userAgent)?a(this).replaceWith(a(this).clone(!0)):a(this).val(""):b&&(b===!0&&/hidden/.test(d)||"string"==typeof b&&a(this).is(b))&&(this.value="")})},a.fn.resetForm=function(){ +return this.each(function(){("function"==typeof this.reset||"object"==typeof this.reset&&!this.reset.nodeType)&&this.reset()})},a.fn.enable=function(a){return void 0===a&&(a=!0),this.each(function(){this.disabled=!a})},a.fn.selected=function(b){return void 0===b&&(b=!0),this.each(function(){var c=this.type;if("checkbox"==c||"radio"==c)this.checked=b;else if("option"==this.tagName.toLowerCase()){var d=a(this).parent("select");b&&d[0]&&"select-one"==d[0].type&&d.find("option").selected(!1),this.selected=b}})},a.fn.ajaxSubmit.debug=!1}),function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){function b(b,d){var e,f,g,h=b.nodeName.toLowerCase();return"area"===h?(e=b.parentNode,f=e.name,b.href&&f&&"map"===e.nodeName.toLowerCase()?(g=a("img[usemap='#"+f+"']")[0],!!g&&c(g)):!1):(/^(input|select|textarea|button|object)$/.test(h)?!b.disabled:"a"===h?b.href||d:d)&&c(b)}function c(b){return a.expr.filters.visible(b)&&!a(b).parents().addBack().filter(function(){return"hidden"===a.css(this,"visibility")}).length}function d(a){for(var b,c;a.length&&a[0]!==document;){if(b=a.css("position"),("absolute"===b||"relative"===b||"fixed"===b)&&(c=parseInt(a.css("zIndex"),10),!isNaN(c)&&0!==c))return c;a=a.parent()}return 0}function e(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},a.extend(this._defaults,this.regional[""]),this.regional.en=a.extend(!0,{},this.regional[""]),this.regional["en-US"]=a.extend(!0,{},this.regional.en),this.dpDiv=f(a("
    "))}function f(b){var c="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return b.delegate(c,"mouseout",function(){a(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&a(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&a(this).removeClass("ui-datepicker-next-hover")}).delegate(c,"mouseover",g)}function g(){a.datepicker._isDisabledDatepicker(r.inline?r.dpDiv.parent()[0]:r.input[0])||(a(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),a(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&a(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&a(this).addClass("ui-datepicker-next-hover"))}function h(b,c){a.extend(b,c);for(var d in c)null==c[d]&&(b[d]=c[d]);return b}function i(a){return function(){var b=this.element.val();a.apply(this,arguments),this._refresh(),b!==this.element.val()&&this._trigger("change")}}a.ui=a.ui||{},a.extend(a.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),a.fn.extend({scrollParent:function(b){var c=this.css("position"),d="absolute"===c,e=b?/(auto|scroll|hidden)/:/(auto|scroll)/,f=this.parents().filter(function(){var b=a(this);return d&&"static"===b.css("position")?!1:e.test(b.css("overflow")+b.css("overflow-y")+b.css("overflow-x"))}).eq(0);return"fixed"!==c&&f.length?f:a(this[0].ownerDocument||document)},uniqueId:function(){var a=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&a(this).removeAttr("id")})}}),a.extend(a.expr[":"],{data:a.expr.createPseudo?a.expr.createPseudo(function(b){return function(c){return!!a.data(c,b)}}):function(b,c,d){return!!a.data(b,d[3])},focusable:function(c){return b(c,!isNaN(a.attr(c,"tabindex")))},tabbable:function(c){var d=a.attr(c,"tabindex"),e=isNaN(d);return(e||d>=0)&&b(c,!e)}}),a("").outerWidth(1).jquery||a.each(["Width","Height"],function(b,c){function d(b,c,d,f){return a.each(e,function(){c-=parseFloat(a.css(b,"padding"+this))||0,d&&(c-=parseFloat(a.css(b,"border"+this+"Width"))||0),f&&(c-=parseFloat(a.css(b,"margin"+this))||0)}),c}var e="Width"===c?["Left","Right"]:["Top","Bottom"],f=c.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+c]=function(b){return void 0===b?g["inner"+c].call(this):this.each(function(){a(this).css(f,d(this,b)+"px")})},a.fn["outer"+c]=function(b,e){return"number"!=typeof b?g["outer"+c].call(this,b):this.each(function(){a(this).css(f,d(this,b,!0,e)+"px")})}}),a.fn.addBack||(a.fn.addBack=function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}),a("").data("a-b","a").removeData("a-b").data("a-b")&&(a.fn.removeData=function(b){return function(c){return arguments.length?b.call(this,a.camelCase(c)):b.call(this)}}(a.fn.removeData)),a.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),a.fn.extend({focus:function(b){return function(c,d){return"number"==typeof c?this.each(function(){var b=this;setTimeout(function(){a(b).focus(),d&&d.call(b)},c)}):b.apply(this,arguments)}}(a.fn.focus),disableSelection:function(){var a="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(a+".ui-disableSelection",function(a){a.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(b){if(void 0!==b)return this.css("zIndex",b);if(this.length)for(var c,d,e=a(this[0]);e.length&&e[0]!==document;){if(c=e.css("position"),("absolute"===c||"relative"===c||"fixed"===c)&&(d=parseInt(e.css("zIndex"),10),!isNaN(d)&&0!==d))return d;e=e.parent()}return 0}}),a.ui.plugin={add:function(b,c,d){var e,f=a.ui[b].prototype;for(e in d)f.plugins[e]=f.plugins[e]||[],f.plugins[e].push([c,d[e]])},call:function(a,b,c,d){var e,f=a.plugins[b];if(f&&(d||a.element[0].parentNode&&11!==a.element[0].parentNode.nodeType))for(e=0;ef;f++)for(c in e[f])d=e[f][c],e[f].hasOwnProperty(c)&&void 0!==d&&(b[c]=a.isPlainObject(d)?a.isPlainObject(b[c])?a.widget.extend({},b[c],d):a.widget.extend({},d):d);return b},a.widget.bridge=function(b,c){var d=c.prototype.widgetFullName||b;a.fn[b]=function(e){var f="string"==typeof e,g=k.call(arguments,1),h=this;return f?this.each(function(){var c,f=a.data(this,d);return"instance"===e?(h=f,!1):f?a.isFunction(f[e])&&"_"!==e.charAt(0)?(c=f[e].apply(f,g),c!==f&&void 0!==c?(h=c&&c.jquery?h.pushStack(c.get()):c,!1):void 0):a.error("no such method '"+e+"' for "+b+" widget instance"):a.error("cannot call methods on "+b+" prior to initialization; attempted to call method '"+e+"'")}):(g.length&&(e=a.widget.extend.apply(null,[e].concat(g))),this.each(function(){var b=a.data(this,d);b?(b.option(e||{}),b._init&&b._init()):a.data(this,d,new c(e,this))})),h}},a.Widget=function(){},a.Widget._childConstructors=[],a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{disabled:!1,create:null},_createWidget:function(b,c){c=a(c||this.defaultElement||this)[0],this.element=a(c),this.uuid=j++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=a(),this.hoverable=a(),this.focusable=a(),c!==this&&(a.data(c,this.widgetFullName,this),this._on(!0,this.element,{remove:function(a){a.target===c&&this.destroy()}}),this.document=a(c.style?c.ownerDocument:c.document||c),this.window=a(this.document[0].defaultView||this.document[0].parentWindow)),this.options=a.widget.extend({},this.options,this._getCreateOptions(),b),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:a.noop,_getCreateEventData:a.noop,_create:a.noop,_init:a.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(a.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:a.noop,widget:function(){return this.element},option:function(b,c){var d,e,f,g=b;if(0===arguments.length)return a.widget.extend({},this.options);if("string"==typeof b)if(g={},d=b.split("."),b=d.shift(),d.length){for(e=g[b]=a.widget.extend({},this.options[b]),f=0;f=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}});!function(){function b(a,b,c){return[parseFloat(a[0])*(n.test(a[0])?b/100:1),parseFloat(a[1])*(n.test(a[1])?c/100:1)]}function c(b,c){return parseInt(a.css(b,c),10)||0}function d(b){var c=b[0];return 9===c.nodeType?{width:b.width(),height:b.height(),offset:{top:0,left:0}}:a.isWindow(c)?{width:b.width(),height:b.height(),offset:{top:b.scrollTop(),left:b.scrollLeft()}}:c.preventDefault?{width:0,height:0,offset:{top:c.pageY,left:c.pageX}}:{width:b.outerWidth(),height:b.outerHeight(),offset:b.offset()}}a.ui=a.ui||{};var e,f,g=Math.max,h=Math.abs,i=Math.round,j=/left|center|right/,k=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,m=/^\w+/,n=/%$/,o=a.fn.position;a.position={scrollbarWidth:function(){if(void 0!==e)return e;var b,c,d=a("
    "),f=d.children()[0];return a("body").append(d),b=f.offsetWidth,d.css("overflow","scroll"),c=f.offsetWidth,b===c&&(c=d[0].clientWidth),d.remove(),e=b-c},getScrollInfo:function(b){var c=b.isWindow||b.isDocument?"":b.element.css("overflow-x"),d=b.isWindow||b.isDocument?"":b.element.css("overflow-y"),e="scroll"===c||"auto"===c&&b.widthc?"left":b>0?"right":"center",vertical:0>f?"top":d>0?"bottom":"middle"};l>p&&h(b+c)q&&h(d+f)g(h(d),h(f))?"horizontal":"vertical",e.using.call(this,a,i)}),k.offset(a.extend(B,{using:j}))})},a.ui.position={fit:{left:function(a,b){var c,d=b.within,e=d.isWindow?d.scrollLeft:d.offset.left,f=d.width,h=a.left-b.collisionPosition.marginLeft,i=e-h,j=h+b.collisionWidth-f-e;b.collisionWidth>f?i>0&&0>=j?(c=a.left+i+b.collisionWidth-f-e,a.left+=i-c):a.left=j>0&&0>=i?e:i>j?e+f-b.collisionWidth:e:i>0?a.left+=i:j>0?a.left-=j:a.left=g(a.left-h,a.left)},top:function(a,b){var c,d=b.within,e=d.isWindow?d.scrollTop:d.offset.top,f=b.within.height,h=a.top-b.collisionPosition.marginTop,i=e-h,j=h+b.collisionHeight-f-e;b.collisionHeight>f?i>0&&0>=j?(c=a.top+i+b.collisionHeight-f-e,a.top+=i-c):a.top=j>0&&0>=i?e:i>j?e+f-b.collisionHeight:e:i>0?a.top+=i:j>0?a.top-=j:a.top=g(a.top-h,a.top)}},flip:{left:function(a,b){var c,d,e=b.within,f=e.offset.left+e.scrollLeft,g=e.width,i=e.isWindow?e.scrollLeft:e.offset.left,j=a.left-b.collisionPosition.marginLeft,k=j-i,l=j+b.collisionWidth-g-i,m="left"===b.my[0]?-b.elemWidth:"right"===b.my[0]?b.elemWidth:0,n="left"===b.at[0]?b.targetWidth:"right"===b.at[0]?-b.targetWidth:0,o=-2*b.offset[0];0>k?(c=a.left+m+n+o+b.collisionWidth-g-f,(0>c||c0&&(d=a.left-b.collisionPosition.marginLeft+m+n+o-i,(d>0||h(d)k?(d=a.top+n+o+p+b.collisionHeight-g-f,(0>d||d0&&(c=a.top-b.collisionPosition.marginTop+n+o+p-i,(c>0||h(c)10&&11>e,b.innerHTML="",c.removeChild(b)}()}();a.ui.position,a.widget("ui.accordion",{version:"1.11.4",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var b=this.options;this.prevShow=this.prevHide=a(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),b.collapsible||b.active!==!1&&null!=b.active||(b.active=0),this._processPanels(),b.active<0&&(b.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():a()}},_createIcons:function(){var b=this.options.icons;b&&(a("").addClass("ui-accordion-header-icon ui-icon "+b.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(b.header).addClass(b.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var a;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),a=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&a.css("height","")},_setOption:function(a,b){return"active"===a?void this._activate(b):("event"===a&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(b)),this._super(a,b),"collapsible"!==a||b||this.options.active!==!1||this._activate(0),"icons"===a&&(this._destroyIcons(),b&&this._createIcons()),void("disabled"===a&&(this.element.toggleClass("ui-state-disabled",!!b).attr("aria-disabled",b),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!b))))},_keydown:function(b){if(!b.altKey&&!b.ctrlKey){var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._eventHandler(b);break;case c.HOME:f=this.headers[0];break;case c.END:f=this.headers[d-1]}f&&(a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus(),b.preventDefault())}},_panelKeyDown:function(b){b.keyCode===a.ui.keyCode.UP&&b.ctrlKey&&a(b.currentTarget).prev().focus()},refresh:function(){var b=this.options;this._processPanels(),b.active===!1&&b.collapsible===!0||!this.headers.length?(b.active=!1,this.active=a()):b.active===!1?this._activate(0):this.active.length&&!a.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(b.active=!1,this.active=a()):this._activate(Math.max(0,b.active-1)):b.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var a=this.headers,b=this.panels;this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.panels=this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide(),b&&(this._off(a.not(this.headers)),this._off(b.not(this.panels)))},_refresh:function(){var b,c=this.options,d=c.heightStyle,e=this.element.parent();this.active=this._findActive(c.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var b=a(this),c=b.uniqueId().attr("id"),d=b.next(),e=d.uniqueId().attr("id");b.attr("aria-controls",e),d.attr("aria-labelledby",c)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(c.event),"fill"===d?(b=e.height(),this.element.siblings(":visible").each(function(){var c=a(this),d=c.css("position");"absolute"!==d&&"fixed"!==d&&(b-=c.outerHeight(!0))}),this.headers.each(function(){b-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,b-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")):"auto"===d&&(b=0,this.headers.next().each(function(){b=Math.max(b,a(this).css("height","").height())}).height(b))},_activate:function(b){var c=this._findActive(b)[0];c!==this.active[0]&&(c=c||this.active[0],this._eventHandler({target:c,currentTarget:c,preventDefault:a.noop}))},_findActive:function(b){return"number"==typeof b?this.headers.eq(b):a()},_setupEvents:function(b){var c={keydown:"_keydown"};b&&a.each(b.split(" "),function(a,b){c[b]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,c),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(b){var c=this.options,d=this.active,e=a(b.currentTarget),f=e[0]===d[0],g=f&&c.collapsible,h=g?a():e.next(),i=d.next(),j={oldHeader:d,oldPanel:i,newHeader:g?a():e,newPanel:h};b.preventDefault(),f&&!c.collapsible||this._trigger("beforeActivate",b,j)===!1||(c.active=g?!1:this.headers.index(e),this.active=f?a():e,this._toggle(j),d.removeClass("ui-accordion-header-active ui-state-active"),c.icons&&d.children(".ui-accordion-header-icon").removeClass(c.icons.activeHeader).addClass(c.icons.header),f||(e.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),c.icons&&e.children(".ui-accordion-header-icon").removeClass(c.icons.header).addClass(c.icons.activeHeader),e.next().addClass("ui-accordion-content-active")))},_toggle:function(b){var c=b.newPanel,d=this.prevShow.length?this.prevShow:b.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=c,this.prevHide=d,this.options.animate?this._animate(c,d,b):(d.hide(),c.show(),this._toggleComplete(b)),d.attr({"aria-hidden":"true"}),d.prev().attr({"aria-selected":"false","aria-expanded":"false"}),c.length&&d.length?d.prev().attr({tabIndex:-1,"aria-expanded":"false"}):c.length&&this.headers.filter(function(){return 0===parseInt(a(this).attr("tabIndex"),10)}).attr("tabIndex",-1),c.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(a,b,c){var d,e,f,g=this,h=0,i=a.css("box-sizing"),j=a.length&&(!b.length||a.index()",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item":function(a){ +a.preventDefault()},"click .ui-menu-item":function(b){var c=a(b.target);!this.mouseHandled&&c.not(".ui-state-disabled").length&&(this.select(b),b.isPropagationStopped()||(this.mouseHandled=!0),c.has(".ui-menu").length?this.expand(b):!this.element.is(":focus")&&a(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(b){if(!this.previousFilter){var c=a(b.currentTarget);c.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(b,c)}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(a,b){var c=this.active||this.element.find(this.options.items).eq(0);b||this.focus(a,c)},blur:function(b){this._delay(function(){a.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(b)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(a){this._closeOnDocumentClick(a)&&this.collapseAll(a),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var b=a(this);b.data("ui-menu-submenu-carat")&&b.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(b){var c,d,e,f,g=!0;switch(b.keyCode){case a.ui.keyCode.PAGE_UP:this.previousPage(b);break;case a.ui.keyCode.PAGE_DOWN:this.nextPage(b);break;case a.ui.keyCode.HOME:this._move("first","first",b);break;case a.ui.keyCode.END:this._move("last","last",b);break;case a.ui.keyCode.UP:this.previous(b);break;case a.ui.keyCode.DOWN:this.next(b);break;case a.ui.keyCode.LEFT:this.collapse(b);break;case a.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(b);break;case a.ui.keyCode.ENTER:case a.ui.keyCode.SPACE:this._activate(b);break;case a.ui.keyCode.ESCAPE:this.collapse(b);break;default:g=!1,d=this.previousFilter||"",e=String.fromCharCode(b.keyCode),f=!1,clearTimeout(this.filterTimer),e===d?f=!0:e=d+e,c=this._filterMenuItems(e),c=f&&-1!==c.index(this.active.next())?this.active.nextAll(".ui-menu-item"):c,c.length||(e=String.fromCharCode(b.keyCode),c=this._filterMenuItems(e)),c.length?(this.focus(b,c),this.previousFilter=e,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}g&&b.preventDefault()},_activate:function(a){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(a):this.select(a))},refresh:function(){var b,c,d=this,e=this.options.icons.submenu,f=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),f.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var b=a(this),c=b.parent(),d=a("").addClass("ui-menu-icon ui-icon "+e).data("ui-menu-submenu-carat",!0);c.attr("aria-haspopup","true").prepend(d),b.attr("aria-labelledby",c.attr("id"))}),b=f.add(this.element),c=b.find(this.options.items),c.not(".ui-menu-item").each(function(){var b=a(this);d._isDivider(b)&&b.addClass("ui-widget-content ui-menu-divider")}),c.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),c.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!a.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(a,b){"icons"===a&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(b.submenu),"disabled"===a&&this.element.toggleClass("ui-state-disabled",!!b).attr("aria-disabled",b),this._super(a,b)},focus:function(a,b){var c,d;this.blur(a,a&&"focus"===a.type),this._scrollIntoView(b),this.active=b.first(),d=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",d.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),a&&"keydown"===a.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),c=b.children(".ui-menu"),c.length&&a&&/^mouse/.test(a.type)&&this._startOpening(c),this.activeMenu=b.parent(),this._trigger("focus",a,{item:b})},_scrollIntoView:function(b){var c,d,e,f,g,h;this._hasScroll()&&(c=parseFloat(a.css(this.activeMenu[0],"borderTopWidth"))||0,d=parseFloat(a.css(this.activeMenu[0],"paddingTop"))||0,e=b.offset().top-this.activeMenu.offset().top-c-d,f=this.activeMenu.scrollTop(),g=this.activeMenu.height(),h=b.outerHeight(),0>e?this.activeMenu.scrollTop(f+e):e+h>g&&this.activeMenu.scrollTop(f+e-g+h))},blur:function(a,b){b||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",a,{item:this.active}))},_startOpening:function(a){clearTimeout(this.timer),"true"===a.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(a)},this.delay))},_open:function(b){var c=a.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(b.parents(".ui-menu")).hide().attr("aria-hidden","true"),b.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(c)},collapseAll:function(b,c){clearTimeout(this.timer),this.timer=this._delay(function(){var d=c?this.element:a(b&&b.target).closest(this.element.find(".ui-menu"));d.length||(d=this.element),this._close(d),this.blur(b),this.activeMenu=d},this.delay)},_close:function(a){a||(a=this.active?this.active.parent():this.element),a.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(b){return!a(b.target).closest(".ui-menu").length},_isDivider:function(a){return!/[^\-\u2014\u2013\s]/.test(a.text())},collapse:function(a){var b=this.active&&this.active.parent().closest(".ui-menu-item",this.element);b&&b.length&&(this._close(),this.focus(a,b))},expand:function(a){var b=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();b&&b.length&&(this._open(b.parent()),this._delay(function(){this.focus(a,b)}))},next:function(a){this._move("next","first",a)},previous:function(a){this._move("prev","last",a)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(a,b,c){var d;this.active&&(d="first"===a||"last"===a?this.active["first"===a?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[a+"All"](".ui-menu-item").eq(0)),d&&d.length&&this.active||(d=this.activeMenu.find(this.options.items)[b]()),this.focus(c,d)},nextPage:function(b){var c,d,e;return this.active?void(this.isLastItem()||(this._hasScroll()?(d=this.active.offset().top,e=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return c=a(this),c.offset().top-d-e<0}),this.focus(b,c)):this.focus(b,this.activeMenu.find(this.options.items)[this.active?"last":"first"]()))):void this.next(b)},previousPage:function(b){var c,d,e;return this.active?void(this.isFirstItem()||(this._hasScroll()?(d=this.active.offset().top,e=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return c=a(this),c.offset().top-d+e>0}),this.focus(b,c)):this.focus(b,this.activeMenu.find(this.options.items).first()))):void this.next(b)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var b,c,d,e=this.element[0].nodeName.toLowerCase(),f="textarea"===e,g="input"===e;this.isMultiLine=f?!0:g?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[f||g?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(e){if(this.element.prop("readOnly"))return b=!0,d=!0,void(c=!0);b=!1,d=!1,c=!1;var f=a.ui.keyCode;switch(e.keyCode){case f.PAGE_UP:b=!0,this._move("previousPage",e);break;case f.PAGE_DOWN:b=!0,this._move("nextPage",e);break;case f.UP:b=!0,this._keyEvent("previous",e);break;case f.DOWN:b=!0,this._keyEvent("next",e);break;case f.ENTER:this.menu.active&&(b=!0,e.preventDefault(),this.menu.select(e));break;case f.TAB:this.menu.active&&this.menu.select(e);break;case f.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(e),e.preventDefault());break;default:c=!0,this._searchTimeout(e)}},keypress:function(d){if(b)return b=!1,void((!this.isMultiLine||this.menu.element.is(":visible"))&&d.preventDefault());if(!c){var e=a.ui.keyCode;switch(d.keyCode){case e.PAGE_UP:this._move("previousPage",d);break;case e.PAGE_DOWN:this._move("nextPage",d);break;case e.UP:this._keyEvent("previous",d);break;case e.DOWN:this._keyEvent("next",d)}}},input:function(a){return d?(d=!1,void a.preventDefault()):void this._searchTimeout(a)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(a){return this.cancelBlur?void delete this.cancelBlur:(clearTimeout(this.searching),this.close(a),void this._change(a))}}),this._initSource(),this.menu=a("
      ").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._on(this.menu.element,{mousedown:function(b){b.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var c=this.menu.element[0];a(b.target).closest(".ui-menu-item").length||this._delay(function(){var b=this;this.document.one("mousedown",function(d){d.target===b.element[0]||d.target===c||a.contains(c,d.target)||b.close()})})},menufocus:function(b,c){var d,e;return this.isNewMenu&&(this.isNewMenu=!1,b.originalEvent&&/^mouse/.test(b.originalEvent.type))?(this.menu.blur(),void this.document.one("mousemove",function(){a(b.target).trigger(b.originalEvent)})):(e=c.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",b,{item:e})&&b.originalEvent&&/^key/.test(b.originalEvent.type)&&this._value(e.value),d=c.item.attr("aria-label")||e.value,void(d&&a.trim(d).length&&(this.liveRegion.children().hide(),a("
      ").text(d).appendTo(this.liveRegion))))},menuselect:function(a,b){var c=b.item.data("ui-autocomplete-item"),d=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=d,this._delay(function(){this.previous=d,this.selectedItem=c})),!1!==this._trigger("select",a,{item:c})&&this._value(c.value),this.term=this._value(),this.close(a),this.selectedItem=c}}),this.liveRegion=a("",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(a,b){this._super(a,b),"source"===a&&this._initSource(),"appendTo"===a&&this.menu.element.appendTo(this._appendTo()),"disabled"===a&&b&&this.xhr&&this.xhr.abort()},_appendTo:function(){var b=this.options.appendTo;return b&&(b=b.jquery||b.nodeType?a(b):this.document.find(b).eq(0)),b&&b[0]||(b=this.element.closest(".ui-front")),b.length||(b=this.document[0].body),b},_initSource:function(){var b,c,d=this;a.isArray(this.options.source)?(b=this.options.source,this.source=function(c,d){d(a.ui.autocomplete.filter(b,c.term))}):"string"==typeof this.options.source?(c=this.options.source,this.source=function(b,e){d.xhr&&d.xhr.abort(),d.xhr=a.ajax({url:c,data:b,dataType:"json",success:function(a){e(a)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(a){clearTimeout(this.searching),this.searching=this._delay(function(){var b=this.term===this._value(),c=this.menu.element.is(":visible"),d=a.altKey||a.ctrlKey||a.metaKey||a.shiftKey;(!b||b&&!c&&!d)&&(this.selectedItem=null,this.search(null,a))},this.options.delay)},search:function(a,b){return a=null!=a?a:this._value(),this.term=this._value(),a.length").text(c.label).appendTo(b)},_move:function(a,b){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(a)||this.menu.isLastItem()&&/^next/.test(a)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[a](b):void this.search(null,b)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(a,b){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(a,b),b.preventDefault())}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}}),a.widget("ui.autocomplete",a.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(a){return a+(a>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(b){var c;this._superApply(arguments),this.options.disabled||this.cancelSearch||(c=b&&b.length?this.options.messages.results(b.length):this.options.messages.noResults,this.liveRegion.children().hide(),a("
      ").text(c).appendTo(this.liveRegion))}});var m,n=(a.ui.autocomplete,"ui-button ui-widget ui-state-default ui-corner-all"),o="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",p=function(){var b=a(this);setTimeout(function(){b.find(":ui-button").button("refresh")},1)},q=function(b){var c=b.name,d=b.form,e=a([]);return c&&(c=c.replace(/'/g,"\\'"),e=d?a(d).find("[name='"+c+"'][type=radio]"):a("[name='"+c+"'][type=radio]",b.ownerDocument).filter(function(){return!this.form})),e};a.widget("ui.button",{version:"1.11.4",defaultElement:"").addClass(this._triggerClass).html(f?a("").attr({src:f,alt:e,title:e}):e)),b[h?"before":"after"](c.trigger),c.trigger.click(function(){return a.datepicker._datepickerShowing&&a.datepicker._lastInput===b[0]?a.datepicker._hideDatepicker():a.datepicker._datepickerShowing&&a.datepicker._lastInput!==b[0]?(a.datepicker._hideDatepicker(),a.datepicker._showDatepicker(b[0])):a.datepicker._showDatepicker(b[0]),!1}))},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b,c,d,e,f=new Date(2009,11,20),g=this._get(a,"dateFormat");g.match(/[DM]/)&&(b=function(a){for(c=0,d=0,e=0;ec&&(c=a[e].length,d=e);return d},f.setMonth(b(this._get(a,g.match(/MM/)?"monthNames":"monthNamesShort"))),f.setDate(b(this._get(a,g.match(/DD/)?"dayNames":"dayNamesShort"))+20-f.getDay())),a.input.attr("size",this._formatDate(a,f).length)}},_inlineDatepicker:function(b,c){var d=a(b);d.hasClass(this.markerClassName)||(d.addClass(this.markerClassName).append(c.dpDiv),a.data(b,"datepicker",c),this._setDate(c,this._getDefaultDate(c),!0),this._updateDatepicker(c),this._updateAlternate(c),c.settings.disabled&&this._disableDatepicker(b),c.dpDiv.css("display","block"))},_dialogDatepicker:function(b,c,d,e,f){var g,i,j,k,l,m=this._dialogInst;return m||(this.uuid+=1,g="dp"+this.uuid,this._dialogInput=a(""),this._dialogInput.keydown(this._doKeyDown),a("body").append(this._dialogInput),m=this._dialogInst=this._newInst(this._dialogInput,!1),m.settings={},a.data(this._dialogInput[0],"datepicker",m)),h(m.settings,e||{}),c=c&&c.constructor===Date?this._formatDate(m,c):c,this._dialogInput.val(c),this._pos=f?f.length?f:[f.pageX,f.pageY]:null,this._pos||(i=document.documentElement.clientWidth,j=document.documentElement.clientHeight,k=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[i/2-100+k,j/2-150+l]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),m.settings.onSelect=d,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),a.blockUI&&a.blockUI(this.dpDiv),a.data(this._dialogInput[0],"datepicker",m),this},_destroyDatepicker:function(b){var c,d=a(b),e=a.data(b,"datepicker");d.hasClass(this.markerClassName)&&(c=b.nodeName.toLowerCase(),a.removeData(b,"datepicker"),"input"===c?(e.append.remove(),e.trigger.remove(),d.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===c||"span"===c)&&d.removeClass(this.markerClassName).empty(),r===e&&(r=null))},_enableDatepicker:function(b){var c,d,e=a(b),f=a.data(b,"datepicker");e.hasClass(this.markerClassName)&&(c=b.nodeName.toLowerCase(),"input"===c?(b.disabled=!1,f.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===c||"span"===c)&&(d=e.children("."+this._inlineClass),d.children().removeClass("ui-state-disabled"),d.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=a.map(this._disabledInputs,function(a){return a===b?null:a}))},_disableDatepicker:function(b){var c,d,e=a(b),f=a.data(b,"datepicker");e.hasClass(this.markerClassName)&&(c=b.nodeName.toLowerCase(),"input"===c?(b.disabled=!0,f.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===c||"span"===c)&&(d=e.children("."+this._inlineClass),d.children().addClass("ui-state-disabled"),d.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=a.map(this._disabledInputs,function(a){return a===b?null:a}),this._disabledInputs[this._disabledInputs.length]=b)},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;bd||!c||c.indexOf(d)>-1):void 0},_doKeyUp:function(b){var c,d=a.datepicker._getInst(b.target);if(d.input.val()!==d.lastVal)try{c=a.datepicker.parseDate(a.datepicker._get(d,"dateFormat"),d.input?d.input.val():null,a.datepicker._getFormatConfig(d)),c&&(a.datepicker._setDateFromField(d),a.datepicker._updateAlternate(d),a.datepicker._updateDatepicker(d))}catch(e){}return!0},_showDatepicker:function(b){if(b=b.target||b,"input"!==b.nodeName.toLowerCase()&&(b=a("input",b.parentNode)[0]),!a.datepicker._isDisabledDatepicker(b)&&a.datepicker._lastInput!==b){var c,e,f,g,i,j,k;c=a.datepicker._getInst(b),a.datepicker._curInst&&a.datepicker._curInst!==c&&(a.datepicker._curInst.dpDiv.stop(!0,!0),c&&a.datepicker._datepickerShowing&&a.datepicker._hideDatepicker(a.datepicker._curInst.input[0])),e=a.datepicker._get(c,"beforeShow"),f=e?e.apply(b,[b,c]):{},f!==!1&&(h(c.settings,f),c.lastVal=null,a.datepicker._lastInput=b,a.datepicker._setDateFromField(c),a.datepicker._inDialog&&(b.value=""),a.datepicker._pos||(a.datepicker._pos=a.datepicker._findPos(b),a.datepicker._pos[1]+=b.offsetHeight),g=!1,a(b).parents().each(function(){return g|="fixed"===a(this).css("position"),!g}),i={left:a.datepicker._pos[0],top:a.datepicker._pos[1]},a.datepicker._pos=null,c.dpDiv.empty(),c.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),a.datepicker._updateDatepicker(c),i=a.datepicker._checkOffset(c,i,g),c.dpDiv.css({position:a.datepicker._inDialog&&a.blockUI?"static":g?"fixed":"absolute",display:"none",left:i.left+"px",top:i.top+"px"}),c.inline||(j=a.datepicker._get(c,"showAnim"),k=a.datepicker._get(c,"duration"),c.dpDiv.css("z-index",d(a(b))+1),a.datepicker._datepickerShowing=!0,a.effects&&a.effects.effect[j]?c.dpDiv.show(j,a.datepicker._get(c,"showOptions"),k):c.dpDiv[j||"show"](j?k:null),a.datepicker._shouldFocusInput(c)&&c.input.focus(),a.datepicker._curInst=c))}},_updateDatepicker:function(b){this.maxRows=4,r=b,b.dpDiv.empty().append(this._generateHTML(b)),this._attachHandlers(b);var c,d=this._getNumberOfMonths(b),e=d[1],f=17,h=b.dpDiv.find("."+this._dayOverClass+" a");h.length>0&&g.apply(h.get(0)),b.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),e>1&&b.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",f*e+"em"),b.dpDiv[(1!==d[0]||1!==d[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),b.dpDiv[(this._get(b,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),b===a.datepicker._curInst&&a.datepicker._datepickerShowing&&a.datepicker._shouldFocusInput(b)&&b.input.focus(),b.yearshtml&&(c=b.yearshtml,setTimeout(function(){c===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml),c=b.yearshtml=null},0))},_shouldFocusInput:function(a){return a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&!a.input.is(":focus")},_checkOffset:function(b,c,d){var e=b.dpDiv.outerWidth(),f=b.dpDiv.outerHeight(),g=b.input?b.input.outerWidth():0,h=b.input?b.input.outerHeight():0,i=document.documentElement.clientWidth+(d?0:a(document).scrollLeft()),j=document.documentElement.clientHeight+(d?0:a(document).scrollTop());return c.left-=this._get(b,"isRTL")?e-g:0,c.left-=d&&c.left===b.input.offset().left?a(document).scrollLeft():0,c.top-=d&&c.top===b.input.offset().top+h?a(document).scrollTop():0,c.left-=Math.min(c.left,c.left+e>i&&i>e?Math.abs(c.left+e-i):0),c.top-=Math.min(c.top,c.top+f>j&&j>f?Math.abs(f+h):0),c},_findPos:function(b){for(var c,d=this._getInst(b),e=this._get(d,"isRTL");b&&("hidden"===b.type||1!==b.nodeType||a.expr.filters.hidden(b));)b=b[e?"previousSibling":"nextSibling"];return c=a(b).offset(),[c.left,c.top]},_hideDatepicker:function(b){var c,d,e,f,g=this._curInst;!g||b&&g!==a.data(b,"datepicker")||this._datepickerShowing&&(c=this._get(g,"showAnim"),d=this._get(g,"duration"),e=function(){a.datepicker._tidyDialog(g)},a.effects&&(a.effects.effect[c]||a.effects[c])?g.dpDiv.hide(c,a.datepicker._get(g,"showOptions"),d,e):g.dpDiv["slideDown"===c?"slideUp":"fadeIn"===c?"fadeOut":"hide"](c?d:null,e),c||e(),this._datepickerShowing=!1,f=this._get(g,"onClose"),f&&f.apply(g.input?g.input[0]:null,[g.input?g.input.val():"",g]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),a.blockUI&&(a.unblockUI(),a("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(b){if(a.datepicker._curInst){var c=a(b.target),d=a.datepicker._getInst(c[0]);(c[0].id!==a.datepicker._mainDivId&&0===c.parents("#"+a.datepicker._mainDivId).length&&!c.hasClass(a.datepicker.markerClassName)&&!c.closest("."+a.datepicker._triggerClass).length&&a.datepicker._datepickerShowing&&(!a.datepicker._inDialog||!a.blockUI)||c.hasClass(a.datepicker.markerClassName)&&a.datepicker._curInst!==d)&&a.datepicker._hideDatepicker()}},_adjustDate:function(b,c,d){var e=a(b),f=this._getInst(e[0]);this._isDisabledDatepicker(e[0])||(this._adjustInstDate(f,c+("M"===d?this._get(f,"showCurrentAtPos"):0),d),this._updateDatepicker(f))},_gotoToday:function(b){var c,d=a(b),e=this._getInst(d[0]);this._get(e,"gotoCurrent")&&e.currentDay?(e.selectedDay=e.currentDay,e.drawMonth=e.selectedMonth=e.currentMonth,e.drawYear=e.selectedYear=e.currentYear):(c=new Date,e.selectedDay=c.getDate(),e.drawMonth=e.selectedMonth=c.getMonth(),e.drawYear=e.selectedYear=c.getFullYear()),this._notifyChange(e),this._adjustDate(d)},_selectMonthYear:function(b,c,d){var e=a(b),f=this._getInst(e[0]);f["selected"+("M"===d?"Month":"Year")]=f["draw"+("M"===d?"Month":"Year")]=parseInt(c.options[c.selectedIndex].value,10),this._notifyChange(f),this._adjustDate(e)},_selectDay:function(b,c,d,e){var f,g=a(b);a(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(g[0])||(f=this._getInst(g[0]),f.selectedDay=f.currentDay=a("a",e).html(),f.selectedMonth=f.currentMonth=c,f.selectedYear=f.currentYear=d,this._selectDate(b,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear)))},_clearDate:function(b){var c=a(b);this._selectDate(c,"")},_selectDate:function(b,c){var d,e=a(b),f=this._getInst(e[0]);c=null!=c?c:this._formatDate(f),f.input&&f.input.val(c),this._updateAlternate(f),d=this._get(f,"onSelect"),d?d.apply(f.input?f.input[0]:null,[c,f]):f.input&&f.input.trigger("change"),f.inline?this._updateDatepicker(f):(this._hideDatepicker(),this._lastInput=f.input[0],"object"!=typeof f.input[0]&&f.input.focus(),this._lastInput=null)},_updateAlternate:function(b){var c,d,e,f=this._get(b,"altField");f&&(c=this._get(b,"altFormat")||this._get(b,"dateFormat"),d=this._getDate(b),e=this.formatDate(c,d,this._getFormatConfig(b)),a(f).each(function(){a(this).val(e)}))},noWeekends:function(a){var b=a.getDay();return[b>0&&6>b,""]},iso8601Week:function(a){var b,c=new Date(a.getTime());return c.setDate(c.getDate()+4-(c.getDay()||7)),b=c.getTime(),c.setMonth(0),c.setDate(1),Math.floor(Math.round((b-c)/864e5)/7)+1},parseDate:function(b,c,d){if(null==b||null==c)throw"Invalid arguments";if(c="object"==typeof c?c.toString():c+"",""===c)return null;var e,f,g,h,i=0,j=(d?d.shortYearCutoff:null)||this._defaults.shortYearCutoff,k="string"!=typeof j?j:(new Date).getFullYear()%100+parseInt(j,10),l=(d?d.dayNamesShort:null)||this._defaults.dayNamesShort,m=(d?d.dayNames:null)||this._defaults.dayNames,n=(d?d.monthNamesShort:null)||this._defaults.monthNamesShort,o=(d?d.monthNames:null)||this._defaults.monthNames,p=-1,q=-1,r=-1,s=-1,t=!1,u=function(a){var c=e+1p&&(p+=(new Date).getFullYear()-(new Date).getFullYear()%100+(k>=p?0:-100)),s>-1)for(q=1,r=s;;){if(f=this._getDaysInMonth(p,q-1),f>=r)break;q++,r-=f}if(h=this._daylightSavingAdjust(new Date(p,q-1,r)),h.getFullYear()!==p||h.getMonth()+1!==q||h.getDate()!==r)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d,e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=function(b){var c=d+112?a.getHours()+2:0),a):null},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),e===a.selectedMonth&&f===a.selectedYear||c||this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&""===a.input.val()?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_attachHandlers:function(b){var c=this._get(b,"stepMonths"),d="#"+b.id.replace(/\\\\/g,"\\");b.dpDiv.find("[data-handler]").map(function(){var b={prev:function(){a.datepicker._adjustDate(d,-c,"M")},next:function(){a.datepicker._adjustDate(d,+c,"M")},hide:function(){a.datepicker._hideDatepicker()},today:function(){a.datepicker._gotoToday(d)},selectDay:function(){return a.datepicker._selectDay(d,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return a.datepicker._selectMonthYear(d,this,"M"),!1},selectYear:function(){return a.datepicker._selectMonthYear(d,this,"Y"),!1}};a(this).bind(this.getAttribute("data-event"),b[this.getAttribute("data-handler")])})},_generateHTML:function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O=new Date,P=this._daylightSavingAdjust(new Date(O.getFullYear(),O.getMonth(),O.getDate())),Q=this._get(a,"isRTL"),R=this._get(a,"showButtonPanel"),S=this._get(a,"hideIfNoPrevNext"),T=this._get(a,"navigationAsDateFormat"),U=this._getNumberOfMonths(a),V=this._get(a,"showCurrentAtPos"),W=this._get(a,"stepMonths"),X=1!==U[0]||1!==U[1],Y=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),Z=this._getMinMaxDate(a,"min"),$=this._getMinMaxDate(a,"max"),_=a.drawMonth-V,aa=a.drawYear;if(0>_&&(_+=12,aa--),$)for(b=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-U[0]*U[1]+1,$.getDate())),b=Z&&Z>b?Z:b;this._daylightSavingAdjust(new Date(aa,_,1))>b;)_--,0>_&&(_=11,aa--);for(a.drawMonth=_,a.drawYear=aa,c=this._get(a,"prevText"),c=T?this.formatDate(c,this._daylightSavingAdjust(new Date(aa,_-W,1)),this._getFormatConfig(a)):c,d=this._canAdjustMonth(a,-1,aa,_)?""+c+"":S?"":""+c+"",e=this._get(a,"nextText"),e=T?this.formatDate(e,this._daylightSavingAdjust(new Date(aa,_+W,1)),this._getFormatConfig(a)):e,f=this._canAdjustMonth(a,1,aa,_)?""+e+"":S?"":""+e+"",g=this._get(a,"currentText"),h=this._get(a,"gotoCurrent")&&a.currentDay?Y:P,g=T?this.formatDate(g,h,this._getFormatConfig(a)):g,i=a.inline?"":"",j=R?"
      "+(Q?i:"")+(this._isInRange(a,h)?"":"")+(Q?"":i)+"
      ":"",k=parseInt(this._get(a,"firstDay"),10),k=isNaN(k)?0:k,l=this._get(a,"showWeek"),m=this._get(a,"dayNames"),n=this._get(a,"dayNamesMin"),o=this._get(a,"monthNames"),p=this._get(a,"monthNamesShort"),q=this._get(a,"beforeShowDay"),r=this._get(a,"showOtherMonths"),s=this._get(a,"selectOtherMonths"),t=this._getDefaultDate(a),u="",w=0;w1)switch(y){case 0:B+=" ui-datepicker-group-first",A=" ui-corner-"+(Q?"right":"left");break;case U[1]-1:B+=" ui-datepicker-group-last",A=" ui-corner-"+(Q?"left":"right");break;default:B+=" ui-datepicker-group-middle",A=""}B+="'>"}for(B+="
      "+(/all|left/.test(A)&&0===w?Q?f:d:"")+(/all|right/.test(A)&&0===w?Q?d:f:"")+this._generateMonthYearHeader(a,_,aa,Z,$,w>0||y>0,o,p)+"
      ",C=l?"":"",v=0;7>v;v++)D=(v+k)%7,C+="";for(B+=C+"",E=this._getDaysInMonth(aa,_),aa===a.selectedYear&&_===a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,E)),F=(this._getFirstDayOfMonth(aa,_)-k+7)%7,G=Math.ceil((F+E)/7),H=X&&this.maxRows>G?this.maxRows:G,this.maxRows=H,I=this._daylightSavingAdjust(new Date(aa,_,1-F)),J=0;H>J;J++){for(B+="",K=l?"":"",v=0;7>v;v++)L=q?q.apply(a.input?a.input[0]:null,[I]):[!0,""],M=I.getMonth()!==_,N=M&&!s||!L[0]||Z&&Z>I||$&&I>$,K+="",I.setDate(I.getDate()+1),I=this._daylightSavingAdjust(I);B+=K+""}_++,_>11&&(_=0,aa++),B+="
      "+this._get(a,"weekHeader")+"=5?" class='ui-datepicker-week-end'":"")+">"+n[D]+"
      "+this._get(a,"calculateWeek")(I)+""+(M&&!r?" ":N?""+I.getDate()+"":""+I.getDate()+"")+"
      "+(X?"
      "+(U[0]>0&&y===U[1]-1?"
      ":""):""),x+=B}u+=x}return u+=j,a._keyEvent=!1,u},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i,j,k,l,m,n,o,p,q=this._get(a,"changeMonth"),r=this._get(a,"changeYear"),s=this._get(a,"showMonthAfterYear"),t="
      ",u="";if(f||!q)u+=""+g[b]+"";else{for(i=d&&d.getFullYear()===c,j=e&&e.getFullYear()===c,u+=""}if(s||(t+=u+(!f&&q&&r?"":" ")),!a.yearshtml)if(a.yearshtml="",f||!r)t+=""+c+"";else{for(l=this._get(a,"yearRange").split(":"),m=(new Date).getFullYear(),n=function(a){var b=a.match(/c[+\-].*/)?c+parseInt(a.substring(1),10):a.match(/[+\-].*/)?m+parseInt(a,10):parseInt(a,10);return isNaN(b)?m:b},o=n(l[0]),p=Math.max(o,n(l[1]||"")),o=d?Math.max(o,d.getFullYear()):o,p=e?Math.min(p,e.getFullYear()):p,a.yearshtml+="",t+=a.yearshtml,a.yearshtml=null}return t+=this._get(a,"yearSuffix"),s&&(t+=(!f&&q&&r?"":" ")+u),t+="
      "},_adjustInstDate:function(a,b,c){var d=a.drawYear+("Y"===c?b:0),e=a.drawMonth+("M"===c?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+("D"===c?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),("M"===c||"Y"===c)&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&c>b?c:b;return d&&e>d?d:e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return null==b?[1,1]:"number"==typeof b?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return new Date(a,b,1).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(0>b?b:e[0]*e[1]),1));return 0>b&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth())),this._isInRange(a,f)},_isInRange:function(a,b){var c,d,e=this._getMinMaxDate(a,"min"),f=this._getMinMaxDate(a,"max"),g=null,h=null,i=this._get(a,"yearRange");return i&&(c=i.split(":"),d=(new Date).getFullYear(),g=parseInt(c[0],10),h=parseInt(c[1],10),c[0].match(/[+\-].*/)&&(g+=d),c[1].match(/[+\-].*/)&&(h+=d)),(!e||b.getTime()>=e.getTime())&&(!f||b.getTime()<=f.getTime())&&(!g||b.getFullYear()>=g)&&(!h||b.getFullYear()<=h)},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");return b="string"!=typeof b?b:(new Date).getFullYear()%100+parseInt(b,10),{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?"object"==typeof b?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),a.fn.datepicker=function(b){if(!this.length)return this;a.datepicker.initialized||(a(document).mousedown(a.datepicker._checkExternalClick),a.datepicker.initialized=!0),0===a("#"+a.datepicker._mainDivId).length&&a("body").append(a.datepicker.dpDiv);var c=Array.prototype.slice.call(arguments,1);return"string"!=typeof b||"isDisabled"!==b&&"getDate"!==b&&"widget"!==b?"option"===b&&2===arguments.length&&"string"==typeof arguments[1]?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(c)):this.each(function(){"string"==typeof b?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this].concat(c)):a.datepicker._attachDatepicker(this,b)}):a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(c))},a.datepicker=new e,a.datepicker.initialized=!1,a.datepicker.uuid=(new Date).getTime(),a.datepicker.version="1.11.4";a.datepicker;a.widget("ui.draggable",a.ui.mouse,{version:"1.11.4",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(a,b){this._super(a,b),"handle"===a&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?void(this.destroyOnClear=!0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),void this._mouseDestroy())},_mouseCapture:function(b){var c=this.options;return this._blurActiveElement(b),this.helper||c.disabled||a(b.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(b),this.handle?(this._blockFrames(c.iframeFix===!0?"iframe":c.iframeFix),!0):!1)},_blockFrames:function(b){this.iframeBlocks=this.document.find(b).map(function(){var b=a(this);return a("
      ").css("position","absolute").appendTo(b.parent()).outerWidth(b.outerWidth()).outerHeight(b.outerHeight()).offset(b.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(b){var c=this.document[0];if(this.handleElement.is(b.target))try{c.activeElement&&"body"!==c.activeElement.nodeName.toLowerCase()&&a(c.activeElement).blur()}catch(d){}},_mouseStart:function(b){var c=this.options;return this.helper=this._createHelper(b),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===a(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(b),this.originalPosition=this.position=this._generatePosition(b,!1),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),this._setContainment(),this._trigger("start",b)===!1?(this._clear(),!1):(this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this._normalizeRightBottom(),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b),!0)},_refreshOffsets:function(a){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:a.pageX-this.offset.left,top:a.pageY-this.offset.top}},_mouseDrag:function(b,c){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(b,!0),this.positionAbs=this._convertPositionTo("absolute"),!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1)return this._mouseUp({}),!1;this.position=d.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),!1},_mouseStop:function(b){var c=this,d=!1;return a.ui.ddmanager&&!this.options.dropBehaviour&&(d=a.ui.ddmanager.drop(this,b)),this.dropped&&(d=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!d||"valid"===this.options.revert&&d||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d)?a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",b)!==!1&&c._clear()}):this._trigger("stop",b)!==!1&&this._clear(),!1},_mouseUp:function(b){return this._unblockFrames(),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b),this.handleElement.is(b.target)&&this.element.focus(),a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(b){return this.options.handle?!!a(b.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper),e=d?a(c.helper.apply(this.element[0],[b])):"clone"===c.helper?this.element.clone().removeAttr("id"):this.element;return e.parents("body").length||e.appendTo("parent"===c.appendTo?this.element[0].parentNode:c.appendTo),d&&e[0]===this.element[0]&&this._setPositionRelative(),e[0]===this.element[0]||/(fixed|absolute)/.test(e.css("position"))||e.css("position","absolute"),e},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(b){"string"==typeof b&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_isRootNode:function(a){return/(html|body)/i.test(a.tagName)||a===this.document[0]},_getParentOffset:function(){var b=this.offsetParent.offset(),c=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==c&&a.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(b={top:0,left:0}),{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var a=this.element.position(),b=this._isRootNode(this.scrollParent[0]);return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+(b?0:this.scrollParent.scrollTop()),left:a.left-(parseInt(this.helper.css("left"),10)||0)+(b?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b,c,d,e=this.options,f=this.document[0];return this.relativeContainer=null,e.containment?"window"===e.containment?void(this.containment=[a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,a(window).scrollLeft()+a(window).width()-this.helperProportions.width-this.margins.left,a(window).scrollTop()+(a(window).height()||f.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):"document"===e.containment?void(this.containment=[0,0,a(f).width()-this.helperProportions.width-this.margins.left,(a(f).height()||f.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):e.containment.constructor===Array?void(this.containment=e.containment):("parent"===e.containment&&(e.containment=this.helper[0].parentNode), +c=a(e.containment),d=c[0],void(d&&(b=/(scroll|auto)/.test(c.css("overflow")),this.containment=[(parseInt(c.css("borderLeftWidth"),10)||0)+(parseInt(c.css("paddingLeft"),10)||0),(parseInt(c.css("borderTopWidth"),10)||0)+(parseInt(c.css("paddingTop"),10)||0),(b?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(c.css("borderRightWidth"),10)||0)-(parseInt(c.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(b?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(c.css("borderBottomWidth"),10)||0)-(parseInt(c.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=c))):void(this.containment=null)},_convertPositionTo:function(a,b){b||(b=this.position);var c="absolute"===a?1:-1,d=this._isRootNode(this.scrollParent[0]);return{top:b.top+this.offset.relative.top*c+this.offset.parent.top*c-("fixed"===this.cssPosition?-this.offset.scroll.top:d?0:this.offset.scroll.top)*c,left:b.left+this.offset.relative.left*c+this.offset.parent.left*c-("fixed"===this.cssPosition?-this.offset.scroll.left:d?0:this.offset.scroll.left)*c}},_generatePosition:function(a,b){var c,d,e,f,g=this.options,h=this._isRootNode(this.scrollParent[0]),i=a.pageX,j=a.pageY;return h&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),b&&(this.containment&&(this.relativeContainer?(d=this.relativeContainer.offset(),c=[this.containment[0]+d.left,this.containment[1]+d.top,this.containment[2]+d.left,this.containment[3]+d.top]):c=this.containment,a.pageX-this.offset.click.leftc[2]&&(i=c[2]+this.offset.click.left),a.pageY-this.offset.click.top>c[3]&&(j=c[3]+this.offset.click.top)),g.grid&&(e=g.grid[1]?this.originalPageY+Math.round((j-this.originalPageY)/g.grid[1])*g.grid[1]:this.originalPageY,j=c?e-this.offset.click.top>=c[1]||e-this.offset.click.top>c[3]?e:e-this.offset.click.top>=c[1]?e-g.grid[1]:e+g.grid[1]:e,f=g.grid[0]?this.originalPageX+Math.round((i-this.originalPageX)/g.grid[0])*g.grid[0]:this.originalPageX,i=c?f-this.offset.click.left>=c[0]||f-this.offset.click.left>c[2]?f:f-this.offset.click.left>=c[0]?f-g.grid[0]:f+g.grid[0]:f),"y"===g.axis&&(i=this.originalPageX),"x"===g.axis&&(j=this.originalPageY)),{top:j-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:h?0:this.offset.scroll.top),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:h?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(b,c,d){return d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d,this],!0),/^(drag|start|stop)/.test(b)&&(this.positionAbs=this._convertPositionTo("absolute"),d.offset=this.positionAbs),a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c,d){var e=a.extend({},c,{item:d.element});d.sortables=[],a(d.options.connectToSortable).each(function(){var c=a(this).sortable("instance");c&&!c.options.disabled&&(d.sortables.push(c),c.refreshPositions(),c._trigger("activate",b,e))})},stop:function(b,c,d){var e=a.extend({},c,{item:d.element});d.cancelHelperRemoval=!1,a.each(d.sortables,function(){var a=this;a.isOver?(a.isOver=0,d.cancelHelperRemoval=!0,a.cancelHelperRemoval=!1,a._storedCSS={position:a.placeholder.css("position"),top:a.placeholder.css("top"),left:a.placeholder.css("left")},a._mouseStop(b),a.options.helper=a.options._helper):(a.cancelHelperRemoval=!0,a._trigger("deactivate",b,e))})},drag:function(b,c,d){a.each(d.sortables,function(){var e=!1,f=this;f.positionAbs=d.positionAbs,f.helperProportions=d.helperProportions,f.offset.click=d.offset.click,f._intersectsWith(f.containerCache)&&(e=!0,a.each(d.sortables,function(){return this.positionAbs=d.positionAbs,this.helperProportions=d.helperProportions,this.offset.click=d.offset.click,this!==f&&this._intersectsWith(this.containerCache)&&a.contains(f.element[0],this.element[0])&&(e=!1),e})),e?(f.isOver||(f.isOver=1,d._parent=c.helper.parent(),f.currentItem=c.helper.appendTo(f.element).data("ui-sortable-item",!0),f.options._helper=f.options.helper,f.options.helper=function(){return c.helper[0]},b.target=f.currentItem[0],f._mouseCapture(b,!0),f._mouseStart(b,!0,!0),f.offset.click.top=d.offset.click.top,f.offset.click.left=d.offset.click.left,f.offset.parent.left-=d.offset.parent.left-f.offset.parent.left,f.offset.parent.top-=d.offset.parent.top-f.offset.parent.top,d._trigger("toSortable",b),d.dropped=f.element,a.each(d.sortables,function(){this.refreshPositions()}),d.currentItem=d.element,f.fromOutside=d),f.currentItem&&(f._mouseDrag(b),c.position=f.position)):f.isOver&&(f.isOver=0,f.cancelHelperRemoval=!0,f.options._revert=f.options.revert,f.options.revert=!1,f._trigger("out",b,f._uiHash(f)),f._mouseStop(b,!0),f.options.revert=f.options._revert,f.options.helper=f.options._helper,f.placeholder&&f.placeholder.remove(),c.helper.appendTo(d._parent),d._refreshOffsets(b),c.position=d._generatePosition(b,!0),d._trigger("fromSortable",b),d.dropped=!1,a.each(d.sortables,function(){this.refreshPositions()}))})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c,d){var e=a("body"),f=d.options;e.css("cursor")&&(f._cursor=e.css("cursor")),e.css("cursor",f.cursor)},stop:function(b,c,d){var e=d.options;e._cursor&&a("body").css("cursor",e._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c,d){var e=a(c.helper),f=d.options;e.css("opacity")&&(f._opacity=e.css("opacity")),e.css("opacity",f.opacity)},stop:function(b,c,d){var e=d.options;e._opacity&&a(c.helper).css("opacity",e._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(a,b,c){c.scrollParentNotHidden||(c.scrollParentNotHidden=c.helper.scrollParent(!1)),c.scrollParentNotHidden[0]!==c.document[0]&&"HTML"!==c.scrollParentNotHidden[0].tagName&&(c.overflowOffset=c.scrollParentNotHidden.offset())},drag:function(b,c,d){var e=d.options,f=!1,g=d.scrollParentNotHidden[0],h=d.document[0];g!==h&&"HTML"!==g.tagName?(e.axis&&"x"===e.axis||(d.overflowOffset.top+g.offsetHeight-b.pageY=0;m--)i=d.snapElements[m].left-d.margins.left,j=i+d.snapElements[m].width,k=d.snapElements[m].top-d.margins.top,l=k+d.snapElements[m].height,i-p>r||q>j+p||k-p>t||s>l+p||!a.contains(d.snapElements[m].item.ownerDocument,d.snapElements[m].item)?(d.snapElements[m].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[m].item})),d.snapElements[m].snapping=!1):("inner"!==o.snapMode&&(e=Math.abs(k-t)<=p,f=Math.abs(l-s)<=p,g=Math.abs(i-r)<=p,h=Math.abs(j-q)<=p,e&&(c.position.top=d._convertPositionTo("relative",{top:k-d.helperProportions.height,left:0}).top),f&&(c.position.top=d._convertPositionTo("relative",{top:l,left:0}).top),g&&(c.position.left=d._convertPositionTo("relative",{top:0,left:i-d.helperProportions.width}).left),h&&(c.position.left=d._convertPositionTo("relative",{top:0,left:j}).left)),n=e||f||g||h,"outer"!==o.snapMode&&(e=Math.abs(k-s)<=p,f=Math.abs(l-t)<=p,g=Math.abs(i-q)<=p,h=Math.abs(j-r)<=p,e&&(c.position.top=d._convertPositionTo("relative",{top:k,left:0}).top),f&&(c.position.top=d._convertPositionTo("relative",{top:l-d.helperProportions.height,left:0}).top),g&&(c.position.left=d._convertPositionTo("relative",{top:0,left:i}).left),h&&(c.position.left=d._convertPositionTo("relative",{top:0,left:j-d.helperProportions.width}).left)),!d.snapElements[m].snapping&&(e||f||g||h||n)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[m].item})),d.snapElements[m].snapping=e||f||g||h||n)}}),a.ui.plugin.add("draggable","stack",{start:function(b,c,d){var e,f=d.options,g=a.makeArray(a(f.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});g.length&&(e=parseInt(a(g[0]).css("zIndex"),10)||0,a(g).each(function(b){a(this).css("zIndex",e+b)}),this.css("zIndex",e+g.length))}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c,d){var e=a(c.helper),f=d.options;e.css("zIndex")&&(f._zIndex=e.css("zIndex")),e.css("zIndex",f.zIndex)},stop:function(b,c,d){var e=d.options;e._zIndex&&a(c.helper).css("zIndex",e._zIndex)}});a.ui.draggable;a.widget("ui.resizable",a.ui.mouse,{version:"1.11.4",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(a){return parseInt(a,10)||0},_isNumber:function(a){return!isNaN(parseInt(a,10))},_hasScroll:function(b,c){if("hidden"===a(b).css("overflow"))return!1;var d=c&&"left"===c?"scrollLeft":"scrollTop",e=!1;return b[d]>0?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)},_create:function(){var b,c,d,e,f,g=this,h=this.options;if(this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!h.aspectRatio,aspectRatio:h.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:h.helper||h.ghost||h.animate?h.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(a("
      ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=h.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=a(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),b=this.handles.split(","),this.handles={},c=0;c
      "),e.css({zIndex:h.zIndex}),"se"===d&&e.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[d]=".ui-resizable-"+d,this.element.append(e);this._renderAxis=function(b){var c,d,e,f;b=b||this.element;for(c in this.handles)this.handles[c].constructor===String?this.handles[c]=this.element.children(this.handles[c]).first().show():(this.handles[c].jquery||this.handles[c].nodeType)&&(this.handles[c]=a(this.handles[c]),this._on(this.handles[c],{mousedown:g._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(d=a(this.handles[c],this.element),f=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth(),e=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join(""),b.css(e,f),this._proportionallyResize()),this._handles=this._handles.add(this.handles[c])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.mouseover(function(){g.resizing||(this.className&&(e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),g.axis=e&&e[1]?e[1]:"se")}),h.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").mouseenter(function(){h.disabled||(a(this).removeClass("ui-resizable-autohide"),g._handles.show())}).mouseleave(function(){h.disabled||g.resizing||(a(this).addClass("ui-resizable-autohide"),g._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var b,c=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(c(this.element),b=this.element,this.originalElement.css({position:b.css("position"),width:b.outerWidth(),height:b.outerHeight(),top:b.css("top"),left:b.css("left")}).insertAfter(b),b.remove()),this.originalElement.css("resize",this.originalResizeStyle),c(this.originalElement),this},_mouseCapture:function(b){var c,d,e=!1;for(c in this.handles)d=a(this.handles[c])[0],(d===b.target||a.contains(d,b.target))&&(e=!0);return!this.options.disabled&&e},_mouseStart:function(b){var c,d,e,f=this.options,g=this.element;return this.resizing=!0,this._renderProxy(),c=this._num(this.helper.css("left")),d=this._num(this.helper.css("top")),f.containment&&(c+=a(f.containment).scrollLeft()||0,d+=a(f.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:c,top:d},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:g.width(),height:g.height()},this.originalSize=this._helper?{width:g.outerWidth(),height:g.outerHeight()}:{width:g.width(),height:g.height()},this.sizeDiff={width:g.outerWidth()-g.width(),height:g.outerHeight()-g.height()},this.originalPosition={left:c,top:d},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio="number"==typeof f.aspectRatio?f.aspectRatio:this.originalSize.width/this.originalSize.height||1,e=a(".ui-resizable-"+this.axis).css("cursor"),a("body").css("cursor","auto"===e?this.axis+"-resize":e),g.addClass("ui-resizable-resizing"),this._propagate("start",b),!0},_mouseDrag:function(b){var c,d,e=this.originalMousePosition,f=this.axis,g=b.pageX-e.left||0,h=b.pageY-e.top||0,i=this._change[f];return this._updatePrevProperties(),i?(c=i.apply(this,[b,g,h]),this._updateVirtualBoundaries(b.shiftKey),(this._aspectRatio||b.shiftKey)&&(c=this._updateRatio(c,b)),c=this._respectSize(c,b),this._updateCache(c),this._propagate("resize",b),d=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),a.isEmptyObject(d)||(this._updatePrevProperties(),this._trigger("resize",b,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(b){this.resizing=!1;var c,d,e,f,g,h,i,j=this.options,k=this;return this._helper&&(c=this._proportionallyResizeElements,d=c.length&&/textarea/i.test(c[0].nodeName),e=d&&this._hasScroll(c[0],"left")?0:k.sizeDiff.height,f=d?0:k.sizeDiff.width,g={width:k.helper.width()-f,height:k.helper.height()-e},h=parseInt(k.element.css("left"),10)+(k.position.left-k.originalPosition.left)||null,i=parseInt(k.element.css("top"),10)+(k.position.top-k.originalPosition.top)||null,j.animate||this.element.css(a.extend(g,{top:i,left:h})),k.helper.height(k.size.height),k.helper.width(k.size.width),this._helper&&!j.animate&&this._proportionallyResize()),a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var a={};return this.position.top!==this.prevPosition.top&&(a.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(a.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(a.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(a.height=this.size.height+"px"),this.helper.css(a),a},_updateVirtualBoundaries:function(a){var b,c,d,e,f,g=this.options;f={minWidth:this._isNumber(g.minWidth)?g.minWidth:0,maxWidth:this._isNumber(g.maxWidth)?g.maxWidth:1/0,minHeight:this._isNumber(g.minHeight)?g.minHeight:0,maxHeight:this._isNumber(g.maxHeight)?g.maxHeight:1/0},(this._aspectRatio||a)&&(b=f.minHeight*this.aspectRatio,d=f.minWidth/this.aspectRatio,c=f.maxHeight*this.aspectRatio,e=f.maxWidth/this.aspectRatio,b>f.minWidth&&(f.minWidth=b),d>f.minHeight&&(f.minHeight=d),ca.width,g=this._isNumber(a.height)&&b.minHeight&&b.minHeight>a.height,h=this.originalPosition.left+this.originalSize.width,i=this.position.top+this.size.height,j=/sw|nw|w/.test(c),k=/nw|ne|n/.test(c);return f&&(a.width=b.minWidth),g&&(a.height=b.minHeight),d&&(a.width=b.maxWidth),e&&(a.height=b.maxHeight),f&&j&&(a.left=h-b.minWidth),d&&j&&(a.left=h-b.maxWidth),g&&k&&(a.top=i-b.minHeight),e&&k&&(a.top=i-b.maxHeight),a.width||a.height||a.left||!a.top?a.width||a.height||a.top||!a.left||(a.left=null):a.top=null,a},_getPaddingPlusBorderDimensions:function(a){for(var b=0,c=[],d=[a.css("borderTopWidth"),a.css("borderRightWidth"),a.css("borderBottomWidth"),a.css("borderLeftWidth")],e=[a.css("paddingTop"),a.css("paddingRight"),a.css("paddingBottom"),a.css("paddingLeft")];4>b;b++)c[b]=parseInt(d[b],10)||0,c[b]+=parseInt(e[b],10)||0;return{height:c[0]+c[2],width:c[1]+c[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var a,b=0,c=this.helper||this.element;b
      "),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(a,b){return{width:this.originalSize.width+b}},w:function(a,b){var c=this.originalSize,d=this.originalPosition;return{left:d.left+b,width:c.width-b}},n:function(a,b,c){var d=this.originalSize,e=this.originalPosition;return{top:e.top+c,height:d.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),"resize"!==b&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.ui.plugin.add("resizable","animate",{stop:function(b){var c=a(this).resizable("instance"),d=c.options,e=c._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&c._hasScroll(e[0],"left")?0:c.sizeDiff.height,h=f?0:c.sizeDiff.width,i={width:c.size.width-h,height:c.size.height-g},j=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,k=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;c.element.animate(a.extend(i,k&&j?{top:k,left:j}:{}),{duration:d.animateDuration,easing:d.animateEasing,step:function(){var d={width:parseInt(c.element.css("width"),10),height:parseInt(c.element.css("height"),10),top:parseInt(c.element.css("top"),10),left:parseInt(c.element.css("left"),10)};e&&e.length&&a(e[0]).css({width:d.width,height:d.height}),c._updateCache(d),c._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(){var b,c,d,e,f,g,h,i=a(this).resizable("instance"),j=i.options,k=i.element,l=j.containment,m=l instanceof a?l.get(0):/parent/.test(l)?k.parent().get(0):l;m&&(i.containerElement=a(m),/document/.test(l)||l===document?(i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight}):(b=a(m),c=[],a(["Top","Right","Left","Bottom"]).each(function(a,d){c[a]=i._num(b.css("padding"+d))}),i.containerOffset=b.offset(),i.containerPosition=b.position(),i.containerSize={height:b.innerHeight()-c[3],width:b.innerWidth()-c[1]},d=i.containerOffset,e=i.containerSize.height,f=i.containerSize.width,g=i._hasScroll(m,"left")?m.scrollWidth:f,h=i._hasScroll(m)?m.scrollHeight:e,i.parentData={element:m,left:d.left,top:d.top,width:g,height:h}))},resize:function(b){var c,d,e,f,g=a(this).resizable("instance"),h=g.options,i=g.containerOffset,j=g.position,k=g._aspectRatio||b.shiftKey,l={top:0,left:0},m=g.containerElement,n=!0;m[0]!==document&&/static/.test(m.css("position"))&&(l=i),j.left<(g._helper?i.left:0)&&(g.size.width=g.size.width+(g._helper?g.position.left-i.left:g.position.left-l.left),k&&(g.size.height=g.size.width/g.aspectRatio,n=!1),g.position.left=h.helper?i.left:0),j.top<(g._helper?i.top:0)&&(g.size.height=g.size.height+(g._helper?g.position.top-i.top:g.position.top),k&&(g.size.width=g.size.height*g.aspectRatio,n=!1),g.position.top=g._helper?i.top:0),e=g.containerElement.get(0)===g.element.parent().get(0),f=/relative|absolute/.test(g.containerElement.css("position")),e&&f?(g.offset.left=g.parentData.left+g.position.left,g.offset.top=g.parentData.top+g.position.top):(g.offset.left=g.element.offset().left,g.offset.top=g.element.offset().top),c=Math.abs(g.sizeDiff.width+(g._helper?g.offset.left-l.left:g.offset.left-i.left)),d=Math.abs(g.sizeDiff.height+(g._helper?g.offset.top-l.top:g.offset.top-i.top)),c+g.size.width>=g.parentData.width&&(g.size.width=g.parentData.width-c,k&&(g.size.height=g.size.width/g.aspectRatio,n=!1)),d+g.size.height>=g.parentData.height&&(g.size.height=g.parentData.height-d,k&&(g.size.width=g.size.height*g.aspectRatio,n=!1)),n||(g.position.left=g.prevPosition.left,g.position.top=g.prevPosition.top,g.size.width=g.prevSize.width,g.size.height=g.prevSize.height)},stop:function(){var b=a(this).resizable("instance"),c=b.options,d=b.containerOffset,e=b.containerPosition,f=b.containerElement,g=a(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width,j=g.outerHeight()-b.sizeDiff.height;b._helper&&!c.animate&&/relative/.test(f.css("position"))&&a(this).css({left:h.left-e.left-d.left,width:i,height:j}),b._helper&&!c.animate&&/static/.test(f.css("position"))&&a(this).css({left:h.left-e.left-d.left,width:i,height:j})}}),a.ui.plugin.add("resizable","alsoResize",{start:function(){var b=a(this).resizable("instance"),c=b.options;a(c.alsoResize).each(function(){var b=a(this);b.data("ui-resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})},resize:function(b,c){var d=a(this).resizable("instance"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0};a(e.alsoResize).each(function(){var b=a(this),d=a(this).data("ui-resizable-alsoresize"),e={},f=b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(f,function(a,b){var c=(d[b]||0)+(h[b]||0);c&&c>=0&&(e[b]=c||null)}),b.css(e)})},stop:function(){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","ghost",{start:function(){var b=a(this).resizable("instance"),c=b.options,d=b.size;b.ghost=b.originalElement.clone(),b.ghost.css({opacity:.25,display:"block",position:"relative",height:d.height,width:d.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof c.ghost?c.ghost:""),b.ghost.appendTo(b.helper)},resize:function(){var b=a(this).resizable("instance");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=a(this).resizable("instance");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(){var b,c=a(this).resizable("instance"),d=c.options,e=c.size,f=c.originalSize,g=c.originalPosition,h=c.axis,i="number"==typeof d.grid?[d.grid,d.grid]:d.grid,j=i[0]||1,k=i[1]||1,l=Math.round((e.width-f.width)/j)*j,m=Math.round((e.height-f.height)/k)*k,n=f.width+l,o=f.height+m,p=d.maxWidth&&d.maxWidthn,s=d.minHeight&&d.minHeight>o;d.grid=i,r&&(n+=j),s&&(o+=k),p&&(n-=j),q&&(o-=k),/^(se|s|e)$/.test(h)?(c.size.width=n,c.size.height=o):/^(ne)$/.test(h)?(c.size.width=n,c.size.height=o,c.position.top=g.top-m):/^(sw)$/.test(h)?(c.size.width=n,c.size.height=o,c.position.left=g.left-l):((0>=o-k||0>=n-j)&&(b=c._getPaddingPlusBorderDimensions(this)),o-k>0?(c.size.height=o,c.position.top=g.top-m):(o=k-b.height,c.size.height=o,c.position.top=g.top+f.height-o),n-j>0?(c.size.width=n,c.position.left=g.left-l):(n=j-b.width,c.size.width=n,c.position.left=g.left+f.width-n))}});a.ui.resizable,a.widget("ui.dialog",{version:"1.11.4",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"Close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(b){var c=a(this).css(b).offset().top;0>c&&a(this).css("top",b.top-c)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&a.fn.draggable&&this._makeDraggable(),this.options.resizable&&a.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var b=this.options.appendTo;return b&&(b.jquery||b.nodeType)?a(b):this.document.find(b||"body").eq(0)},_destroy:function(){var a,b=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),a=b.parent.children().eq(b.index),a.length&&a[0]!==this.element[0]?a.before(this.element):b.parent.append(this.element)},widget:function(){return this.uiDialog},disable:a.noop,enable:a.noop,close:function(b){var c,d=this;if(this._isOpen&&this._trigger("beforeClose",b)!==!1){if(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),!this.opener.filter(":focusable").focus().length)try{c=this.document[0].activeElement,c&&"body"!==c.nodeName.toLowerCase()&&a(c).blur()}catch(e){}this._hide(this.uiDialog,this.options.hide,function(){d._trigger("close",b)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(b,c){var d=!1,e=this.uiDialog.siblings(".ui-front:visible").map(function(){return+a(this).css("z-index")}).get(),f=Math.max.apply(null,e);return f>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",f+1),d=!0),d&&!c&&this._trigger("focus",b),d},open:function(){var b=this;return this._isOpen?void(this._moveToTop()&&this._focusTabbable()):(this._isOpen=!0,this.opener=a(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){b._focusTabbable(),b._trigger("focus")}),this._makeFocusTarget(), +void this._trigger("open"))},_focusTabbable:function(){var a=this._focusedElement;a||(a=this.element.find("[autofocus]")),a.length||(a=this.element.find(":tabbable")),a.length||(a=this.uiDialogButtonPane.find(":tabbable")),a.length||(a=this.uiDialogTitlebarClose.filter(":tabbable")),a.length||(a=this.uiDialog),a.eq(0).focus()},_keepFocus:function(b){function c(){var b=this.document[0].activeElement,c=this.uiDialog[0]===b||a.contains(this.uiDialog[0],b);c||this._focusTabbable()}b.preventDefault(),c.call(this),this._delay(c)},_createWrapper:function(){this.uiDialog=a("
      ").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(b){if(this.options.closeOnEscape&&!b.isDefaultPrevented()&&b.keyCode&&b.keyCode===a.ui.keyCode.ESCAPE)return b.preventDefault(),void this.close(b);if(b.keyCode===a.ui.keyCode.TAB&&!b.isDefaultPrevented()){var c=this.uiDialog.find(":tabbable"),d=c.filter(":first"),e=c.filter(":last");b.target!==e[0]&&b.target!==this.uiDialog[0]||b.shiftKey?b.target!==d[0]&&b.target!==this.uiDialog[0]||!b.shiftKey||(this._delay(function(){e.focus()}),b.preventDefault()):(this._delay(function(){d.focus()}),b.preventDefault())}},mousedown:function(a){this._moveToTop(a)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var b;this.uiDialogTitlebar=a("
      ").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(b){a(b.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=a("").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(a){a.preventDefault(),this.close(a)}}),b=a("").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(b),this.uiDialog.attr({"aria-labelledby":b.attr("id")})},_title:function(a){this.options.title||a.html(" "),a.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=a("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=a("
      ").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var b=this,c=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),a.isEmptyObject(c)||a.isArray(c)&&!c.length?void this.uiDialog.removeClass("ui-dialog-buttons"):(a.each(c,function(c,d){var e,f;d=a.isFunction(d)?{click:d,text:c}:d,d=a.extend({type:"button"},d),e=d.click,d.click=function(){e.apply(b.element[0],arguments)},f={icons:d.icons,text:d.showText},delete d.icons,delete d.showText,a("",d).button(f).appendTo(b.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),void this.uiDialogButtonPane.appendTo(this.uiDialog))},_makeDraggable:function(){function b(a){return{position:a.position,offset:a.offset}}var c=this,d=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,e){a(this).addClass("ui-dialog-dragging"),c._blockFrames(),c._trigger("dragStart",d,b(e))},drag:function(a,d){c._trigger("drag",a,b(d))},stop:function(e,f){var g=f.offset.left-c.document.scrollLeft(),h=f.offset.top-c.document.scrollTop();d.position={my:"left top",at:"left"+(g>=0?"+":"")+g+" top"+(h>=0?"+":"")+h,of:c.window},a(this).removeClass("ui-dialog-dragging"),c._unblockFrames(),c._trigger("dragStop",e,b(f))}})},_makeResizable:function(){function b(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}var c=this,d=this.options,e=d.resizable,f=this.uiDialog.css("position"),g="string"==typeof e?e:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:d.maxWidth,maxHeight:d.maxHeight,minWidth:d.minWidth,minHeight:this._minHeight(),handles:g,start:function(d,e){a(this).addClass("ui-dialog-resizing"),c._blockFrames(),c._trigger("resizeStart",d,b(e))},resize:function(a,d){c._trigger("resize",a,b(d))},stop:function(e,f){var g=c.uiDialog.offset(),h=g.left-c.document.scrollLeft(),i=g.top-c.document.scrollTop();d.height=c.uiDialog.height(),d.width=c.uiDialog.width(),d.position={my:"left top",at:"left"+(h>=0?"+":"")+h+" top"+(i>=0?"+":"")+i,of:c.window},a(this).removeClass("ui-dialog-resizing"),c._unblockFrames(),c._trigger("resizeStop",e,b(f))}}).css("position",f)},_trackFocus:function(){this._on(this.widget(),{focusin:function(b){this._makeFocusTarget(),this._focusedElement=a(b.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var b=this._trackingInstances(),c=a.inArray(this,b);-1!==c&&b.splice(c,1)},_trackingInstances:function(){var a=this.document.data("ui-dialog-instances");return a||(a=[],this.document.data("ui-dialog-instances",a)),a},_minHeight:function(){var a=this.options;return"auto"===a.height?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(){var a=this.uiDialog.is(":visible");a||this.uiDialog.show(),this.uiDialog.position(this.options.position),a||this.uiDialog.hide()},_setOptions:function(b){var c=this,d=!1,e={};a.each(b,function(a,b){c._setOption(a,b),a in c.sizeRelatedOptions&&(d=!0),a in c.resizableRelatedOptions&&(e[a]=b)}),d&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",e)},_setOption:function(a,b){var c,d,e=this.uiDialog;"dialogClass"===a&&e.removeClass(this.options.dialogClass).addClass(b),"disabled"!==a&&(this._super(a,b),"appendTo"===a&&this.uiDialog.appendTo(this._appendTo()),"buttons"===a&&this._createButtons(),"closeText"===a&&this.uiDialogTitlebarClose.button({label:""+b}),"draggable"===a&&(c=e.is(":data(ui-draggable)"),c&&!b&&e.draggable("destroy"),!c&&b&&this._makeDraggable()),"position"===a&&this._position(),"resizable"===a&&(d=e.is(":data(ui-resizable)"),d&&!b&&e.resizable("destroy"),d&&"string"==typeof b&&e.resizable("option","handles",b),d||b===!1||this._makeResizable()),"title"===a&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var a,b,c,d=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),d.minWidth>d.width&&(d.width=d.minWidth),a=this.uiDialog.css({height:"auto",width:d.width}).outerHeight(),b=Math.max(0,d.minHeight-a),c="number"==typeof d.maxHeight?Math.max(0,d.maxHeight-a):"none","auto"===d.height?this.element.css({minHeight:b,maxHeight:c,height:"auto"}):this.element.height(Math.max(0,d.height-a)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var b=a(this);return a("
      ").css({position:"absolute",width:b.outerWidth(),height:b.outerHeight()}).appendTo(b.parent()).offset(b.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(b){return a(b.target).closest(".ui-dialog").length?!0:!!a(b.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var b=!0;this._delay(function(){b=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(a){b||this._allowInteraction(a)||(a.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=a("
      ").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var a=this.document.data("ui-dialog-overlays")-1;a?this.document.data("ui-dialog-overlays",a):this.document.unbind("focusin").removeData("ui-dialog-overlays"),this.overlay.remove(),this.overlay=null}}});a.widget("ui.droppable",{version:"1.11.4",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var b,c=this.options,d=c.accept;this.isover=!1,this.isout=!0,this.accept=a.isFunction(d)?d:function(a){return a.is(d)},this.proportions=function(){return arguments.length?void(b=arguments[0]):b?b:b={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(c.scope),c.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(b){a.ui.ddmanager.droppables[b]=a.ui.ddmanager.droppables[b]||[],a.ui.ddmanager.droppables[b].push(this)},_splice:function(a){for(var b=0;b=b&&b+c>a}return function(b,c,d,e){if(!c.offset)return!1;var f=(b.positionAbs||b.position.absolute).left+b.margins.left,g=(b.positionAbs||b.position.absolute).top+b.margins.top,h=f+b.helperProportions.width,i=g+b.helperProportions.height,j=c.offset.left,k=c.offset.top,l=j+c.proportions().width,m=k+c.proportions().height;switch(d){case"fit":return f>=j&&l>=h&&g>=k&&m>=i;case"intersect":return j=k&&m>=g||i>=k&&m>=i||k>g&&i>m)&&(f>=j&&l>=f||h>=j&&l>=h||j>f&&h>l);default:return!1}}}(),a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d,e,f=a.ui.ddmanager.droppables[b.options.scope]||[],g=c?c.type:null,h=(b.currentItem||b.element).find(":data(ui-droppable)").addBack();a:for(d=0;da?0:d.max6*c?a+(b-a)*c*6:1>2*c?b:2>3*c?a+(b-a)*(2/3-c)*6:a}var f,g="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",h=/^([\-+])=\s*(\d+\.?\d*)/,i=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[2.55*a[1],2.55*a[2],2.55*a[3],a[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a){return[a[1],a[2]/100,a[3]/100,a[4]]}}],j=a.Color=function(b,c,d,e){return new a.Color.fn.parse(b,c,d,e)},k={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},l={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},m=j.support={},n=a("

      ")[0],o=a.each;n.style.cssText="background-color:rgba(1,1,1,.5)",m.rgba=n.style.backgroundColor.indexOf("rgba")>-1,o(k,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),j.fn=a.extend(j.prototype,{parse:function(e,g,h,i){if(e===b)return this._rgba=[null,null,null,null],this;(e.jquery||e.nodeType)&&(e=a(e).css(g),g=b);var l=this,m=a.type(e),n=this._rgba=[];return g!==b&&(e=[e,g,h,i],m="array"),"string"===m?this.parse(d(e)||f._default):"array"===m?(o(k.rgba.props,function(a,b){n[b.idx]=c(e[b.idx],b)}),this):"object"===m?(e instanceof j?o(k,function(a,b){e[b.cache]&&(l[b.cache]=e[b.cache].slice())}):o(k,function(b,d){var f=d.cache;o(d.props,function(a,b){if(!l[f]&&d.to){if("alpha"===a||null==e[a])return;l[f]=d.to(l._rgba)}l[f][b.idx]=c(e[a],b,!0)}),l[f]&&a.inArray(null,l[f].slice(0,3))<0&&(l[f][3]=1,d.from&&(l._rgba=d.from(l[f])))}),this):void 0},is:function(a){var b=j(a),c=!0,d=this;return o(k,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],o(e.props,function(a,b){return null!=g[b.idx]?c=g[b.idx]===f[b.idx]:void 0})),c}),c},_space:function(){var a=[],b=this;return o(k,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var d=j(a),e=d._space(),f=k[e],g=0===this.alpha()?j("transparent"):this,h=g[f.cache]||f.to(g._rgba),i=h.slice();return d=d[f.cache],o(f.props,function(a,e){var f=e.idx,g=h[f],j=d[f],k=l[e.type]||{};null!==j&&(null===g?i[f]=j:(k.mod&&(j-g>k.mod/2?g+=k.mod:g-j>k.mod/2&&(g-=k.mod)),i[f]=c((j-g)*b+g,e)))}),this[e](i)},blend:function(b){if(1===this._rgba[3])return this;var c=this._rgba.slice(),d=c.pop(),e=j(b)._rgba;return j(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return null==a?b>2?1:0:a});return 1===c[3]&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return null==a&&(a=b>2?1:0),b&&3>b&&(a=Math.round(100*a)+"%"),a});return 1===c[3]&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(255*d)),"#"+a.map(c,function(a){return a=(a||0).toString(16),1===a.length?"0"+a:a}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),j.fn.parse.prototype=j.fn,k.hsla.to=function(a){if(null==a[0]||null==a[1]||null==a[2])return[null,null,null,a[3]];var b,c,d=a[0]/255,e=a[1]/255,f=a[2]/255,g=a[3],h=Math.max(d,e,f),i=Math.min(d,e,f),j=h-i,k=h+i,l=.5*k;return b=i===h?0:d===h?60*(e-f)/j+360:e===h?60*(f-d)/j+120:60*(d-e)/j+240,c=0===j?0:.5>=l?j/k:j/(2-k),[Math.round(b)%360,c,l,null==g?1:g]},k.hsla.from=function(a){if(null==a[0]||null==a[1]||null==a[2])return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],f=a[3],g=.5>=d?d*(1+c):d+c-d*c,h=2*d-g;return[Math.round(255*e(h,g,b+1/3)),Math.round(255*e(h,g,b)),Math.round(255*e(h,g,b-1/3)),f]},o(k,function(d,e){var f=e.props,g=e.cache,i=e.to,k=e.from;j.fn[d]=function(d){if(i&&!this[g]&&(this[g]=i(this._rgba)),d===b)return this[g].slice();var e,h=a.type(d),l="array"===h||"object"===h?d:arguments,m=this[g].slice();return o(f,function(a,b){var d=l["object"===h?a:b.idx];null==d&&(d=m[b.idx]),m[b.idx]=c(d,b)}),k?(e=j(k(m)),e[g]=m,e):j(m)},o(f,function(b,c){j.fn[b]||(j.fn[b]=function(e){var f,g=a.type(e),i="alpha"===b?this._hsla?"hsla":"rgba":d,j=this[i](),k=j[c.idx];return"undefined"===g?k:("function"===g&&(e=e.call(this,k),g=a.type(e)),null==e&&c.empty?this:("string"===g&&(f=h.exec(e),f&&(e=k+parseFloat(f[2])*("+"===f[1]?1:-1))),j[c.idx]=e,this[i](j)))})})}),j.hook=function(b){var c=b.split(" ");o(c,function(b,c){a.cssHooks[c]={set:function(b,e){var f,g,h="";if("transparent"!==e&&("string"!==a.type(e)||(f=d(e)))){if(e=j(f||e),!m.rgba&&1!==e._rgba[3]){for(g="backgroundColor"===c?b.parentNode:b;(""===h||"transparent"===h)&&g&&g.style;)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(i){}e=e.blend(h&&"transparent"!==h?h:"_default")}e=e.toRgbaString()}try{b.style[c]=e}catch(i){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=j(b.elem,c),b.end=j(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},j.hook(g),a.cssHooks.borderColor={expand:function(a){var b={};return o(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},f=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(t),function(){function b(b){var c,d,e=b.ownerDocument.defaultView?b.ownerDocument.defaultView.getComputedStyle(b,null):b.currentStyle,f={};if(e&&e.length&&e[0]&&e[e[0]])for(d=e.length;d--;)c=e[d],"string"==typeof e[c]&&(f[a.camelCase(c)]=e[c]);else for(c in e)"string"==typeof e[c]&&(f[c]=e[c]);return f}function c(b,c){var d,f,g={};for(d in c)f=c[d],b[d]!==f&&(e[d]||(a.fx.step[d]||!isNaN(parseFloat(f)))&&(g[d]=f));return g}var d=["add","remove","toggle"],e={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(b,c){a.fx.step[c]=function(a){("none"!==a.end&&!a.setAttr||1===a.pos&&!a.setAttr)&&(t.style(a.elem,c,a.end),a.setAttr=!0)}}),a.fn.addBack||(a.fn.addBack=function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}),a.effects.animateClass=function(e,f,g,h){var i=a.speed(f,g,h);return this.queue(function(){var f,g=a(this),h=g.attr("class")||"",j=i.children?g.find("*").addBack():g;j=j.map(function(){var c=a(this);return{el:c,start:b(this)}}),f=function(){a.each(d,function(a,b){e[b]&&g[b+"Class"](e[b])})},f(),j=j.map(function(){return this.end=b(this.el[0]),this.diff=c(this.start,this.end),this}),g.attr("class",h),j=j.map(function(){var b=this,c=a.Deferred(),d=a.extend({},i,{queue:!1,complete:function(){c.resolve(b)}});return this.el.animate(this.diff,d),c.promise()}),a.when.apply(a,j.get()).done(function(){f(),a.each(arguments,function(){var b=this.el;a.each(this.diff,function(a){b.css(a,"")})}),i.complete.call(g[0])})})},a.fn.extend({addClass:function(b){return function(c,d,e,f){return d?a.effects.animateClass.call(this,{add:c},d,e,f):b.apply(this,arguments)}}(a.fn.addClass),removeClass:function(b){return function(c,d,e,f){return arguments.length>1?a.effects.animateClass.call(this,{remove:c},d,e,f):b.apply(this,arguments)}}(a.fn.removeClass),toggleClass:function(b){return function(c,d,e,f,g){return"boolean"==typeof d||void 0===d?e?a.effects.animateClass.call(this,d?{add:c}:{remove:c},e,f,g):b.apply(this,arguments):a.effects.animateClass.call(this,{toggle:c},d,e,f)}}(a.fn.toggleClass),switchClass:function(b,c,d,e,f){return a.effects.animateClass.call(this,{add:c,remove:b},d,e,f)}})}(),function(){function b(b,c,d,e){return a.isPlainObject(b)&&(c=b,b=b.effect),b={effect:b},null==c&&(c={}),a.isFunction(c)&&(e=c,d=null,c={}),("number"==typeof c||a.fx.speeds[c])&&(e=d,d=c,c={}),a.isFunction(d)&&(e=d,d=null),c&&a.extend(b,c),d=d||c.duration,b.duration=a.fx.off?0:"number"==typeof d?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,b.complete=e||c.complete,b}function c(b){return!b||"number"==typeof b||a.fx.speeds[b]?!0:"string"!=typeof b||a.effects.effect[b]?a.isFunction(b)?!0:"object"!=typeof b||b.effect?!1:!0:!0}a.extend(a.effects,{version:"1.11.4",save:function(a,b){for(var c=0;c

      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:b.width(),height:b.height()},f=document.activeElement;try{f.id}catch(g){f=document.body}return b.wrap(d),(b[0]===f||a.contains(b[0],f))&&a(f).focus(),d=b.parent(),"static"===b.css("position")?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),b.css(e),d.css(c).show()},removeWrapper:function(b){var c=document.activeElement;return b.parent().is(".ui-effects-wrapper")&&(b.parent().replaceWith(b),(b[0]===c||a.contains(b[0],c))&&a(c).focus()),b},setTransition:function(b,c,d,e){return e=e||{},a.each(c,function(a,c){var f=b.cssUnit(c);f[0]>0&&(e[c]=f[0]*d+f[1])}),e}}),a.fn.extend({effect:function(){function c(b){function c(){a.isFunction(f)&&f.call(e[0]),a.isFunction(b)&&b()}var e=a(this),f=d.complete,h=d.mode;(e.is(":hidden")?"hide"===h:"show"===h)?(e[h](),c()):g.call(e[0],d,c)}var d=b.apply(this,arguments),e=d.mode,f=d.queue,g=a.effects.effect[d.effect];return a.fx.off||!g?e?this[e](d.duration,d.complete):this.each(function(){d.complete&&d.complete.call(this)}):f===!1?this.each(c):this.queue(f||"fx",c)},show:function(a){return function(d){if(c(d))return a.apply(this,arguments);var e=b.apply(this,arguments);return e.mode="show",this.effect.call(this,e)}}(a.fn.show),hide:function(a){return function(d){if(c(d))return a.apply(this,arguments);var e=b.apply(this,arguments);return e.mode="hide",this.effect.call(this,e)}}(a.fn.hide),toggle:function(a){return function(d){if(c(d)||"boolean"==typeof d)return a.apply(this,arguments);var e=b.apply(this,arguments);return e.mode="toggle",this.effect.call(this,e)}}(a.fn.toggle),cssUnit:function(b){var c=this.css(b),d=[];return a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])}),d}})}(),function(){var b={};a.each(["Quad","Cubic","Quart","Quint","Expo"],function(a,c){b[c]=function(b){return Math.pow(b,a+2)}}),a.extend(b,{Sine:function(a){return 1-Math.cos(a*Math.PI/2)},Circ:function(a){return 1-Math.sqrt(1-a*a)},Elastic:function(a){return 0===a||1===a?a:-Math.pow(2,8*(a-1))*Math.sin((80*(a-1)-7.5)*Math.PI/15)},Back:function(a){return a*a*(3*a-2)},Bounce:function(a){for(var b,c=4;a<((b=Math.pow(2,--c))-1)/11;);return 1/Math.pow(4,3-c)-7.5625*Math.pow((3*b-2)/22-a,2)}}),a.each(b,function(b,c){a.easing["easeIn"+b]=c,a.easing["easeOut"+b]=function(a){return 1-c(1-a)},a.easing["easeInOut"+b]=function(a){return.5>a?c(2*a)/2:1-c(-2*a+2)/2}})}();a.effects,a.effects.effect.blind=function(b,c){var d,e,f,g=a(this),h=/up|down|vertical/,i=/up|left|vertical|horizontal/,j=["position","top","bottom","left","right","height","width"],k=a.effects.setMode(g,b.mode||"hide"),l=b.direction||"up",m=h.test(l),n=m?"height":"width",o=m?"top":"left",p=i.test(l),q={},r="show"===k;g.parent().is(".ui-effects-wrapper")?a.effects.save(g.parent(),j):a.effects.save(g,j),g.show(),d=a.effects.createWrapper(g).css({overflow:"hidden"}),e=d[n](),f=parseFloat(d.css(o))||0,q[n]=r?e:0,p||(g.css(m?"bottom":"right",0).css(m?"top":"left","auto").css({position:"absolute"}),q[o]=r?f:e+f),r&&(d.css(n,0),p||d.css(o,f+e)),d.animate(q,{duration:b.duration,easing:b.easing,queue:!1,complete:function(){"hide"===k&&g.hide(),a.effects.restore(g,j),a.effects.removeWrapper(g),c()}})},a.effects.effect.bounce=function(b,c){var d,e,f,g=a(this),h=["position","top","bottom","left","right","height","width"],i=a.effects.setMode(g,b.mode||"effect"),j="hide"===i,k="show"===i,l=b.direction||"up",m=b.distance,n=b.times||5,o=2*n+(k||j?1:0),p=b.duration/o,q=b.easing,r="up"===l||"down"===l?"top":"left",s="up"===l||"left"===l,t=g.queue(),u=t.length;for((k||j)&&h.push("opacity"),a.effects.save(g,h),g.show(),a.effects.createWrapper(g),m||(m=g["top"===r?"outerHeight":"outerWidth"]()/3),k&&(f={opacity:1},f[r]=0,g.css("opacity",0).css(r,s?2*-m:2*m).animate(f,p,q)),j&&(m/=Math.pow(2,n-1)),f={},f[r]=0,d=0;n>d;d++)e={},e[r]=(s?"-=":"+=")+m,g.animate(e,p,q).animate(f,p,q),m=j?2*m:m/2;j&&(e={opacity:0},e[r]=(s?"-=":"+=")+m,g.animate(e,p,q)),g.queue(function(){j&&g.hide(),a.effects.restore(g,h),a.effects.removeWrapper(g),c()}),u>1&&t.splice.apply(t,[1,0].concat(t.splice(u,o+1))),g.dequeue()},a.effects.effect.clip=function(b,c){var d,e,f,g=a(this),h=["position","top","bottom","left","right","height","width"],i=a.effects.setMode(g,b.mode||"hide"),j="show"===i,k=b.direction||"vertical",l="vertical"===k,m=l?"height":"width",n=l?"top":"left",o={};a.effects.save(g,h),g.show(),d=a.effects.createWrapper(g).css({overflow:"hidden"}),e="IMG"===g[0].tagName?d:g,f=e[m](),j&&(e.css(m,0),e.css(n,f/2)),o[m]=j?f:0,o[n]=j?0:f/2,e.animate(o,{queue:!1,duration:b.duration,easing:b.easing,complete:function(){j||g.hide(),a.effects.restore(g,h),a.effects.removeWrapper(g),c()}})},a.effects.effect.drop=function(b,c){var d,e=a(this),f=["position","top","bottom","left","right","opacity","height","width"],g=a.effects.setMode(e,b.mode||"hide"),h="show"===g,i=b.direction||"left",j="up"===i||"down"===i?"top":"left",k="up"===i||"left"===i?"pos":"neg",l={opacity:h?1:0};a.effects.save(e,f),e.show(),a.effects.createWrapper(e),d=b.distance||e["top"===j?"outerHeight":"outerWidth"](!0)/2,h&&e.css("opacity",0).css(j,"pos"===k?-d:d),l[j]=(h?"pos"===k?"+=":"-=":"pos"===k?"-=":"+=")+d,e.animate(l,{queue:!1,duration:b.duration,easing:b.easing,complete:function(){"hide"===g&&e.hide(),a.effects.restore(e,f),a.effects.removeWrapper(e),c()}})},a.effects.effect.explode=function(b,c){function d(){t.push(this),t.length===l*m&&e()}function e(){n.css({visibility:"visible"}),a(t).remove(),p||n.hide(),c()}var f,g,h,i,j,k,l=b.pieces?Math.round(Math.sqrt(b.pieces)):3,m=l,n=a(this),o=a.effects.setMode(n,b.mode||"hide"),p="show"===o,q=n.show().css("visibility","hidden").offset(),r=Math.ceil(n.outerWidth()/m),s=Math.ceil(n.outerHeight()/l),t=[];for(f=0;l>f;f++)for(i=q.top+f*s,k=f-(l-1)/2,g=0;m>g;g++)h=q.left+g*r,j=g-(m-1)/2,n.clone().appendTo("body").wrap("
      ").css({position:"absolute",visibility:"visible",left:-g*r,top:-f*s}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:r,height:s,left:h+(p?j*r:0),top:i+(p?k*s:0),opacity:p?0:1}).animate({left:h+(p?0:j*r),top:i+(p?0:k*s),opacity:p?1:0},b.duration||500,b.easing,d)},a.effects.effect.fade=function(b,c){var d=a(this),e=a.effects.setMode(d,b.mode||"toggle");d.animate({opacity:e},{queue:!1,duration:b.duration,easing:b.easing,complete:c})},a.effects.effect.fold=function(b,c){var d,e,f=a(this),g=["position","top","bottom","left","right","height","width"],h=a.effects.setMode(f,b.mode||"hide"),i="show"===h,j="hide"===h,k=b.size||15,l=/([0-9]+)%/.exec(k),m=!!b.horizFirst,n=i!==m,o=n?["width","height"]:["height","width"],p=b.duration/2,q={},r={};a.effects.save(f,g),f.show(),d=a.effects.createWrapper(f).css({overflow:"hidden"}),e=n?[d.width(),d.height()]:[d.height(),d.width()],l&&(k=parseInt(l[1],10)/100*e[j?0:1]),i&&d.css(m?{height:0,width:k}:{height:k,width:0}),q[o[0]]=i?e[0]:k,r[o[1]]=i?e[1]:0,d.animate(q,p,b.easing).animate(r,p,b.easing,function(){j&&f.hide(),a.effects.restore(f,g),a.effects.removeWrapper(f),c()})},a.effects.effect.highlight=function(b,c){var d=a(this),e=["backgroundImage","backgroundColor","opacity"],f=a.effects.setMode(d,b.mode||"show"),g={backgroundColor:d.css("backgroundColor")};"hide"===f&&(g.opacity=0),a.effects.save(d,e),d.show().css({backgroundImage:"none",backgroundColor:b.color||"#ffff99" +}).animate(g,{queue:!1,duration:b.duration,easing:b.easing,complete:function(){"hide"===f&&d.hide(),a.effects.restore(d,e),c()}})},a.effects.effect.size=function(b,c){var d,e,f,g=a(this),h=["position","top","bottom","left","right","width","height","overflow","opacity"],i=["position","top","bottom","left","right","overflow","opacity"],j=["width","height","overflow"],k=["fontSize"],l=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],m=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],n=a.effects.setMode(g,b.mode||"effect"),o=b.restore||"effect"!==n,p=b.scale||"both",q=b.origin||["middle","center"],r=g.css("position"),s=o?h:i,t={height:0,width:0,outerHeight:0,outerWidth:0};"show"===n&&g.show(),d={height:g.height(),width:g.width(),outerHeight:g.outerHeight(),outerWidth:g.outerWidth()},"toggle"===b.mode&&"show"===n?(g.from=b.to||t,g.to=b.from||d):(g.from=b.from||("show"===n?t:d),g.to=b.to||("hide"===n?t:d)),f={from:{y:g.from.height/d.height,x:g.from.width/d.width},to:{y:g.to.height/d.height,x:g.to.width/d.width}},("box"===p||"both"===p)&&(f.from.y!==f.to.y&&(s=s.concat(l),g.from=a.effects.setTransition(g,l,f.from.y,g.from),g.to=a.effects.setTransition(g,l,f.to.y,g.to)),f.from.x!==f.to.x&&(s=s.concat(m),g.from=a.effects.setTransition(g,m,f.from.x,g.from),g.to=a.effects.setTransition(g,m,f.to.x,g.to))),("content"===p||"both"===p)&&f.from.y!==f.to.y&&(s=s.concat(k).concat(j),g.from=a.effects.setTransition(g,k,f.from.y,g.from),g.to=a.effects.setTransition(g,k,f.to.y,g.to)),a.effects.save(g,s),g.show(),a.effects.createWrapper(g),g.css("overflow","hidden").css(g.from),q&&(e=a.effects.getBaseline(q,d),g.from.top=(d.outerHeight-g.outerHeight())*e.y,g.from.left=(d.outerWidth-g.outerWidth())*e.x,g.to.top=(d.outerHeight-g.to.outerHeight)*e.y,g.to.left=(d.outerWidth-g.to.outerWidth)*e.x),g.css(g.from),("content"===p||"both"===p)&&(l=l.concat(["marginTop","marginBottom"]).concat(k),m=m.concat(["marginLeft","marginRight"]),j=h.concat(l).concat(m),g.find("*[width]").each(function(){var c=a(this),d={height:c.height(),width:c.width(),outerHeight:c.outerHeight(),outerWidth:c.outerWidth()};o&&a.effects.save(c,j),c.from={height:d.height*f.from.y,width:d.width*f.from.x,outerHeight:d.outerHeight*f.from.y,outerWidth:d.outerWidth*f.from.x},c.to={height:d.height*f.to.y,width:d.width*f.to.x,outerHeight:d.height*f.to.y,outerWidth:d.width*f.to.x},f.from.y!==f.to.y&&(c.from=a.effects.setTransition(c,l,f.from.y,c.from),c.to=a.effects.setTransition(c,l,f.to.y,c.to)),f.from.x!==f.to.x&&(c.from=a.effects.setTransition(c,m,f.from.x,c.from),c.to=a.effects.setTransition(c,m,f.to.x,c.to)),c.css(c.from),c.animate(c.to,b.duration,b.easing,function(){o&&a.effects.restore(c,j)})})),g.animate(g.to,{queue:!1,duration:b.duration,easing:b.easing,complete:function(){0===g.to.opacity&&g.css("opacity",g.from.opacity),"hide"===n&&g.hide(),a.effects.restore(g,s),o||("static"===r?g.css({position:"relative",top:g.to.top,left:g.to.left}):a.each(["top","left"],function(a,b){g.css(b,function(b,c){var d=parseInt(c,10),e=a?g.to.left:g.to.top;return"auto"===c?e+"px":d+e+"px"})})),a.effects.removeWrapper(g),c()}})},a.effects.effect.scale=function(b,c){var d=a(this),e=a.extend(!0,{},b),f=a.effects.setMode(d,b.mode||"effect"),g=parseInt(b.percent,10)||(0===parseInt(b.percent,10)?0:"hide"===f?0:100),h=b.direction||"both",i=b.origin,j={height:d.height(),width:d.width(),outerHeight:d.outerHeight(),outerWidth:d.outerWidth()},k={y:"horizontal"!==h?g/100:1,x:"vertical"!==h?g/100:1};e.effect="size",e.queue=!1,e.complete=c,"effect"!==f&&(e.origin=i||["middle","center"],e.restore=!0),e.from=b.from||("show"===f?{height:0,width:0,outerHeight:0,outerWidth:0}:j),e.to={height:j.height*k.y,width:j.width*k.x,outerHeight:j.outerHeight*k.y,outerWidth:j.outerWidth*k.x},e.fade&&("show"===f&&(e.from.opacity=0,e.to.opacity=1),"hide"===f&&(e.from.opacity=1,e.to.opacity=0)),d.effect(e)},a.effects.effect.puff=function(b,c){var d=a(this),e=a.effects.setMode(d,b.mode||"hide"),f="hide"===e,g=parseInt(b.percent,10)||150,h=g/100,i={height:d.height(),width:d.width(),outerHeight:d.outerHeight(),outerWidth:d.outerWidth()};a.extend(b,{effect:"scale",queue:!1,fade:!0,mode:e,complete:c,percent:f?g:100,from:f?i:{height:i.height*h,width:i.width*h,outerHeight:i.outerHeight*h,outerWidth:i.outerWidth*h}}),d.effect(b)},a.effects.effect.pulsate=function(b,c){var d,e=a(this),f=a.effects.setMode(e,b.mode||"show"),g="show"===f,h="hide"===f,i=g||"hide"===f,j=2*(b.times||5)+(i?1:0),k=b.duration/j,l=0,m=e.queue(),n=m.length;for((g||!e.is(":visible"))&&(e.css("opacity",0).show(),l=1),d=1;j>d;d++)e.animate({opacity:l},k,b.easing),l=1-l;e.animate({opacity:l},k,b.easing),e.queue(function(){h&&e.hide(),c()}),n>1&&m.splice.apply(m,[1,0].concat(m.splice(n,j+1))),e.dequeue()},a.effects.effect.shake=function(b,c){var d,e=a(this),f=["position","top","bottom","left","right","height","width"],g=a.effects.setMode(e,b.mode||"effect"),h=b.direction||"left",i=b.distance||20,j=b.times||3,k=2*j+1,l=Math.round(b.duration/k),m="up"===h||"down"===h?"top":"left",n="up"===h||"left"===h,o={},p={},q={},r=e.queue(),s=r.length;for(a.effects.save(e,f),e.show(),a.effects.createWrapper(e),o[m]=(n?"-=":"+=")+i,p[m]=(n?"+=":"-=")+2*i,q[m]=(n?"-=":"+=")+2*i,e.animate(o,l,b.easing),d=1;j>d;d++)e.animate(p,l,b.easing).animate(q,l,b.easing);e.animate(p,l,b.easing).animate(o,l/2,b.easing).queue(function(){"hide"===g&&e.hide(),a.effects.restore(e,f),a.effects.removeWrapper(e),c()}),s>1&&r.splice.apply(r,[1,0].concat(r.splice(s,k+1))),e.dequeue()},a.effects.effect.slide=function(b,c){var d,e=a(this),f=["position","top","bottom","left","right","width","height"],g=a.effects.setMode(e,b.mode||"show"),h="show"===g,i=b.direction||"left",j="up"===i||"down"===i?"top":"left",k="up"===i||"left"===i,l={};a.effects.save(e,f),e.show(),d=b.distance||e["top"===j?"outerHeight":"outerWidth"](!0),a.effects.createWrapper(e).css({overflow:"hidden"}),h&&e.css(j,k?isNaN(d)?"-"+d:-d:d),l[j]=(h?k?"+=":"-=":k?"-=":"+=")+d,e.animate(l,{queue:!1,duration:b.duration,easing:b.easing,complete:function(){"hide"===g&&e.hide(),a.effects.restore(e,f),a.effects.removeWrapper(e),c()}})},a.effects.effect.transfer=function(b,c){var d=a(this),e=a(b.to),f="fixed"===e.css("position"),g=a("body"),h=f?g.scrollTop():0,i=f?g.scrollLeft():0,j=e.offset(),k={top:j.top-h,left:j.left-i,height:e.innerHeight(),width:e.innerWidth()},l=d.offset(),m=a("
      ").appendTo(document.body).addClass(b.className).css({top:l.top-h,left:l.left-i,height:d.innerHeight(),width:d.innerWidth(),position:f?"fixed":"absolute"}).animate(k,b.duration,b.easing,function(){m.remove(),c()})},a.widget("ui.progressbar",{version:"1.11.4",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=a("
      ").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(a){return void 0===a?this.options.value:(this.options.value=this._constrainedValue(a),void this._refreshValue())},_constrainedValue:function(a){return void 0===a&&(a=this.options.value),this.indeterminate=a===!1,"number"!=typeof a&&(a=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,a))},_setOptions:function(a){var b=a.value;delete a.value,this._super(a),this.options.value=this._constrainedValue(b),this._refreshValue()},_setOption:function(a,b){"max"===a&&(b=Math.max(this.min,b)),"disabled"===a&&this.element.toggleClass("ui-state-disabled",!!b).attr("aria-disabled",b),this._super(a,b)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var b=this.options.value,c=this._percentage();this.valueDiv.toggle(this.indeterminate||b>this.min).toggleClass("ui-corner-right",b===this.options.max).width(c.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=a("
      ").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":b}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==b&&(this.oldValue=b,this._trigger("change")),b===this.options.max&&this._trigger("complete")}}),a.widget("ui.selectable",a.ui.mouse,{version:"1.11.4",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var b,c=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){b=a(c.options.filter,c.element[0]),b.addClass("ui-selectee"),b.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=b.addClass("ui-selectee"),this._mouseInit(),this.helper=a("
      ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(b){var c=this,d=this.options;this.opos=[b.pageX,b.pageY],this.options.disabled||(this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.pageX,top:b.pageY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,b.metaKey||b.ctrlKey||(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().addBack().each(function(){var d,e=a.data(this,"selectable-item");return e?(d=!b.metaKey&&!b.ctrlKey||!e.$element.hasClass("ui-selected"),e.$element.removeClass(d?"ui-unselecting":"ui-selected").addClass(d?"ui-selecting":"ui-unselecting"),e.unselecting=!d,e.selecting=d,e.selected=d,d?c._trigger("selecting",b,{selecting:e.element}):c._trigger("unselecting",b,{unselecting:e.element}),!1):void 0}))},_mouseDrag:function(b){if(this.dragged=!0,!this.options.disabled){var c,d=this,e=this.options,f=this.opos[0],g=this.opos[1],h=b.pageX,i=b.pageY;return f>h&&(c=h,h=f,f=c),g>i&&(c=i,i=g,g=c),this.helper.css({left:f,top:g,width:h-f,height:i-g}),this.selectees.each(function(){var c=a.data(this,"selectable-item"),j=!1;c&&c.element!==d.element[0]&&("touch"===e.tolerance?j=!(c.left>h||c.righti||c.bottomf&&c.rightg&&c.bottom",options:{appendTo:null,disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:null,change:null,close:null,focus:null,open:null,select:null},_create:function(){var a=this.element.uniqueId().attr("id");this.ids={element:a,button:a+"-button",menu:a+"-menu"},this._drawButton(),this._drawMenu(),this.options.disabled&&this.disable()},_drawButton:function(){var b=this;this.label=a("label[for='"+this.ids.element+"']").attr("for",this.ids.button),this._on(this.label,{click:function(a){this.button.focus(),a.preventDefault()}}),this.element.hide(),this.button=a("",{"class":"ui-selectmenu-button ui-widget ui-state-default ui-corner-all",tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true"}).insertAfter(this.element),a("",{"class":"ui-icon "+this.options.icons.button}).prependTo(this.button),this.buttonText=a("",{"class":"ui-selectmenu-text"}).appendTo(this.button),this._setText(this.buttonText,this.element.find("option:selected").text()),this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){b.menuItems||b._refreshMenu()}),this._hoverable(this.button),this._focusable(this.button)},_drawMenu:function(){var b=this;this.menu=a("
        ",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=a("
        ",{"class":"ui-selectmenu-menu ui-front"}).append(this.menu).appendTo(this._appendTo()),this.menuInstance=this.menu.menu({role:"listbox",select:function(a,c){a.preventDefault(),b._setSelection(),b._select(c.item.data("ui-selectmenu-item"),a)},focus:function(a,c){var d=c.item.data("ui-selectmenu-item");null!=b.focusIndex&&d.index!==b.focusIndex&&(b._trigger("focus",a,{item:d}),b.isOpen||b._select(d,a)),b.focusIndex=d.index,b.button.attr("aria-activedescendant",b.menuItems.eq(d.index).attr("id"))}}).menu("instance"),this.menu.addClass("ui-corner-bottom").removeClass("ui-corner-all"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this._setText(this.buttonText,this._getSelectedItem().text()),this.options.width||this._resizeButton()},_refreshMenu:function(){this.menu.empty();var a,b=this.element.find("option");b.length&&(this._parseOptions(b),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup"),a=this._getSelectedItem(),this.menuInstance.focus(null,a),this._setAria(a.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(a){this.options.disabled||(this.menuItems?(this.menu.find(".ui-state-focus").removeClass("ui-state-focus"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",a))},_position:function(){this.menuWrap.position(a.extend({of:this.button},this.options.position))},close:function(a){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",a))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderMenu:function(b,c){var d=this,e="";a.each(c,function(c,f){f.optgroup!==e&&(a("
      • ",{"class":"ui-selectmenu-optgroup ui-menu-divider"+(f.element.parent("optgroup").prop("disabled")?" ui-state-disabled":""),text:f.optgroup}).appendTo(b),e=f.optgroup),d._renderItemData(b,f)})},_renderItemData:function(a,b){return this._renderItem(a,b).data("ui-selectmenu-item",b)},_renderItem:function(b,c){var d=a("
      • ");return c.disabled&&d.addClass("ui-state-disabled"),this._setText(d,c.label),d.appendTo(b)},_setText:function(a,b){b?a.text(b):a.html(" ")},_move:function(a,b){var c,d,e=".ui-menu-item";this.isOpen?c=this.menuItems.eq(this.focusIndex):(c=this.menuItems.eq(this.element[0].selectedIndex),e+=":not(.ui-state-disabled)"),d="first"===a||"last"===a?c["first"===a?"prevAll":"nextAll"](e).eq(-1):c[a+"All"](e).eq(0),d.length&&this.menuInstance.focus(b,d)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex)},_toggle:function(a){this[this.isOpen?"close":"open"](a)},_setSelection:function(){var a;this.range&&(window.getSelection?(a=window.getSelection(),a.removeAllRanges(),a.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(b){this.isOpen&&(a(b.target).closest(".ui-selectmenu-menu, #"+this.ids.button).length||this.close(b))}},_buttonEvents:{mousedown:function(){var a;window.getSelection?(a=window.getSelection(),a.rangeCount&&(this.range=a.getRangeAt(0))):this.range=document.selection.createRange()},click:function(a){this._setSelection(),this._toggle(a)},keydown:function(b){var c=!0;switch(b.keyCode){case a.ui.keyCode.TAB:case a.ui.keyCode.ESCAPE:this.close(b),c=!1;break;case a.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(b);break;case a.ui.keyCode.UP:b.altKey?this._toggle(b):this._move("prev",b);break;case a.ui.keyCode.DOWN:b.altKey?this._toggle(b):this._move("next",b);break;case a.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(b):this._toggle(b);break;case a.ui.keyCode.LEFT:this._move("prev",b);break;case a.ui.keyCode.RIGHT:this._move("next",b);break;case a.ui.keyCode.HOME:case a.ui.keyCode.PAGE_UP:this._move("first",b);break;case a.ui.keyCode.END:case a.ui.keyCode.PAGE_DOWN:this._move("last",b);break;default:this.menu.trigger(b),c=!1}c&&b.preventDefault()}},_selectFocusedItem:function(a){var b=this.menuItems.eq(this.focusIndex);b.hasClass("ui-state-disabled")||this._select(b.data("ui-selectmenu-item"),a)},_select:function(a,b){var c=this.element[0].selectedIndex;this.element[0].selectedIndex=a.index,this._setText(this.buttonText,a.label),this._setAria(a),this._trigger("select",b,{item:a}),a.index!==c&&this._trigger("change",b,{item:a}),this.close(b)},_setAria:function(a){var b=this.menuItems.eq(a.index).attr("id");this.button.attr({"aria-labelledby":b,"aria-activedescendant":b}),this.menu.attr("aria-activedescendant",b)},_setOption:function(a,b){"icons"===a&&this.button.find("span.ui-icon").removeClass(this.options.icons.button).addClass(b.button),this._super(a,b),"appendTo"===a&&this.menuWrap.appendTo(this._appendTo()),"disabled"===a&&(this.menuInstance.option("disabled",b),this.button.toggleClass("ui-state-disabled",b).attr("aria-disabled",b),this.element.prop("disabled",b),b?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)),"width"===a&&this._resizeButton()},_appendTo:function(){var b=this.options.appendTo;return b&&(b=b.jquery||b.nodeType?a(b):this.document.find(b).eq(0)),b&&b[0]||(b=this.element.closest(".ui-front")),b.length||(b=this.document[0].body),b},_toggleAttr:function(){this.button.toggleClass("ui-corner-top",this.isOpen).toggleClass("ui-corner-all",!this.isOpen).attr("aria-expanded",this.isOpen),this.menuWrap.toggleClass("ui-selectmenu-open",this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var a=this.options.width;a||(a=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(a)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){return{disabled:this.element.prop("disabled")}},_parseOptions:function(b){var c=[];b.each(function(b,d){var e=a(d),f=e.parent("optgroup");c.push({element:e,index:b,value:e.val(),label:e.text(),optgroup:f.attr("label")||"",disabled:f.prop("disabled")||e.prop("disabled")})}),this.items=c},_destroy:function(){this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.label.attr("for",this.ids.element)}}),a.widget("ui.slider",a.ui.mouse,{version:"1.11.4",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var b,c,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="",g=[];for(c=d.values&&d.values.length||1,e.length>c&&(e.slice(c).remove(),e=e.slice(0,c)),b=e.length;c>b;b++)g.push(f);this.handles=e.add(a(g.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(b){a(this).data("ui-slider-handle-index",b)})},_createRange:function(){var b=this.options,c="";b.range?(b.range===!0&&(b.values?b.values.length&&2!==b.values.length?b.values=[b.values[0],b.values[0]]:a.isArray(b.values)&&(b.values=b.values.slice(0)):b.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=a("
        ").appendTo(this.element),c="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(c+("min"===b.range||"max"===b.range?" ui-slider-range-"+b.range:""))):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(b){var c,d,e,f,g,h,i,j,k=this,l=this.options;return l.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),c={x:b.pageX,y:b.pageY},d=this._normValueFromMouse(c),e=this._valueMax()-this._valueMin()+1,this.handles.each(function(b){var c=Math.abs(d-k.values(b));(e>c||e===c&&(b===k._lastChangedValue||k.values(b)===l.min))&&(e=c,f=a(this),g=b)}),h=this._start(b,g),h===!1?!1:(this._mouseSliding=!0,this._handleIndex=g,f.addClass("ui-state-active").focus(),i=f.offset(),j=!a(b.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=j?{left:0,top:0}:{left:b.pageX-i.left-f.width()/2,top:b.pageY-i.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,g,d),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);return this._slide(a,this._handleIndex,c),!1},_mouseStop:function(a){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;return"horizontal"===this.orientation?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),0>d&&(d=0),"vertical"===this.orientation&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e,this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};return this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),2===this.options.values.length&&this.options.range===!0&&(0===b&&c>d||1===b&&d>c)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._lastChangedValue=b,this._trigger("change",a,c)}},value:function(a){return arguments.length?(this.options.value=this._trimAlignValue(a),this._refreshValue(),void this._change(null,0)):this._value()},values:function(b,c){var d,e,f;if(arguments.length>1)return this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),void this._change(null,b);if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();for(d=this.options.values,e=arguments[0],f=0;fd;d+=1)this._change(null,d);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var a=this.options.value;return a=this._trimAlignValue(a)},_values:function(a){var b,c,d;if(arguments.length)return b=this.options.values[a],b=this._trimAlignValue(b);if(this.options.values&&this.options.values.length){for(c=this.options.values.slice(),d=0;d=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;return 2*Math.abs(c)>=b&&(d+=c>0?b:-b),parseFloat(d.toFixed(5))},_calculateNewMax:function(){var a=this.options.max,b=this._valueMin(),c=this.options.step,d=Math.floor(+(a-b).toFixed(this._precision())/c)*c;a=d+b,this.max=parseFloat(a.toFixed(this._precision()))},_precision:function(){var a=this._precisionOf(this.options.step);return null!==this.options.min&&(a=Math.max(a,this._precisionOf(this.options.min))),a},_precisionOf:function(a){var b=a.toString(),c=b.indexOf(".");return-1===c?0:b.length-c-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshValue:function(){var b,c,d,e,f,g=this.options.range,h=this.options,i=this,j=this._animateOff?!1:h.animate,k={};this.options.values&&this.options.values.length?this.handles.each(function(d){c=(i.values(d)-i._valueMin())/(i._valueMax()-i._valueMin())*100,k["horizontal"===i.orientation?"left":"bottom"]=c+"%",a(this).stop(1,1)[j?"animate":"css"](k,h.animate),i.options.range===!0&&("horizontal"===i.orientation?(0===d&&i.range.stop(1,1)[j?"animate":"css"]({left:c+"%"},h.animate),1===d&&i.range[j?"animate":"css"]({width:c-b+"%"},{queue:!1,duration:h.animate})):(0===d&&i.range.stop(1,1)[j?"animate":"css"]({bottom:c+"%"},h.animate),1===d&&i.range[j?"animate":"css"]({height:c-b+"%"},{queue:!1,duration:h.animate}))),b=c}):(d=this.value(),e=this._valueMin(),f=this._valueMax(),c=f!==e?(d-e)/(f-e)*100:0,k["horizontal"===this.orientation?"left":"bottom"]=c+"%",this.handle.stop(1,1)[j?"animate":"css"](k,h.animate),"min"===g&&"horizontal"===this.orientation&&this.range.stop(1,1)[j?"animate":"css"]({width:c+"%"},h.animate),"max"===g&&"horizontal"===this.orientation&&this.range[j?"animate":"css"]({width:100-c+"%"},{queue:!1,duration:h.animate}),"min"===g&&"vertical"===this.orientation&&this.range.stop(1,1)[j?"animate":"css"]({height:c+"%"},h.animate),"max"===g&&"vertical"===this.orientation&&this.range[j?"animate":"css"]({height:100-c+"%"},{queue:!1,duration:h.animate}))},_handleEvents:{keydown:function(b){var c,d,e,f,g=a(b.target).data("ui-slider-handle-index");switch(b.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(b.preventDefault(),!this._keySliding&&(this._keySliding=!0,a(b.target).addClass("ui-state-active"),c=this._start(b,g),c===!1))return}switch(f=this.options.step,d=e=this.options.values&&this.options.values.length?this.values(g):this.value(),b.keyCode){case a.ui.keyCode.HOME:e=this._valueMin();break;case a.ui.keyCode.END:e=this._valueMax();break;case a.ui.keyCode.PAGE_UP:e=this._trimAlignValue(d+(this._valueMax()-this._valueMin())/this.numPages);break;case a.ui.keyCode.PAGE_DOWN:e=this._trimAlignValue(d-(this._valueMax()-this._valueMin())/this.numPages);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(d===this._valueMax())return;e=this._trimAlignValue(d+f);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(d===this._valueMin())return;e=this._trimAlignValue(d-f)}this._slide(b,g,e)},keyup:function(b){var c=a(b.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(b,c),this._change(b,c),a(b.target).removeClass("ui-state-active"))}}}),a.widget("ui.sortable",a.ui.mouse,{version:"1.11.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(a,b,c){return a>=b&&b+c>a},_isFloating:function(a){return/left|right/.test(a.css("float"))||/inline|table-cell/.test(a.css("display")); + +},_create:function(){this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(a,b){this._super(a,b),"handle"===a&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),a.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(b,c){var d=null,e=!1,f=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(b),a(b.target).parents().each(function(){return a.data(this,f.widgetName+"-item")===f?(d=a(this),!1):void 0}),a.data(b.target,f.widgetName+"-item")===f&&(d=a(b.target)),d&&(!this.options.handle||c||(a(this.options.handle,d).find("*").addBack().each(function(){this===b.target&&(e=!0)}),e))?(this.currentItem=d,this._removeCurrentsFromItems(),!0):!1)},_mouseStart:function(b,c,d){var e,f,g=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,g.cursorAt&&this._adjustOffsetFromHelper(g.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),g.containment&&this._setContainment(),g.cursor&&"auto"!==g.cursor&&(f=this.document.find("body"),this.storedCursor=f.css("cursor"),f.css("cursor",g.cursor),this.storedStylesheet=a("").appendTo(f)),g.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",g.opacity)),g.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",g.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!d)for(e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("activate",b,this._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!g.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){var c,d,e,f,g=this.options,h=!1;for(this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;c--)if(d=this.items[c],e=d.item[0],f=this._intersectsWithPointer(d),f&&d.instance===this.currentContainer&&e!==this.currentItem[0]&&this.placeholder[1===f?"next":"prev"]()[0]!==e&&!a.contains(this.placeholder[0],e)&&("semi-dynamic"===this.options.type?!a.contains(this.element[0],e):!0)){if(this.direction=1===f?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(d))break;this._rearrange(b,d),this._trigger("change",b,this._uiHash());break}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(b){if(a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b),this.options.revert){var d=this,e=this.placeholder.offset(),f=this.options.axis,g={};f&&"x"!==f||(g.left=e.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),f&&"y"!==f||(g.top=e.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,a(this.helper).animate(g,parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--)this.containers[b]._trigger("deactivate",null,this._uiHash(this)),this.containers[b].containerCache.over&&(this.containers[b]._trigger("out",null,this._uiHash(this)),this.containers[b].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[\-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l="x"===this.options.axis||d+j>h&&i>d+j,m="y"===this.options.axis||b+k>f&&g>b+k,n=l&&m;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?n:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return 0!==a&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor===String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){function c(){h.push(this)}var d,e,f,g,h=[],i=[],j=this._connectWith();if(j&&b)for(d=j.length-1;d>=0;d--)for(f=a(j[d],this.document[0]),e=f.length-1;e>=0;e--)g=a.data(f[e],this.widgetFullName),g&&g!==this&&!g.options.disabled&&i.push([a.isFunction(g.options.items)?g.options.items.call(g.element):a(g.options.items,g.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),g]);for(i.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),d=i.length-1;d>=0;d--)i[d][0].each(c);return a(h)},_removeCurrentsFromItems:function(){var b=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=a.grep(this.items,function(a){for(var c=0;c=0;c--)for(e=a(m[c],this.document[0]),d=e.length-1;d>=0;d--)f=a.data(e[d],this.widgetFullName),f&&f!==this&&!f.options.disabled&&(l.push([a.isFunction(f.options.items)?f.options.items.call(f.element[0],b,{item:this.currentItem}):a(f.options.items,f.element),f]),this.containers.push(f));for(c=l.length-1;c>=0;c--)for(g=l[c][1],h=l[c][0],d=0,j=h.length;j>d;d++)i=a(h[d]),i.data(this.widgetName+"-item",g),k.push({item:i,instance:g,width:0,height:0,left:0,top:0})},refreshPositions:function(b){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var c,d,e,f;for(c=this.items.length-1;c>=0;c--)d=this.items[c],d.instance!==this.currentContainer&&this.currentContainer&&d.item[0]!==this.currentItem[0]||(e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item,b||(d.width=e.outerWidth(),d.height=e.outerHeight()),f=e.offset(),d.left=f.left,d.top=f.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(c=this.containers.length-1;c>=0;c--)f=this.containers[c].element.offset(),this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight();return this},_createPlaceholder:function(b){b=b||this;var c,d=b.options;d.placeholder&&d.placeholder.constructor!==String||(c=d.placeholder,d.placeholder={element:function(){var d=b.currentItem[0].nodeName.toLowerCase(),e=a("<"+d+">",b.document[0]).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tbody"===d?b._createTrPlaceholder(b.currentItem.find("tr").eq(0),a("",b.document[0]).appendTo(e)):"tr"===d?b._createTrPlaceholder(b.currentItem,e):"img"===d&&e.attr("src",b.currentItem.attr("src")),c||e.css("visibility","hidden"),e},update:function(a,e){(!c||d.forcePlaceholderSize)&&(e.height()||e.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10)))}}),b.placeholder=a(d.placeholder.element.call(b.element,b.currentItem)),b.currentItem.after(b.placeholder),d.placeholder.update(b,b.placeholder)},_createTrPlaceholder:function(b,c){var d=this;b.children().each(function(){a(" ",d.document[0]).attr("colspan",a(this).attr("colspan")||1).appendTo(c)})},_contactContainers:function(b){var c,d,e,f,g,h,i,j,k,l,m=null,n=null;for(c=this.containers.length-1;c>=0;c--)if(!a.contains(this.currentItem[0],this.containers[c].element[0]))if(this._intersectsWith(this.containers[c].containerCache)){if(m&&a.contains(this.containers[c].element[0],m.element[0]))continue;m=this.containers[c],n=c}else this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",b,this._uiHash(this)),this.containers[c].containerCache.over=0);if(m)if(1===this.containers.length)this.containers[n].containerCache.over||(this.containers[n]._trigger("over",b,this._uiHash(this)),this.containers[n].containerCache.over=1);else{for(e=1e4,f=null,k=m.floating||this._isFloating(this.currentItem),g=k?"left":"top",h=k?"width":"height",l=k?"clientX":"clientY",d=this.items.length-1;d>=0;d--)a.contains(this.containers[n].element[0],this.items[d].item[0])&&this.items[d].item[0]!==this.currentItem[0]&&(i=this.items[d].item.offset()[g],j=!1,b[l]-i>this.items[d][h]/2&&(j=!0),Math.abs(b[l]-i)this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top)),e.grid&&(c=this.originalPageY+Math.round((g-this.originalPageY)/e.grid[1])*e.grid[1],g=this.containment?c-this.offset.click.top>=this.containment[1]&&c-this.offset.click.top<=this.containment[3]?c:c-this.offset.click.top>=this.containment[1]?c-e.grid[1]:c+e.grid[1]:c,d=this.originalPageX+Math.round((f-this.originalPageX)/e.grid[0])*e.grid[0],f=this.containment?d-this.offset.click.left>=this.containment[0]&&d-this.offset.click.left<=this.containment[2]?d:d-this.offset.click.left>=this.containment[0]?d-e.grid[0]:d+e.grid[0]:d)),{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():i?0:h.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():i?0:h.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this.counter;this._delay(function(){e===this.counter&&this.refreshPositions(!d)})},_clear:function(a,b){function c(a,b,c){return function(d){c._trigger(a,d,b._uiHash(b))}}this.reverting=!1;var d,e=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(d in this._storedCSS)("auto"===this._storedCSS[d]||"static"===this._storedCSS[d])&&(this._storedCSS[d]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!b&&e.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||b||e.push(function(a){this._trigger("update",a,this._uiHash())}),this!==this.currentContainer&&(b||(e.push(function(a){this._trigger("remove",a,this._uiHash())}),e.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.currentContainer)),e.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.currentContainer)))),d=this.containers.length-1;d>=0;d--)b||e.push(c("deactivate",this,this.containers[d])),this.containers[d].containerCache.over&&(e.push(c("out",this,this.containers[d])),this.containers[d].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,b||this._trigger("beforeStop",a,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!b){for(d=0;d",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var b={},c=this.element;return a.each(["min","max","step"],function(a,d){var e=c.attr(d);void 0!==e&&e.length&&(b[d]=e)}),b},_events:{keydown:function(a){this._start(a)&&this._keydown(a)&&a.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(a){return this.cancelBlur?void delete this.cancelBlur:(this._stop(),this._refresh(),void(this.previous!==this.element.val()&&this._trigger("change",a)))},mousewheel:function(a,b){if(b){if(!this.spinning&&!this._start(a))return!1;this._spin((b>0?1:-1)*this.options.step,a),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(a)},100),a.preventDefault()}},"mousedown .ui-spinner-button":function(b){function c(){var a=this.element[0]===this.document[0].activeElement;a||(this.element.focus(),this.previous=d,this._delay(function(){this.previous=d}))}var d;d=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),b.preventDefault(),c.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,c.call(this)}),this._start(b)!==!1&&this._repeat(null,a(b.currentTarget).hasClass("ui-spinner-up")?1:-1,b)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(b){return a(b.currentTarget).hasClass("ui-state-active")?this._start(b)===!1?!1:void this._repeat(null,a(b.currentTarget).hasClass("ui-spinner-up")?1:-1,b):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var a=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=a.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*a.height())&&a.height()>0&&a.height(a.height()),this.options.disabled&&this.disable()},_keydown:function(b){var c=this.options,d=a.ui.keyCode;switch(b.keyCode){case d.UP:return this._repeat(null,1,b),!0;case d.DOWN:return this._repeat(null,-1,b),!0;case d.PAGE_UP:return this._repeat(null,c.page,b),!0;case d.PAGE_DOWN:return this._repeat(null,-c.page,b),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""},_start:function(a){return this.spinning||this._trigger("start",a)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(a,b,c){a=a||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,b,c)},a),this._spin(b*this.options.step,c)},_spin:function(a,b){var c=this.value()||0;this.counter||(this.counter=1),c=this._adjustValue(c+a*this._increment(this.counter)),this.spinning&&this._trigger("spin",b,{value:c})===!1||(this._value(c),this.counter++)},_increment:function(b){var c=this.options.incremental;return c?a.isFunction(c)?c(b):Math.floor(b*b*b/5e4-b*b/500+17*b/200+1):1},_precision:function(){var a=this._precisionOf(this.options.step);return null!==this.options.min&&(a=Math.max(a,this._precisionOf(this.options.min))),a},_precisionOf:function(a){var b=a.toString(),c=b.indexOf(".");return-1===c?0:b.length-c-1},_adjustValue:function(a){var b,c,d=this.options;return b=null!==d.min?d.min:0,c=a-b,c=Math.round(c/d.step)*d.step,a=b+c,a=parseFloat(a.toFixed(this._precision())),null!==d.max&&a>d.max?d.max:null!==d.min&&a1&&c===d}}(),_create:function(){var b=this,c=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",c.collapsible),this._processTabs(),c.active=this._initialActive(),a.isArray(c.disabled)&&(c.disabled=a.unique(c.disabled.concat(a.map(this.tabs.filter(".ui-state-disabled"),function(a){return b.tabs.index(a)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(c.active):a(),this._refresh(),this.active.length&&this.load(c.active)},_initialActive:function(){var b=this.options.active,c=this.options.collapsible,d=location.hash.substring(1);return null===b&&(d&&this.tabs.each(function(c,e){return a(e).attr("aria-controls")===d?(b=c,!1):void 0}),null===b&&(b=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===b||-1===b)&&(b=this.tabs.length?0:!1)),b!==!1&&(b=this.tabs.index(this.tabs.eq(b)),-1===b&&(b=c?!1:0)),!c&&b===!1&&this.anchors.length&&(b=0),b},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):a()}},_tabKeydown:function(b){ +var c=a(this.document[0].activeElement).closest("li"),d=this.tabs.index(c),e=!0;if(!this._handlePageNav(b)){switch(b.keyCode){case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:d++;break;case a.ui.keyCode.UP:case a.ui.keyCode.LEFT:e=!1,d--;break;case a.ui.keyCode.END:d=this.anchors.length-1;break;case a.ui.keyCode.HOME:d=0;break;case a.ui.keyCode.SPACE:return b.preventDefault(),clearTimeout(this.activating),void this._activate(d);case a.ui.keyCode.ENTER:return b.preventDefault(),clearTimeout(this.activating),void this._activate(d===this.options.active?!1:d);default:return}b.preventDefault(),clearTimeout(this.activating),d=this._focusNextTab(d,e),b.ctrlKey||b.metaKey||(c.attr("aria-selected","false"),this.tabs.eq(d).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",d)},this.delay))}},_panelKeydown:function(b){this._handlePageNav(b)||b.ctrlKey&&b.keyCode===a.ui.keyCode.UP&&(b.preventDefault(),this.active.focus())},_handlePageNav:function(b){return b.altKey&&b.keyCode===a.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):b.altKey&&b.keyCode===a.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(b,c){function d(){return b>e&&(b=0),0>b&&(b=e),b}for(var e=this.tabs.length-1;-1!==a.inArray(d(),this.options.disabled);)b=c?b+1:b-1;return b},_focusNextTab:function(a,b){return a=this._findNextTab(a,b),this.tabs.eq(a).focus(),a},_setOption:function(a,b){return"active"===a?void this._activate(b):"disabled"===a?void this._setupDisabled(b):(this._super(a,b),"collapsible"===a&&(this.element.toggleClass("ui-tabs-collapsible",b),b||this.options.active!==!1||this._activate(0)),"event"===a&&this._setupEvents(b),void("heightStyle"===a&&this._setupHeightStyle(b)))},_sanitizeSelector:function(a){return a?a.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var b=this.options,c=this.tablist.children(":has(a[href])");b.disabled=a.map(c.filter(".ui-state-disabled"),function(a){return c.index(a)}),this._processTabs(),b.active!==!1&&this.anchors.length?this.active.length&&!a.contains(this.tablist[0],this.active[0])?this.tabs.length===b.disabled.length?(b.active=!1,this.active=a()):this._activate(this._findNextTab(Math.max(0,b.active-1),!1)):b.active=this.tabs.index(this.active):(b.active=!1,this.active=a()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var b=this,c=this.tabs,d=this.anchors,e=this.panels;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist").delegate("> li","mousedown"+this.eventNamespace,function(b){a(this).is(".ui-state-disabled")&&b.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){a(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return a("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=a(),this.anchors.each(function(c,d){var e,f,g,h=a(d).uniqueId().attr("id"),i=a(d).closest("li"),j=i.attr("aria-controls");b._isLocal(d)?(e=d.hash,g=e.substring(1),f=b.element.find(b._sanitizeSelector(e))):(g=i.attr("aria-controls")||a({}).uniqueId()[0].id,e="#"+g,f=b.element.find(e),f.length||(f=b._createPanel(g),f.insertAfter(b.panels[c-1]||b.tablist)),f.attr("aria-live","polite")),f.length&&(b.panels=b.panels.add(f)),j&&i.data("ui-tabs-aria-controls",j),i.attr({"aria-controls":g,"aria-labelledby":h}),f.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel"),c&&(this._off(c.not(this.tabs)),this._off(d.not(this.anchors)),this._off(e.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(b){return a("
        ").attr("id",b).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(b){a.isArray(b)&&(b.length?b.length===this.anchors.length&&(b=!0):b=!1);for(var c,d=0;c=this.tabs[d];d++)b===!0||-1!==a.inArray(d,b)?a(c).addClass("ui-state-disabled").attr("aria-disabled","true"):a(c).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=b},_setupEvents:function(b){var c={};b&&a.each(b.split(" "),function(a,b){c[b]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(a){a.preventDefault()}}),this._on(this.anchors,c),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(b){var c,d=this.element.parent();"fill"===b?(c=d.height(),c-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var b=a(this),d=b.css("position");"absolute"!==d&&"fixed"!==d&&(c-=b.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){c-=a(this).outerHeight(!0)}),this.panels.each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")):"auto"===b&&(c=0,this.panels.each(function(){c=Math.max(c,a(this).height("").height())}).height(c))},_eventHandler:function(b){var c=this.options,d=this.active,e=a(b.currentTarget),f=e.closest("li"),g=f[0]===d[0],h=g&&c.collapsible,i=h?a():this._getPanelForTab(f),j=d.length?this._getPanelForTab(d):a(),k={oldTab:d,oldPanel:j,newTab:h?a():f,newPanel:i};b.preventDefault(),f.hasClass("ui-state-disabled")||f.hasClass("ui-tabs-loading")||this.running||g&&!c.collapsible||this._trigger("beforeActivate",b,k)===!1||(c.active=h?!1:this.tabs.index(f),this.active=g?a():f,this.xhr&&this.xhr.abort(),j.length||i.length||a.error("jQuery UI Tabs: Mismatching fragment identifier."),i.length&&this.load(this.tabs.index(f),b),this._toggle(b,k))},_toggle:function(b,c){function d(){f.running=!1,f._trigger("activate",b,c)}function e(){c.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),g.length&&f.options.show?f._show(g,f.options.show,d):(g.show(),d())}var f=this,g=c.newPanel,h=c.oldPanel;this.running=!0,h.length&&this.options.hide?this._hide(h,this.options.hide,function(){c.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),e()}):(c.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),h.hide(),e()),h.attr("aria-hidden","true"),c.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),g.length&&h.length?c.oldTab.attr("tabIndex",-1):g.length&&this.tabs.filter(function(){return 0===a(this).attr("tabIndex")}).attr("tabIndex",-1),g.attr("aria-hidden","false"),c.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(b){var c,d=this._findActive(b);d[0]!==this.active[0]&&(d.length||(d=this.active),c=d.find(".ui-tabs-anchor")[0],this._eventHandler({target:c,currentTarget:c,preventDefault:a.noop}))},_findActive:function(b){return b===!1?a():this.tabs.eq(b)},_getIndex:function(a){return"string"==typeof a&&(a=this.anchors.index(this.anchors.filter("[href$='"+a+"']"))),a},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tablist.unbind(this.eventNamespace),this.tabs.add(this.panels).each(function(){a.data(this,"ui-tabs-destroy")?a(this).remove():a(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var b=a(this),c=b.data("ui-tabs-aria-controls");c?b.attr("aria-controls",c).removeData("ui-tabs-aria-controls"):b.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(b){var c=this.options.disabled;c!==!1&&(void 0===b?c=!1:(b=this._getIndex(b),c=a.isArray(c)?a.map(c,function(a){return a!==b?a:null}):a.map(this.tabs,function(a,c){return c!==b?c:null})),this._setupDisabled(c))},disable:function(b){var c=this.options.disabled;if(c!==!0){if(void 0===b)c=!0;else{if(b=this._getIndex(b),-1!==a.inArray(b,c))return;c=a.isArray(c)?a.merge([b],c).sort():[b]}this._setupDisabled(c)}},load:function(b,c){b=this._getIndex(b);var d=this,e=this.tabs.eq(b),f=e.find(".ui-tabs-anchor"),g=this._getPanelForTab(e),h={tab:e,panel:g},i=function(a,b){"abort"===b&&d.panels.stop(!1,!0),e.removeClass("ui-tabs-loading"),g.removeAttr("aria-busy"),a===d.xhr&&delete d.xhr};this._isLocal(f[0])||(this.xhr=a.ajax(this._ajaxSettings(f,c,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(e.addClass("ui-tabs-loading"),g.attr("aria-busy","true"),this.xhr.done(function(a,b,e){setTimeout(function(){g.html(a),d._trigger("load",c,h),i(e,b)},1)}).fail(function(a,b){setTimeout(function(){i(a,b)},1)})))},_ajaxSettings:function(b,c,d){var e=this;return{url:b.attr("href"),beforeSend:function(b,f){return e._trigger("beforeLoad",c,a.extend({jqXHR:b,ajaxSettings:f},d))}}},_getPanelForTab:function(b){var c=a(b).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+c))}}),a.widget("ui.tooltip",{version:"1.11.4",options:{content:function(){var b=a(this).attr("title")||"";return a("").text(b).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_addDescribedBy:function(b,c){var d=(b.attr("aria-describedby")||"").split(/\s+/);d.push(c),b.data("ui-tooltip-id",c).attr("aria-describedby",a.trim(d.join(" ")))},_removeDescribedBy:function(b){var c=b.data("ui-tooltip-id"),d=(b.attr("aria-describedby")||"").split(/\s+/),e=a.inArray(c,d);-1!==e&&d.splice(e,1),b.removeData("ui-tooltip-id"),d=a.trim(d.join(" ")),d?b.attr("aria-describedby",d):b.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable(),this.liveRegion=a("
        ").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body)},_setOption:function(b,c){var d=this;return"disabled"===b?(this[c?"_disable":"_enable"](),void(this.options[b]=c)):(this._super(b,c),void("content"===b&&a.each(this.tooltips,function(a,b){d._updateContent(b.element)})))},_disable:function(){var b=this;a.each(this.tooltips,function(c,d){var e=a.Event("blur");e.target=e.currentTarget=d.element[0],b.close(e,!0)}),this.element.find(this.options.items).addBack().each(function(){var b=a(this);b.is("[title]")&&b.data("ui-tooltip-title",b.attr("title")).removeAttr("title")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var b=a(this);b.data("ui-tooltip-title")&&b.attr("title",b.data("ui-tooltip-title"))})},open:function(b){var c=this,d=a(b?b.target:this.element).closest(this.options.items);d.length&&!d.data("ui-tooltip-id")&&(d.attr("title")&&d.data("ui-tooltip-title",d.attr("title")),d.data("ui-tooltip-open",!0),b&&"mouseover"===b.type&&d.parents().each(function(){var b,d=a(this);d.data("ui-tooltip-open")&&(b=a.Event("blur"),b.target=b.currentTarget=this,c.close(b,!0)),d.attr("title")&&(d.uniqueId(),c.parents[this.id]={element:this,title:d.attr("title")},d.attr("title",""))}),this._registerCloseHandlers(b,d),this._updateContent(d,b))},_updateContent:function(a,b){var c,d=this.options.content,e=this,f=b?b.type:null;return"string"==typeof d?this._open(b,a,d):(c=d.call(a[0],function(c){e._delay(function(){a.data("ui-tooltip-open")&&(b&&(b.type=f),this._open(b,a,c))})}),void(c&&this._open(b,a,c)))},_open:function(b,c,d){function e(a){j.of=a,g.is(":hidden")||g.position(j)}var f,g,h,i,j=a.extend({},this.options.position);if(d){if(f=this._find(c))return void f.tooltip.find(".ui-tooltip-content").html(d);c.is("[title]")&&(b&&"mouseover"===b.type?c.attr("title",""):c.removeAttr("title")),f=this._tooltip(c),g=f.tooltip,this._addDescribedBy(c,g.attr("id")),g.find(".ui-tooltip-content").html(d),this.liveRegion.children().hide(),d.clone?(i=d.clone(),i.removeAttr("id").find("[id]").removeAttr("id")):i=d,a("
        ").html(i).appendTo(this.liveRegion),this.options.track&&b&&/^mouse/.test(b.type)?(this._on(this.document,{mousemove:e}),e(b)):g.position(a.extend({of:c},this.options.position)),g.hide(),this._show(g,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){g.is(":visible")&&(e(j.of),clearInterval(h))},a.fx.interval)),this._trigger("open",b,{tooltip:g})}},_registerCloseHandlers:function(b,c){var d={keyup:function(b){if(b.keyCode===a.ui.keyCode.ESCAPE){var d=a.Event(b);d.currentTarget=c[0],this.close(d,!0)}}};c[0]!==this.element[0]&&(d.remove=function(){this._removeTooltip(this._find(c).tooltip)}),b&&"mouseover"!==b.type||(d.mouseleave="close"),b&&"focusin"!==b.type||(d.focusout="close"),this._on(!0,c,d)},close:function(b){var c,d=this,e=a(b?b.currentTarget:this.element),f=this._find(e);return f?(c=f.tooltip,void(f.closing||(clearInterval(this.delayedShow),e.data("ui-tooltip-title")&&!e.attr("title")&&e.attr("title",e.data("ui-tooltip-title")),this._removeDescribedBy(e),f.hiding=!0,c.stop(!0),this._hide(c,this.options.hide,function(){d._removeTooltip(a(this))}),e.removeData("ui-tooltip-open"),this._off(e,"mouseleave focusout keyup"),e[0]!==this.element[0]&&this._off(e,"remove"),this._off(this.document,"mousemove"),b&&"mouseleave"===b.type&&a.each(this.parents,function(b,c){a(c.element).attr("title",c.title),delete d.parents[b]}),f.closing=!0,this._trigger("close",b,{tooltip:c}),f.hiding||(f.closing=!1)))):void e.removeData("ui-tooltip-open")},_tooltip:function(b){var c=a("
        ").attr("role","tooltip").addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||"")),d=c.uniqueId().attr("id");return a("
        ").addClass("ui-tooltip-content").appendTo(c),c.appendTo(this.document[0].body),this.tooltips[d]={element:b,tooltip:c}},_find:function(a){var b=a.data("ui-tooltip-id");return b?this.tooltips[b]:null},_removeTooltip:function(a){a.remove(),delete this.tooltips[a.attr("id")]},_destroy:function(){var b=this;a.each(this.tooltips,function(c,d){var e=a.Event("blur"),f=d.element;e.target=e.currentTarget=f[0],b.close(e,!0),a("#"+c).remove(),f.data("ui-tooltip-title")&&(f.attr("title")||f.attr("title",f.data("ui-tooltip-title")),f.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}})}),function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(b.target).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d,e;return c.settings.submitHandler?(c.submitButton&&(d=a("").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c;return a(this[0]).is("form")?b=this.validate().form():(b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b})),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(a,b){(9!==b.which||""!==this.elementValue(a))&&(a.name in this.submitted||a===this.lastElement)&&this.element(a)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!this.is(e.ignore)&&e[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']","focusin focusout keyup",b).validateDelegate("select, option, [type='radio'], [type='checkbox']","click",b),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue").removeAttr("aria-invalid")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled], [readonly]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?a("input[name='"+b.name+"']:checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+"")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\])/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),/min|max/.test(c)&&(null===g||/number|range|text/.test(g))&&(d=Number(d)),d||0===d?e[c]=d:g===c&&"range"!==g&&(e[c]=!0);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b);for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),void 0!==d&&(e[c]=d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/), +b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}}),a.format=function(){throw"$.format has been deprecated. Please use $.validator.format instead."};var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);return e.is(b)?d.apply(e,arguments):void 0})}})}),function(a){var b=!1;if("function"==typeof define&&define.amd&&(define(a),b=!0),"object"==typeof exports&&(module.exports=a(),b=!0),!b){var c=window.Cookies,d=window.Cookies=a();d.noConflict=function(){return window.Cookies=c,d}}}(function(){function a(){for(var a=0,b={};a1){if(f=a({path:"/"},d.defaults,f),"number"==typeof f.expires){var h=new Date;h.setMilliseconds(h.getMilliseconds()+864e5*f.expires),f.expires=h}try{g=JSON.stringify(e),/^[\{\[]/.test(g)&&(e=g)}catch(i){}return e=c.write?c.write(e,b):encodeURIComponent(String(e)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),b=encodeURIComponent(String(b)),b=b.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),b=b.replace(/[\(\)]/g,escape),document.cookie=[b,"=",e,f.expires?"; expires="+f.expires.toUTCString():"",f.path?"; path="+f.path:"",f.domain?"; domain="+f.domain:"",f.secure?"; secure":""].join("")}b||(g={});for(var j=document.cookie?document.cookie.split("; "):[],k=/(%[0-9A-Z]{2})+/g,l=0;l {1} {2}
        '};String.format=function(){for(var a=arguments[0],b=1;b .progress-bar').removeClass("progress-bar-"+a.settings.type),a.settings.type=d[b],this.$ele.addClass("alert-"+d[b]).find('[data-notify="progressbar"] > .progress-bar').addClass("progress-bar-"+d[b]);break;case"icon":var e=this.$ele.find('[data-notify="icon"]');"class"==a.settings.icon_type.toLowerCase()?e.removeClass(a.settings.content.icon).addClass(d[b]):(e.is("img")||e.find("img"),e.attr("src",d[b]));break;case"progress":var f=a.settings.delay-a.settings.delay*(d[b]/100);this.$ele.data("notify-delay",f),this.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",d[b]).css("width",d[b]+"%");break;case"url":this.$ele.find('[data-notify="url"]').attr("href",d[b]);break;case"target":this.$ele.find('[data-notify="url"]').attr("target",d[b]);break;default:this.$ele.find('[data-notify="'+b+'"]').html(d[b])}var g=this.$ele.outerHeight()+parseInt(a.settings.spacing)+parseInt(a.settings.offset.y);a.reposition(g)},close:function(){a.close()}}},buildNotify:function(){var b=this.settings.content;this.$ele=a(String.format(this.settings.template,this.settings.type,b.title,b.message,b.url,b.target)),this.$ele.attr("data-notify-position",this.settings.placement.from+"-"+this.settings.placement.align),this.settings.allow_dismiss||this.$ele.find('[data-notify="dismiss"]').css("display","none"),(this.settings.delay<=0&&!this.settings.showProgressbar||!this.settings.showProgressbar)&&this.$ele.find('[data-notify="progressbar"]').remove()},setIcon:function(){"class"==this.settings.icon_type.toLowerCase()?this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon):this.$ele.find('[data-notify="icon"]').is("img")?this.$ele.find('[data-notify="icon"]').attr("src",this.settings.content.icon):this.$ele.find('[data-notify="icon"]').append('Notify Icon')},styleURL:function(){this.$ele.find('[data-notify="url"]').css({backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)",height:"100%",left:"0px",position:"absolute",top:"0px",width:"100%",zIndex:this.settings.z_index+1}),this.$ele.find('[data-notify="dismiss"]').css({position:"absolute",right:"10px",top:"5px",zIndex:this.settings.z_index+2})},placement:function(){var b=this,c=this.settings.offset.y,d={display:"inline-block",margin:"0px auto",position:this.settings.position?this.settings.position:"body"===this.settings.element?"fixed":"absolute",transition:"all .5s ease-in-out",zIndex:this.settings.z_index},e=!1,f=this.settings;switch(a('[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])').each(function(){return c=Math.max(c,parseInt(a(this).css(f.placement.from))+parseInt(a(this).outerHeight())+parseInt(f.spacing))}),1==this.settings.newest_on_top&&(c=this.settings.offset.y),d[this.settings.placement.from]=c+"px",this.settings.placement.align){case"left":case"right":d[this.settings.placement.align]=this.settings.offset.x+"px";break;case"center":d.left=0,d.right=0}this.$ele.css(d).addClass(this.settings.animate.enter),a.each(Array("webkit","moz","o","ms",""),function(a,c){b.$ele[0].style[c+"AnimationIterationCount"]=1}),a(this.settings.element).append(this.$ele),1==this.settings.newest_on_top&&(c=parseInt(c)+parseInt(this.settings.spacing)+this.$ele.outerHeight(),this.reposition(c)),a.isFunction(b.settings.onShow)&&b.settings.onShow.call(this.$ele),this.$ele.one(this.animations.start,function(){e=!0}).one(this.animations.end,function(){a.isFunction(b.settings.onShown)&&b.settings.onShown.call(this)}),setTimeout(function(){e||a.isFunction(b.settings.onShown)&&b.settings.onShown.call(this)},600)},bind:function(){var b=this;if(this.$ele.find('[data-notify="dismiss"]').on("click",function(){b.close()}),this.$ele.mouseover(function(){a(this).data("data-hover","true")}).mouseout(function(){a(this).data("data-hover","false")}),this.$ele.data("data-hover","false"),this.settings.delay>0){b.$ele.data("notify-delay",b.settings.delay);var c=setInterval(function(){var a=parseInt(b.$ele.data("notify-delay"))-b.settings.timer;if("false"===b.$ele.data("data-hover")&&"pause"==b.settings.mouse_over||"pause"!=b.settings.mouse_over){var d=(b.settings.delay-a)/b.settings.delay*100;b.$ele.data("notify-delay",a),b.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",d).css("width",d+"%")}a<=-b.settings.timer&&(clearInterval(c),b.close())},b.settings.timer)}},close:function(){var b=this,c=parseInt(this.$ele.css(this.settings.placement.from)),d=!1;this.$ele.data("closing","true").addClass(this.settings.animate.exit),b.reposition(c),a.isFunction(b.settings.onClose)&&b.settings.onClose.call(this.$ele),this.$ele.one(this.animations.start,function(){d=!0}).one(this.animations.end,function(){a(this).remove(),a.isFunction(b.settings.onClosed)&&b.settings.onClosed.call(this)}),setTimeout(function(){d||(b.$ele.remove(),b.settings.onClosed&&b.settings.onClosed(b.$ele))},600)},reposition:function(b){var c=this,d='[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])',e=this.$ele.nextAll(d);1==this.settings.newest_on_top&&(e=this.$ele.prevAll(d)),e.each(function(){a(this).css(c.settings.placement.from,b),b=parseInt(b)+parseInt(c.settings.spacing)+a(this).outerHeight()})}}),a.notify=function(a,c){var d=new b(this,a,c);return d.notify},a.notifyDefaults=function(b){return c=a.extend(!0,{},c,b)},a.notifyClose=function(b){"undefined"==typeof b||"all"==b?a("[data-notify]").find('[data-notify="dismiss"]').trigger("click"):a('[data-notify-position="'+b+'"]').find('[data-notify="dismiss"]').trigger("click")}}),function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a,b){function c(){return new Date(Date.UTC.apply(Date,arguments))}"indexOf"in Array.prototype||(Array.prototype.indexOf=function(a,c){c===b&&(c=0),0>c&&(c+=this.length),0>c&&(c=0);for(var d=this.length;d>c;c++)if(c in this&&this[c]===a)return c;return-1});var d=function(c,d){var e=this;this.element=a(c),this.container=d.container||"body",this.language=d.language||this.element.data("date-language")||"en",this.language=this.language in f?this.language:this.language.split("-")[0],this.language=this.language in f?this.language:"en",this.isRTL=f[this.language].rtl||!1,this.formatType=d.formatType||this.element.data("format-type")||"standard",this.format=g.parseFormat(d.format||this.element.data("date-format")||f[this.language].format||g.getDefaultFormat(this.formatType,"input"),this.formatType),this.isInline=!1,this.isVisible=!1,this.isInput=this.element.is("input"),this.fontAwesome=d.fontAwesome||this.element.data("font-awesome")||!1,this.bootcssVer=d.bootcssVer||(this.isInput?this.element.is(".form-control")?3:2:this.bootcssVer=this.element.is(".input-group")?3:2),this.component=this.element.is(".date")?3==this.bootcssVer?this.element.find(".input-group-addon .glyphicon-th, .input-group-addon .glyphicon-time, .input-group-addon .glyphicon-remove, .input-group-addon .glyphicon-calendar, .input-group-addon .fa-calendar, .input-group-addon .fa-clock-o").parent():this.element.find(".add-on .icon-th, .add-on .icon-time, .add-on .icon-calendar, .add-on .fa-calendar, .add-on .fa-clock-o").parent():!1,this.componentReset=this.element.is(".date")?3==this.bootcssVer?this.element.find(".input-group-addon .glyphicon-remove, .input-group-addon .fa-times").parent():this.element.find(".add-on .icon-remove, .add-on .fa-times").parent():!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&0===this.component.length&&(this.component=!1),this.linkField=d.linkField||this.element.data("link-field")||!1,this.linkFormat=g.parseFormat(d.linkFormat||this.element.data("link-format")||g.getDefaultFormat(this.formatType,"link"),this.formatType),this.minuteStep=d.minuteStep||this.element.data("minute-step")||5,this.pickerPosition=d.pickerPosition||this.element.data("picker-position")||"bottom-right",this.showMeridian=d.showMeridian||this.element.data("show-meridian")||!1,this.initialDate=d.initialDate||new Date,this.zIndex=d.zIndex||this.element.data("z-index")||b,this.title="undefined"==typeof d.title?!1:d.title,this.defaultTimeZone=(new Date).toString().split("(")[1].slice(0,-1),this.timezone=d.timezone||this.defaultTimeZone,this.icons={leftArrow:this.fontAwesome?"fa-arrow-left":3===this.bootcssVer?"glyphicon-arrow-left":"icon-arrow-left",rightArrow:this.fontAwesome?"fa-arrow-right":3===this.bootcssVer?"glyphicon-arrow-right":"icon-arrow-right"},this.icontype=this.fontAwesome?"fa":"glyphicon",this._attachEvents(),this.clickedOutside=function(b){0===a(b.target).closest(".datetimepicker").length&&e.hide()},this.formatViewType="datetime","formatViewType"in d?this.formatViewType=d.formatViewType:"formatViewType"in this.element.data()&&(this.formatViewType=this.element.data("formatViewType")),this.minView=0,"minView"in d?this.minView=d.minView:"minView"in this.element.data()&&(this.minView=this.element.data("min-view")),this.minView=g.convertViewMode(this.minView),this.maxView=g.modes.length-1,"maxView"in d?this.maxView=d.maxView:"maxView"in this.element.data()&&(this.maxView=this.element.data("max-view")),this.maxView=g.convertViewMode(this.maxView),this.wheelViewModeNavigation=!1,"wheelViewModeNavigation"in d?this.wheelViewModeNavigation=d.wheelViewModeNavigation:"wheelViewModeNavigation"in this.element.data()&&(this.wheelViewModeNavigation=this.element.data("view-mode-wheel-navigation")),this.wheelViewModeNavigationInverseDirection=!1,"wheelViewModeNavigationInverseDirection"in d?this.wheelViewModeNavigationInverseDirection=d.wheelViewModeNavigationInverseDirection:"wheelViewModeNavigationInverseDirection"in this.element.data()&&(this.wheelViewModeNavigationInverseDirection=this.element.data("view-mode-wheel-navigation-inverse-dir")),this.wheelViewModeNavigationDelay=100,"wheelViewModeNavigationDelay"in d?this.wheelViewModeNavigationDelay=d.wheelViewModeNavigationDelay:"wheelViewModeNavigationDelay"in this.element.data()&&(this.wheelViewModeNavigationDelay=this.element.data("view-mode-wheel-navigation-delay")),this.startViewMode=2,"startView"in d?this.startViewMode=d.startView:"startView"in this.element.data()&&(this.startViewMode=this.element.data("start-view")),this.startViewMode=g.convertViewMode(this.startViewMode),this.viewMode=this.startViewMode,this.viewSelect=this.minView,"viewSelect"in d?this.viewSelect=d.viewSelect:"viewSelect"in this.element.data()&&(this.viewSelect=this.element.data("view-select")),this.viewSelect=g.convertViewMode(this.viewSelect),this.forceParse=!0,"forceParse"in d?this.forceParse=d.forceParse:"dateForceParse"in this.element.data()&&(this.forceParse=this.element.data("date-force-parse"));for(var h=3===this.bootcssVer?g.templateV3:g.template;-1!==h.indexOf("{iconType}");)h=h.replace("{iconType}",this.icontype);for(;-1!==h.indexOf("{leftArrow}");)h=h.replace("{leftArrow}",this.icons.leftArrow);for(;-1!==h.indexOf("{rightArrow}");)h=h.replace("{rightArrow}",this.icons.rightArrow);if(this.picker=a(h).appendTo(this.isInline?this.element:this.container).on({click:a.proxy(this.click,this),mousedown:a.proxy(this.mousedown,this)}),this.wheelViewModeNavigation&&(a.fn.mousewheel?this.picker.on({mousewheel:a.proxy(this.mousewheel,this)}):console.log("Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option")),this.picker.addClass(this.isInline?"datetimepicker-inline":"datetimepicker-dropdown-"+this.pickerPosition+" dropdown-menu"),this.isRTL){this.picker.addClass("datetimepicker-rtl");var i=3===this.bootcssVer?".prev span, .next span":".prev i, .next i";this.picker.find(i).toggleClass(this.icons.leftArrow+" "+this.icons.rightArrow)}a(document).on("mousedown",this.clickedOutside),this.autoclose=!1,"autoclose"in d?this.autoclose=d.autoclose:"dateAutoclose"in this.element.data()&&(this.autoclose=this.element.data("date-autoclose")),this.keyboardNavigation=!0,"keyboardNavigation"in d?this.keyboardNavigation=d.keyboardNavigation:"dateKeyboardNavigation"in this.element.data()&&(this.keyboardNavigation=this.element.data("date-keyboard-navigation")),this.todayBtn=d.todayBtn||this.element.data("date-today-btn")||!1,this.clearBtn=d.clearBtn||this.element.data("date-clear-btn")||!1,this.todayHighlight=d.todayHighlight||this.element.data("date-today-highlight")||!1,this.weekStart=(d.weekStart||this.element.data("date-weekstart")||f[this.language].weekStart||0)%7,this.weekEnd=(this.weekStart+6)%7,this.startDate=-(1/0),this.endDate=1/0,this.datesDisabled=[],this.daysOfWeekDisabled=[],this.setStartDate(d.startDate||this.element.data("date-startdate")),this.setEndDate(d.endDate||this.element.data("date-enddate")),this.setDatesDisabled(d.datesDisabled||this.element.data("date-dates-disabled")),this.setDaysOfWeekDisabled(d.daysOfWeekDisabled||this.element.data("date-days-of-week-disabled")),this.setMinutesDisabled(d.minutesDisabled||this.element.data("date-minute-disabled")),this.setHoursDisabled(d.hoursDisabled||this.element.data("date-hour-disabled")),this.fillDow(),this.fillMonths(),this.update(),this.showMode(),this.isInline&&this.show()};d.prototype={constructor:d,_events:[],_attachEvents:function(){this._detachEvents(),this.isInput?this._events=[[this.element,{focus:a.proxy(this.show,this),keyup:a.proxy(this.update,this),keydown:a.proxy(this.keydown,this)}]]:this.component&&this.hasInput?(this._events=[[this.element.find("input"),{focus:a.proxy(this.show,this),keyup:a.proxy(this.update,this),keydown:a.proxy(this.keydown,this)}],[this.component,{click:a.proxy(this.show,this)}]],this.componentReset&&this._events.push([this.componentReset,{click:a.proxy(this.reset,this)}])):this.element.is("div")?this.isInline=!0:this._events=[[this.element,{click:a.proxy(this.show,this)}]];for(var b,c,d=0;d=this.startDate&&a<=this.endDate?(this.date=a,this.setValue(),this.viewDate=this.date,this.fill()):this.element.trigger({type:"outOfRange",date:a,startDate:this.startDate,endDate:this.endDate})},setFormat:function(a){this.format=g.parseFormat(a,this.formatType);var b;this.isInput?b=this.element:this.component&&(b=this.element.find("input")),b&&b.val()&&this.setValue()},setValue:function(){var b=this.getFormattedDate();this.isInput?this.element.val(b):(this.component&&this.element.find("input").val(b),this.element.data("date",b)),this.linkField&&a("#"+this.linkField).val(this.getFormattedDate(this.linkFormat))},getFormattedDate:function(a){return a==b&&(a=this.format),g.formatDate(this.date,a,this.language,this.formatType,this.timezone)},setStartDate:function(a){this.startDate=a||-(1/0),this.startDate!==-(1/0)&&(this.startDate=g.parseDate(this.startDate,this.format,this.language,this.formatType,this.timezone)),this.update(),this.updateNavArrows()},setEndDate:function(a){this.endDate=a||1/0,this.endDate!==1/0&&(this.endDate=g.parseDate(this.endDate,this.format,this.language,this.formatType,this.timezone)),this.update(),this.updateNavArrows()},setDatesDisabled:function(b){this.datesDisabled=b||[],a.isArray(this.datesDisabled)||(this.datesDisabled=this.datesDisabled.split(/,\s*/)),this.datesDisabled=a.map(this.datesDisabled,function(a){return g.parseDate(a,this.format,this.language,this.formatType,this.timezone).toDateString()}),this.update(),this.updateNavArrows()},setTitle:function(a,b){return this.picker.find(a).find("th:eq(1)").text(this.title===!1?b:this.title)},setDaysOfWeekDisabled:function(b){this.daysOfWeekDisabled=b||[],a.isArray(this.daysOfWeekDisabled)||(this.daysOfWeekDisabled=this.daysOfWeekDisabled.split(/,\s*/)),this.daysOfWeekDisabled=a.map(this.daysOfWeekDisabled,function(a){return parseInt(a,10)}),this.update(),this.updateNavArrows()},setMinutesDisabled:function(b){this.minutesDisabled=b||[],a.isArray(this.minutesDisabled)||(this.minutesDisabled=this.minutesDisabled.split(/,\s*/)),this.minutesDisabled=a.map(this.minutesDisabled,function(a){return parseInt(a,10)}),this.update(),this.updateNavArrows()},setHoursDisabled:function(b){this.hoursDisabled=b||[],a.isArray(this.hoursDisabled)||(this.hoursDisabled=this.hoursDisabled.split(/,\s*/)),this.hoursDisabled=a.map(this.hoursDisabled,function(a){return parseInt(a,10)}),this.update(),this.updateNavArrows()},place:function(){if(!this.isInline){if(!this.zIndex){var b=0;a("div").each(function(){var c=parseInt(a(this).css("zIndex"),10);c>b&&(b=c)}),this.zIndex=b+10}var c,d,e,f;f=this.container instanceof a?this.container.offset():a(this.container).offset(),this.component?(c=this.component.offset(),e=c.left,("bottom-left"==this.pickerPosition||"top-left"==this.pickerPosition)&&(e+=this.component.outerWidth()-this.picker.outerWidth())):(c=this.element.offset(),e=c.left,("bottom-left"==this.pickerPosition||"top-left"==this.pickerPosition)&&(e+=this.element.outerWidth()-this.picker.outerWidth()));var g=document.body.clientWidth||window.innerWidth;e+220>g&&(e=g-220),d="top-left"==this.pickerPosition||"top-right"==this.pickerPosition?c.top-this.picker.outerHeight():c.top+this.height,d-=f.top,e-=f.left,this.picker.css({top:d,left:e,zIndex:this.zIndex})}},update:function(){var a,b=!1;arguments&&arguments.length&&("string"==typeof arguments[0]||arguments[0]instanceof Date)?(a=arguments[0],b=!0):(a=(this.isInput?this.element.val():this.element.find("input").val())||this.element.data("date")||this.initialDate,("string"==typeof a||a instanceof String)&&(a=a.replace(/^\s+|\s+$/g,""))),a||(a=new Date,b=!1),this.date=g.parseDate(a,this.format,this.language,this.formatType,this.timezone),b&&this.setValue(),this.viewDate=new Date(this.datethis.endDate?this.endDate:this.date),this.fill()},fillDow:function(){for(var a=this.weekStart,b="";a'+f[this.language].daysMin[a++%7]+"";b+="",this.picker.find(".datetimepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;12>b;)a+=''+f[this.language].monthsShort[b++]+"";this.picker.find(".datetimepicker-months td").html(a)},fill:function(){if(null!=this.date&&null!=this.viewDate){var b=new Date(this.viewDate),d=b.getUTCFullYear(),e=b.getUTCMonth(),h=b.getUTCDate(),i=b.getUTCHours(),j=b.getUTCMinutes(),k=this.startDate!==-(1/0)?this.startDate.getUTCFullYear():-(1/0),l=this.startDate!==-(1/0)?this.startDate.getUTCMonth():-(1/0),m=this.endDate!==1/0?this.endDate.getUTCFullYear():1/0,n=this.endDate!==1/0?this.endDate.getUTCMonth()+1:1/0,o=new c(this.date.getUTCFullYear(),this.date.getUTCMonth(),this.date.getUTCDate()).valueOf(),p=new Date;if(this.setTitle(".datetimepicker-days",f[this.language].months[e]+" "+d),"time"==this.formatViewType){var q=this.getFormattedDate();this.setTitle(".datetimepicker-hours",q),this.setTitle(".datetimepicker-minutes",q)}else this.setTitle(".datetimepicker-hours",h+" "+f[this.language].months[e]+" "+d),this.setTitle(".datetimepicker-minutes",h+" "+f[this.language].months[e]+" "+d);this.picker.find("tfoot th.today").text(f[this.language].today||f.en.today).toggle(this.todayBtn!==!1),this.picker.find("tfoot th.clear").text(f[this.language].clear||f.en.clear).toggle(this.clearBtn!==!1),this.updateNavArrows(),this.fillMonths();var r=c(d,e-1,28,0,0,0,0),s=g.getDaysInMonth(r.getUTCFullYear(),r.getUTCMonth());r.setUTCDate(s),r.setUTCDate(s-(r.getUTCDay()-this.weekStart+7)%7);var t=new Date(r);t.setUTCDate(t.getUTCDate()+42),t=t.valueOf();for(var u,v=[];r.valueOf()"),u="",r.getUTCFullYear()d||r.getUTCFullYear()==d&&r.getUTCMonth()>e)&&(u+=" new"),this.todayHighlight&&r.getUTCFullYear()==p.getFullYear()&&r.getUTCMonth()==p.getMonth()&&r.getUTCDate()==p.getDate()&&(u+=" today"),r.valueOf()==o&&(u+=" active"),(r.valueOf()+864e5<=this.startDate||r.valueOf()>this.endDate||-1!==a.inArray(r.getUTCDay(),this.daysOfWeekDisabled)||-1!==a.inArray(r.toDateString(),this.datesDisabled))&&(u+=" disabled"),v.push(''+r.getUTCDate()+""),r.getUTCDay()==this.weekEnd&&v.push(""),r.setUTCDate(r.getUTCDate()+1);this.picker.find(".datetimepicker-days tbody").empty().append(v.join("")),v=[];for(var w="",x="",y="",z=this.hoursDisabled||[],A=0;24>A;A++)if(-1===z.indexOf(A)){var B=c(d,e,h,A);u="",B.valueOf()+36e5<=this.startDate||B.valueOf()>this.endDate?u+=" disabled":i==A&&(u+=" active"),this.showMeridian&&2==f[this.language].meridiem.length?(x=12>A?f[this.language].meridiem[0]:f[this.language].meridiem[1],x!=y&&(""!=y&&v.push(""),v.push('
        '+x.toUpperCase()+"")),y=x,w=A%12?A%12:12,v.push('A?"am":"pm")+'">'+w+""),23==A&&v.push("
        ")):(w=A+":00",v.push(''+w+""))}this.picker.find(".datetimepicker-hours td").html(v.join("")),v=[],w="",x="",y="";for(var C=this.minutesDisabled||[],A=0;60>A;A+=this.minuteStep)if(-1===C.indexOf(A)){var B=c(d,e,h,i,A,0);u="",B.valueOf()this.endDate?u+=" disabled":Math.floor(j/this.minuteStep)==Math.floor(A/this.minuteStep)&&(u+=" active"),this.showMeridian&&2==f[this.language].meridiem.length?(x=12>i?f[this.language].meridiem[0]:f[this.language].meridiem[1],x!=y&&(""!=y&&v.push(""),v.push('
        '+x.toUpperCase()+"")),y=x,w=i%12?i%12:12,v.push(''+w+":"+(10>A?"0"+A:A)+""),59==A&&v.push("
        ")):(w=A+":00",v.push(''+i+":"+(10>A?"0"+A:A)+"")); + +}this.picker.find(".datetimepicker-minutes td").html(v.join(""));var D=this.date.getUTCFullYear(),E=this.setTitle(".datetimepicker-months",d).end().find("span").removeClass("active");if(D==d){var F=E.length-12;E.eq(this.date.getUTCMonth()+F).addClass("active")}(k>d||d>m)&&E.addClass("disabled"),d==k&&E.slice(0,l).addClass("disabled"),d==m&&E.slice(n).addClass("disabled"),v="",d=10*parseInt(d/10,10);var G=this.setTitle(".datetimepicker-years",d+"-"+(d+9)).end().find("td");d-=1;for(var A=-1;11>A;A++)v+='d||d>m?" disabled":"")+'">'+d+"",d+=1;G.html(v),this.place()}},updateNavArrows:function(){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth(),d=a.getUTCDate(),e=a.getUTCHours();switch(this.viewMode){case 0:this.picker.find(".prev").css(this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()&&c<=this.startDate.getUTCMonth()&&d<=this.startDate.getUTCDate()&&e<=this.startDate.getUTCHours()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()&&c>=this.endDate.getUTCMonth()&&d>=this.endDate.getUTCDate()&&e>=this.endDate.getUTCHours()?{visibility:"hidden"}:{visibility:"visible"});break;case 1:this.picker.find(".prev").css(this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()&&c<=this.startDate.getUTCMonth()&&d<=this.startDate.getUTCDate()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()&&c>=this.endDate.getUTCMonth()&&d>=this.endDate.getUTCDate()?{visibility:"hidden"}:{visibility:"visible"});break;case 2:this.picker.find(".prev").css(this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()&&c<=this.startDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()&&c>=this.endDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"});break;case 3:case 4:this.picker.find(".prev").css(this.startDate!==-(1/0)&&b<=this.startDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(this.endDate!==1/0&&b>=this.endDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"})}},mousewheel:function(b){if(b.preventDefault(),b.stopPropagation(),!this.wheelPause){this.wheelPause=!0;var c=b.originalEvent,d=c.wheelDelta,e=d>0?1:0===d?0:-1;this.wheelViewModeNavigationInverseDirection&&(e=-e),this.showMode(e),setTimeout(a.proxy(function(){this.wheelPause=!1},this),this.wheelViewModeNavigationDelay)}},click:function(b){b.stopPropagation(),b.preventDefault();var d=a(b.target).closest("span, td, th, legend");if(d.is("."+this.icontype)&&(d=a(d).parent().closest("span, td, th, legend")),1==d.length){if(d.is(".disabled"))return void this.element.trigger({type:"outOfRange",date:this.viewDate,startDate:this.startDate,endDate:this.endDate});switch(d[0].nodeName.toLowerCase()){case"th":switch(d[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var e=g.modes[this.viewMode].navStep*("prev"==d[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveHour(this.viewDate,e);break;case 1:this.viewDate=this.moveDate(this.viewDate,e);break;case 2:this.viewDate=this.moveMonth(this.viewDate,e);break;case 3:case 4:this.viewDate=this.moveYear(this.viewDate,e)}this.fill(),this.element.trigger({type:d[0].className+":"+this.convertViewModeText(this.viewMode),date:this.viewDate,startDate:this.startDate,endDate:this.endDate});break;case"clear":this.reset(),this.autoclose&&this.hide();break;case"today":var f=new Date;f=c(f.getFullYear(),f.getMonth(),f.getDate(),f.getHours(),f.getMinutes(),f.getSeconds(),0),fthis.endDate&&(f=this.endDate),this.viewMode=this.startViewMode,this.showMode(0),this._setDate(f),this.fill(),this.autoclose&&this.hide()}break;case"span":if(!d.is(".disabled")){var h=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),j=this.viewDate.getUTCDate(),k=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),m=this.viewDate.getUTCSeconds();if(d.is(".month")?(this.viewDate.setUTCDate(1),i=d.parent().find("span").index(d),j=this.viewDate.getUTCDate(),this.viewDate.setUTCMonth(i),this.element.trigger({type:"changeMonth",date:this.viewDate}),this.viewSelect>=3&&this._setDate(c(h,i,j,k,l,m,0))):d.is(".year")?(this.viewDate.setUTCDate(1),h=parseInt(d.text(),10)||0,this.viewDate.setUTCFullYear(h),this.element.trigger({type:"changeYear",date:this.viewDate}),this.viewSelect>=4&&this._setDate(c(h,i,j,k,l,m,0))):d.is(".hour")?(k=parseInt(d.text(),10)||0,(d.hasClass("hour_am")||d.hasClass("hour_pm"))&&(12==k&&d.hasClass("hour_am")?k=0:12!=k&&d.hasClass("hour_pm")&&(k+=12)),this.viewDate.setUTCHours(k),this.element.trigger({type:"changeHour",date:this.viewDate}),this.viewSelect>=1&&this._setDate(c(h,i,j,k,l,m,0))):d.is(".minute")&&(l=parseInt(d.text().substr(d.text().indexOf(":")+1),10)||0,this.viewDate.setUTCMinutes(l),this.element.trigger({type:"changeMinute",date:this.viewDate}),this.viewSelect>=0&&this._setDate(c(h,i,j,k,l,m,0))),0!=this.viewMode){var n=this.viewMode;this.showMode(-1),this.fill(),n==this.viewMode&&this.autoclose&&this.hide()}else this.fill(),this.autoclose&&this.hide()}break;case"td":if(d.is(".day")&&!d.is(".disabled")){var j=parseInt(d.text(),10)||1,h=this.viewDate.getUTCFullYear(),i=this.viewDate.getUTCMonth(),k=this.viewDate.getUTCHours(),l=this.viewDate.getUTCMinutes(),m=this.viewDate.getUTCSeconds();d.is(".old")?0===i?(i=11,h-=1):i-=1:d.is(".new")&&(11==i?(i=0,h+=1):i+=1),this.viewDate.setUTCFullYear(h),this.viewDate.setUTCMonth(i,j),this.element.trigger({type:"changeDay",date:this.viewDate}),this.viewSelect>=2&&this._setDate(c(h,i,j,k,l,m,0))}var n=this.viewMode;this.showMode(-1),this.fill(),n==this.viewMode&&this.autoclose&&this.hide()}}},_setDate:function(a,b){b&&"date"!=b||(this.date=a),b&&"view"!=b||(this.viewDate=a),this.fill(),this.setValue();var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&(c.change(),this.autoclose&&(!b||"date"==b)),this.element.trigger({type:"changeDate",date:this.getDate()}),null==a&&(this.date=this.viewDate)},moveMinute:function(a,b){if(!b)return a;var c=new Date(a.valueOf());return c.setUTCMinutes(c.getUTCMinutes()+b*this.minuteStep),c},moveHour:function(a,b){if(!b)return a;var c=new Date(a.valueOf());return c.setUTCHours(c.getUTCHours()+b),c},moveDate:function(a,b){if(!b)return a;var c=new Date(a.valueOf());return c.setUTCDate(c.getUTCDate()+b),c},moveMonth:function(a,b){if(!b)return a;var c,d,e=new Date(a.valueOf()),f=e.getUTCDate(),g=e.getUTCMonth(),h=Math.abs(b);if(b=b>0?1:-1,1==h)d=-1==b?function(){return e.getUTCMonth()==g}:function(){return e.getUTCMonth()!=c},c=g+b,e.setUTCMonth(c),(0>c||c>11)&&(c=(c+12)%12);else{for(var i=0;h>i;i++)e=this.moveMonth(e,b);c=e.getUTCMonth(),e.setUTCDate(f),d=function(){return c!=e.getUTCMonth()}}for(;d();)e.setUTCDate(--f),e.setUTCMonth(c);return e},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.startDate&&a<=this.endDate},keydown:function(a){if(this.picker.is(":not(:visible)"))return void(27==a.keyCode&&this.show());var b,c,d,e=!1;switch(a.keyCode){case 27:this.hide(),a.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation)break;b=37==a.keyCode?-1:1,viewMode=this.viewMode,a.ctrlKey?viewMode+=2:a.shiftKey&&(viewMode+=1),4==viewMode?(c=this.moveYear(this.date,b),d=this.moveYear(this.viewDate,b)):3==viewMode?(c=this.moveMonth(this.date,b),d=this.moveMonth(this.viewDate,b)):2==viewMode?(c=this.moveDate(this.date,b),d=this.moveDate(this.viewDate,b)):1==viewMode?(c=this.moveHour(this.date,b),d=this.moveHour(this.viewDate,b)):0==viewMode&&(c=this.moveMinute(this.date,b),d=this.moveMinute(this.viewDate,b)),this.dateWithinRange(c)&&(this.date=c,this.viewDate=d,this.setValue(),this.update(),a.preventDefault(),e=!0);break;case 38:case 40:if(!this.keyboardNavigation)break;b=38==a.keyCode?-1:1,viewMode=this.viewMode,a.ctrlKey?viewMode+=2:a.shiftKey&&(viewMode+=1),4==viewMode?(c=this.moveYear(this.date,b),d=this.moveYear(this.viewDate,b)):3==viewMode?(c=this.moveMonth(this.date,b),d=this.moveMonth(this.viewDate,b)):2==viewMode?(c=this.moveDate(this.date,7*b),d=this.moveDate(this.viewDate,7*b)):1==viewMode?this.showMeridian?(c=this.moveHour(this.date,6*b),d=this.moveHour(this.viewDate,6*b)):(c=this.moveHour(this.date,4*b),d=this.moveHour(this.viewDate,4*b)):0==viewMode&&(c=this.moveMinute(this.date,4*b),d=this.moveMinute(this.viewDate,4*b)),this.dateWithinRange(c)&&(this.date=c,this.viewDate=d,this.setValue(),this.update(),a.preventDefault(),e=!0);break;case 13:if(0!=this.viewMode){var f=this.viewMode;this.showMode(-1),this.fill(),f==this.viewMode&&this.autoclose&&this.hide()}else this.fill(),this.autoclose&&this.hide();a.preventDefault();break;case 9:this.hide()}if(e){var g;this.isInput?g=this.element:this.component&&(g=this.element.find("input")),g&&g.change(),this.element.trigger({type:"changeDate",date:this.getDate()})}},showMode:function(a){if(a){var b=Math.max(0,Math.min(g.modes.length-1,this.viewMode+a));b>=this.minView&&b<=this.maxView&&(this.element.trigger({type:"changeMode",date:this.viewDate,oldViewMode:this.viewMode,newViewMode:b}),this.viewMode=b)}this.picker.find(">div").hide().filter(".datetimepicker-"+g.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()},reset:function(){this._setDate(null,"date")},convertViewModeText:function(a){switch(a){case 4:return"decade";case 3:return"year";case 2:return"month";case 1:return"day";case 0:return"hour"}}};var e=a.fn.datetimepicker;a.fn.datetimepicker=function(c){var e=Array.apply(null,arguments);e.shift();var f;return this.each(function(){var g=a(this),h=g.data("datetimepicker"),i="object"==typeof c&&c;return h||g.data("datetimepicker",h=new d(this,a.extend({},a.fn.datetimepicker.defaults,i))),"string"==typeof c&&"function"==typeof h[c]&&(f=h[c].apply(h,e),f!==b)?!1:void 0}),f!==b?f:this},a.fn.datetimepicker.defaults={},a.fn.datetimepicker.Constructor=d;var f=a.fn.datetimepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["am","pm"],suffix:["st","nd","rd","th"],today:"Today",clear:"Clear"}},g={modes:[{clsName:"minutes",navFnc:"Hours",navStep:1},{clsName:"hours",navFnc:"Date",navStep:1},{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return a%4===0&&a%100!==0||a%400===0},getDaysInMonth:function(a,b){return[31,g.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},getDefaultFormat:function(a,b){if("standard"==a)return"input"==b?"yyyy-mm-dd hh:ii":"yyyy-mm-dd hh:ii:ss";if("php"==a)return"input"==b?"Y-m-d H:i":"Y-m-d H:i:s";throw new Error("Invalid format type.")},validParts:function(a){if("standard"==a)return/t|hh?|HH?|p|P|z|Z|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g;if("php"==a)return/[dDjlNwzFmMnStyYaABgGhHis]/g;throw new Error("Invalid format type.")},nonpunctuation:/[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,parseFormat:function(a,b){var c=a.replace(this.validParts(b),"\x00").split("\x00"),d=a.match(this.validParts(b));if(!c||!c.length||!d||0==d.length)throw new Error("Invalid date format.");return{separators:c,parts:d}},parseDate:function(b,e,g,h,i){if(b instanceof Date){var j=new Date(b.valueOf()-6e4*b.getTimezoneOffset());return j.setMilliseconds(0),j}if(/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(b)&&(e=this.parseFormat("yyyy-mm-dd",h)),/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(b)&&(e=this.parseFormat("yyyy-mm-dd hh:ii",h)),/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(b)&&(e=this.parseFormat("yyyy-mm-dd hh:ii:ss",h)),/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(b)){var k,l,m=/([-+]\d+)([dmwy])/,n=b.match(/([-+]\d+)([dmwy])/g);b=new Date;for(var o=0;ob;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!=b;){if(isNaN(a.getUTCMonth()))return a;a.setUTCDate(a.getUTCDate()-1)}return a},d:function(a,b){return a.setUTCDate(b)},p:function(a,b){return a.setUTCHours(1==b?a.getUTCHours()+12:a.getUTCHours())},z:function(){return i}};if(t.M=t.MM=t.mm=t.m,t.dd=t.d,t.P=t.p,t.Z=t.z,b=c(b.getFullYear(),b.getMonth(),b.getDate(),b.getHours(),b.getMinutes(),b.getSeconds()),n.length==e.parts.length){for(var o=0,u=e.parts.length;u>o;o++){if(p=parseInt(n[o],10),k=e.parts[o],isNaN(p))switch(k){case"MM":q=a(f[g].months).filter(function(){var a=this.slice(0,n[o].length),b=n[o].slice(0,a.length);return a==b}),p=a.inArray(q[0],f[g].months)+1;break;case"M":q=a(f[g].monthsShort).filter(function(){var a=this.slice(0,n[o].length),b=n[o].slice(0,a.length);return a.toLowerCase()==b.toLowerCase()}),p=a.inArray(q[0],f[g].monthsShort)+1;break;case"p":case"P":p=a.inArray(n[o].toLowerCase(),f[g].meridiem);break;case"z":case"Z":}r[k]=p}for(var v,o=0;ok;k++)j.length&&b.push(j.shift()),b.push(i[c.parts[k]]);return j.length&&b.push(j.shift()),b.join("")},convertViewMode:function(a){switch(a){case 4:case"decade":a=4;break;case 3:case"year":a=3;break;case 2:case"month":a=2;break;case 1:case"day":a=1;break;case 0:case"hour":a=0}return a},headTemplate:'',headTemplateV3:' ',contTemplate:'',footTemplate:''};g.template='
        '+g.headTemplate+g.contTemplate+g.footTemplate+'
        '+g.headTemplate+g.contTemplate+g.footTemplate+'
        '+g.headTemplate+""+g.footTemplate+'
        '+g.headTemplate+g.contTemplate+g.footTemplate+'
        '+g.headTemplate+g.contTemplate+g.footTemplate+"
        ",g.templateV3='
        '+g.headTemplateV3+g.contTemplate+g.footTemplate+'
        '+g.headTemplateV3+g.contTemplate+g.footTemplate+'
        '+g.headTemplateV3+""+g.footTemplate+'
        '+g.headTemplateV3+g.contTemplate+g.footTemplate+'
        '+g.headTemplateV3+g.contTemplate+g.footTemplate+"
        ",a.fn.datetimepicker.DPGlobal=g,a.fn.datetimepicker.noConflict=function(){return a.fn.datetimepicker=e,this},a(document).on("focus.datetimepicker.data-api click.datetimepicker.data-api",'[data-provide="datetimepicker"]',function(b){var c=a(this);c.data("datetimepicker")||(b.preventDefault(),c.datetimepicker("show"))}),a(function(){a('[data-provide="datetimepicker-inline"]').datetimepicker()})});var saveAs=saveAs||function(a){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=b.createElementNS("http://www.w3.org/1999/xhtml","a"),e="download"in d,f=function(c){var d=b.createEvent("MouseEvents");d.initMouseEvent("click",!0,!1,a,0,0,0,0,0,!1,!1,!1,!1,0,null),c.dispatchEvent(d)},g=a.webkitRequestFileSystem,h=a.requestFileSystem||g||a.mozRequestFileSystem,i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=0,l=500,m=function(b){var d=function(){"string"==typeof b?c().revokeObjectURL(b):b.remove()};a.chrome?d():setTimeout(d,l)},n=function(a,b,c){b=[].concat(b);for(var d=b.length;d--;){var e=a["on"+b[d]];if("function"==typeof e)try{e.call(a,c||a)}catch(f){i(f)}}},o=function(a){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\ufeff",a],{type:a.type}):a},p=function(b,i){b=o(b);var l,p,q,r=this,s=b.type,t=!1,u=function(){n(r,"writestart progress write writeend".split(" "))},v=function(){if((t||!l)&&(l=c().createObjectURL(b)),p)p.location.href=l;else{var d=a.open(l,"_blank");void 0==d&&"undefined"!=typeof safari&&(a.location.href=l)}r.readyState=r.DONE,u(),m(l)},w=function(a){return function(){return r.readyState!==r.DONE?a.apply(this,arguments):void 0}},x={create:!0,exclusive:!1};return r.readyState=r.INIT,i||(i="download"),e?(l=c().createObjectURL(b),d.href=l,d.download=i,f(d),r.readyState=r.DONE,u(),void m(l)):(a.chrome&&s&&s!==j&&(q=b.slice||b.webkitSlice,b=q.call(b,0,b.size,j),t=!0),g&&"download"!==i&&(i+=".download"),(s===j||g)&&(p=a),h?(k+=b.size,void h(a.TEMPORARY,k,w(function(a){a.root.getDirectory("saved",x,w(function(a){var c=function(){a.getFile(i,x,w(function(a){a.createWriter(w(function(c){c.onwriteend=function(b){p.location.href=a.toURL(),r.readyState=r.DONE,n(r,"writeend",b),m(a)},c.onerror=function(){var a=c.error;a.code!==a.ABORT_ERR&&v()},"writestart progress write abort".split(" ").forEach(function(a){c["on"+a]=r["on"+a]}),c.write(b),r.abort=function(){c.abort(),r.readyState=r.DONE},r.readyState=r.WRITING}),v)}),v)};a.getFile(i,{create:!1},w(function(a){a.remove(),c()}),w(function(a){a.code===a.NOT_FOUND_ERR?c():v()}))}),v)}),v)):void v())},q=p.prototype,r=function(a,b){return new p(a,b)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(a,b){return navigator.msSaveOrOpenBlob(o(a),b)}:(q.abort=function(){var a=this;a.readyState=a.DONE,n(a,"abort")},q.readyState=q.INIT=0,q.WRITING=1,q.DONE=2,q.error=q.onwritestart=q.onprogress=q.onwrite=q.onabort=q.onerror=q.onwriteend=null,r)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!=define.amd&&define([],function(){return saveAs}),function(a,b,c){"use strict";function d(a,b,c){var d,e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;return!/^-?[0-9]+\.?[0-9]*(?:px)?$/i.test(c)&&/^-?\d/.test(c)&&(d=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left="fontSize"===b?"1em":c||0,c=f.pixelLeft+"px",f.left=d,e&&(a.runtimeStyle.left=e)),/^(thin|medium|thick)$/i.test(c)?c:Math.round(parseFloat(c))+"px"}function e(a){return parseInt(a,10)}function f(a,b,e,f){if(a=(a||"").split(","),a=a[f||0]||a[0]||"auto",a=l.Util.trimText(a).split(" "),"backgroundSize"!==e||a[0]&&!a[0].match(/cover|contain|auto/)){if(a[0]=-1===a[0].indexOf("%")?d(b,e+"X",a[0]):a[0],a[1]===c){if("backgroundSize"===e)return a[1]="auto",a;a[1]=a[0]}a[1]=-1===a[1].indexOf("%")?d(b,e+"Y",a[1]):a[1]}else;return a}function g(a,b,c,d,e,f){var g,h,i,j,k=l.Util.getCSS(b,a,e);if(1===k.length&&(j=k[0],k=[],k[0]=j,k[1]=j),-1!==k[0].toString().indexOf("%"))i=parseFloat(k[0])/100,h=c.width*i,"backgroundSize"!==a&&(h-=(f||d).width*i);else if("backgroundSize"===a)if("auto"===k[0])h=d.width;else if(/contain|cover/.test(k[0])){var m=l.Util.resizeBounds(d.width,d.height,c.width,c.height,k[0]);h=m.width,g=m.height}else h=parseInt(k[0],10);else h=parseInt(k[0],10);return"auto"===k[1]?g=h/d.width*d.height:-1!==k[1].toString().indexOf("%")?(i=parseFloat(k[1])/100,g=c.height*i,"backgroundSize"!==a&&(g-=(f||d).height*i)):g=parseInt(k[1],10),[h,g]}function h(a,b){var c=[];return{storage:c,width:a,height:b,clip:function(){c.push({type:"function",name:"clip",arguments:arguments})},translate:function(){c.push({type:"function",name:"translate",arguments:arguments})},fill:function(){c.push({type:"function",name:"fill",arguments:arguments})},save:function(){c.push({type:"function",name:"save",arguments:arguments})},restore:function(){c.push({type:"function",name:"restore",arguments:arguments})},fillRect:function(){c.push({type:"function",name:"fillRect",arguments:arguments})},createPattern:function(){c.push({type:"function",name:"createPattern",arguments:arguments})},drawShape:function(){var a=[];return c.push({type:"function",name:"drawShape",arguments:a}),{moveTo:function(){a.push({name:"moveTo",arguments:arguments})},lineTo:function(){a.push({name:"lineTo",arguments:arguments})},arcTo:function(){a.push({name:"arcTo",arguments:arguments})},bezierCurveTo:function(){a.push({name:"bezierCurveTo",arguments:arguments})},quadraticCurveTo:function(){a.push({name:"quadraticCurveTo",arguments:arguments})}}},drawImage:function(){c.push({type:"function",name:"drawImage",arguments:arguments})},fillText:function(){c.push({type:"function",name:"fillText",arguments:arguments})},setVariable:function(a,b){return c.push({type:"variable",name:a,arguments:b}),b}}}function i(a){return{zindex:a,children:[]}}var j,k,l={};l.Util={},l.Util.log=function(b){l.logging&&a.console&&a.console.log&&a.console.log(b)},l.Util.trimText=function(a){return function(b){return a?a.apply(b):((b||"")+"").replace(/^\s+|\s+$/g,"")}}(String.prototype.trim),l.Util.asFloat=function(a){return parseFloat(a)},function(){var a=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,b=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;l.Util.parseTextShadows=function(c){if(!c||"none"===c)return[];for(var d=c.match(a),e=[],f=0;d&&f0&&(d=b.substr(0,e),b=b.substr(e)),k.push({prefix:d,method:b.toLowerCase(),value:f,args:i})),i=[],b=d=c=f=""};n();for(var o=0,p=a.length;p>o;o++)if(g=a[o],!(0===l&&j.indexOf(g)>-1)){switch(g){case'"':h?h===g&&(h=null):h=g;break;case"(":if(h)break;if(0===l){l=1,f+=g;continue}m++;break;case")":if(h)break;if(1===l){if(0===m){l=0,f+=g,n();continue}m--}break;case",":if(h)break;if(0===l){n();continue}if(1===l&&0===m&&!b.match(/^url$/i)){i.push(c),c="",f+=g;continue}}f+=g,0===l?b+=g:c+=g}return n(),k},l.Util.Bounds=function(a){var b,c={};return a.getBoundingClientRect&&(b=a.getBoundingClientRect(),c.top=b.top,c.bottom=b.bottom||b.top+b.height,c.left=b.left,c.width=a.offsetWidth,c.height=a.offsetHeight),c},l.Util.OffsetBounds=function(a){var b=a.offsetParent?l.Util.OffsetBounds(a.offsetParent):{top:0,left:0};return{top:a.offsetTop+b.top,bottom:a.offsetTop+a.offsetHeight+b.top,left:a.offsetLeft+b.left,width:a.offsetWidth,height:a.offsetHeight}},l.Util.getCSS=function(a,c,d){j!==a&&(k=b.defaultView.getComputedStyle(a,null));var g=k[c];if(/^background(Size|Position)$/.test(c))return f(g,a,c,d);if(/border(Top|Bottom)(Left|Right)Radius/.test(c)){var h=g.split(" ");return h.length<=1&&(h[1]=h[0]),h.map(e)}return g},l.Util.resizeBounds=function(a,b,c,d,e){var f,g,h=c/d,i=a/b;return e&&"auto"!==e?i>h^"contain"===e?(g=d,f=d*i):(f=c,g=c/i):(f=c,g=d),{width:f,height:g}},l.Util.BackgroundPosition=function(a,b,c,d,e){var f=g("backgroundPosition",a,b,c,d,e);return{left:f[0],top:f[1]}},l.Util.BackgroundSize=function(a,b,c,d){var e=g("backgroundSize",a,b,c,d);return{width:e[0],height:e[1]}},l.Util.Extend=function(a,b){for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b},l.Util.Children=function(a){var b;try{b=a.nodeName&&"IFRAME"===a.nodeName.toUpperCase()?a.contentDocument||a.contentWindow.document:function(a){var b=[];return null!==a&&!function(a,b){var d=a.length,e=0;if("number"==typeof b.length)for(var f=b.length;f>e;e++)a[d++]=b[e];else for(;b[e]!==c;)a[d++]=b[e++];return a.length=d,a}(b,a),b}(a.childNodes)}catch(d){l.Util.log("html2canvas.Util.Children failed with exception: "+d.message),b=[]}return b},l.Util.isTransparent=function(a){return"transparent"===a||"rgba(0, 0, 0, 0)"===a},l.Util.Font=function(){var a={};return function(b,d,e){if(a[b+"-"+d]!==c)return a[b+"-"+d];var f,g,h,i=e.createElement("div"),j=e.createElement("img"),k=e.createElement("span"),l="Hidden Text";return i.style.visibility="hidden",i.style.fontFamily=b,i.style.fontSize=d,i.style.margin=0,i.style.padding=0,e.body.appendChild(i),j.src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=",j.width=1,j.height=1,j.style.margin=0,j.style.padding=0,j.style.verticalAlign="baseline",k.style.fontFamily=b,k.style.fontSize=d,k.style.margin=0,k.style.padding=0,k.appendChild(e.createTextNode(l)),i.appendChild(k),i.appendChild(j),f=j.offsetTop-k.offsetTop+1,i.removeChild(k),i.appendChild(e.createTextNode(l)),i.style.lineHeight="normal",j.style.verticalAlign="super",g=j.offsetTop-i.offsetTop+1,h={baseline:f,lineWidth:1,middle:g},a[b+"-"+d]=h,e.body.removeChild(i),h}}(),function(){function a(a){return function(b){try{a.addColorStop(b.stop,b.color)}catch(d){c.log(["failed to add color stop: ",d,"; tried to add: ",b])}}}var c=l.Util,d={};l.Generate=d;var e=[/^(-webkit-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-o-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-webkit-gradient)\((linear|radial),\s((?:\d{1,3}%?)\s(?:\d{1,3}%?),\s(?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)\-]+)\)$/,/^(-moz-linear-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)]+)\)$/,/^(-webkit-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-moz-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s?([a-z\-]*)([\w\d\.\s,%\(\)]+)\)$/,/^(-o-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/];d.parseGradient=function(a,b){var c,d,f,g,h,i,j,k,l,m,n,o,p=e.length;for(d=0;p>d&&!(f=a.match(e[d]));d+=1);if(f)switch(f[1]){case"-webkit-linear-gradient":case"-o-linear-gradient":if(c={type:"linear",x0:null,y0:null,x1:null,y1:null,colorStops:[]},h=f[2].match(/\w+/g))for(i=h.length,d=0;i>d;d+=1)switch(h[d]){case"top":c.y0=0,c.y1=b.height;break;case"right":c.x0=b.width,c.x1=0;break;case"bottom":c.y0=b.height,c.y1=0;break;case"left":c.x0=0,c.x1=b.width}if(null===c.x0&&null===c.x1&&(c.x0=c.x1=b.width/2),null===c.y0&&null===c.y1&&(c.y0=c.y1=b.height/2),h=f[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g))for(i=h.length,j=1/Math.max(i-1,1),d=0;i>d;d+=1)k=h[d].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/),k[2]?(g=parseFloat(k[2]),g/="%"===k[3]?100:b.width):g=d*j,c.colorStops.push({color:k[1],stop:g});break;case"-webkit-gradient":if(c={type:"radial"===f[2]?"circle":f[2],x0:0,y0:0,x1:0,y1:0,colorStops:[]},h=f[3].match(/(\d{1,3})%?\s(\d{1,3})%?,\s(\d{1,3})%?\s(\d{1,3})%?/),h&&(c.x0=h[1]*b.width/100,c.y0=h[2]*b.height/100,c.x1=h[3]*b.width/100,c.y1=h[4]*b.height/100),h=f[4].match(/((?:from|to|color-stop)\((?:[0-9\.]+,\s)?(?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)\))+/g))for(i=h.length,d=0;i>d;d+=1)k=h[d].match(/(from|to|color-stop)\(([0-9\.]+)?(?:,\s)?((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\)/),g=parseFloat(k[2]),"from"===k[1]&&(g=0),"to"===k[1]&&(g=1),c.colorStops.push({color:k[3],stop:g});break;case"-moz-linear-gradient":if(c={type:"linear",x0:0,y0:0,x1:0,y1:0,colorStops:[]},h=f[2].match(/(\d{1,3})%?\s(\d{1,3})%?/),h&&(c.x0=h[1]*b.width/100,c.y0=h[2]*b.height/100,c.x1=b.width-c.x0,c.y1=b.height-c.y0),h=f[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}%)?)+/g))for(i=h.length,j=1/Math.max(i-1,1),d=0;i>d;d+=1)k=h[d].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%)?/),k[2]?(g=parseFloat(k[2]),k[3]&&(g/=100)):g=d*j,c.colorStops.push({color:k[1],stop:g});break;case"-webkit-radial-gradient":case"-moz-radial-gradient":case"-o-radial-gradient":if(c={type:"circle",x0:0,y0:0,x1:b.width,y1:b.height,cx:0,cy:0,rx:0,ry:0,colorStops:[]},h=f[2].match(/(\d{1,3})%?\s(\d{1,3})%?/),h&&(c.cx=h[1]*b.width/100,c.cy=h[2]*b.height/100),h=f[3].match(/\w+/),k=f[4].match(/[a-z\-]*/),h&&k)switch(k[0]){case"farthest-corner":case"cover":case"":l=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.cy,2)),m=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.y1-c.cy,2)),n=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.y1-c.cy,2)),o=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.cy,2)),c.rx=c.ry=Math.max(l,m,n,o);break;case"closest-corner":l=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.cy,2)),m=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.y1-c.cy,2)),n=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.y1-c.cy,2)),o=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.cy,2)),c.rx=c.ry=Math.min(l,m,n,o);break;case"farthest-side":"circle"===h[0]?c.rx=c.ry=Math.max(c.cx,c.cy,c.x1-c.cx,c.y1-c.cy):(c.type=h[0], +c.rx=Math.max(c.cx,c.x1-c.cx),c.ry=Math.max(c.cy,c.y1-c.cy));break;case"closest-side":case"contain":"circle"===h[0]?c.rx=c.ry=Math.min(c.cx,c.cy,c.x1-c.cx,c.y1-c.cy):(c.type=h[0],c.rx=Math.min(c.cx,c.x1-c.cx),c.ry=Math.min(c.cy,c.y1-c.cy))}if(h=f[5].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g))for(i=h.length,j=1/Math.max(i-1,1),d=0;i>d;d+=1)k=h[d].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/),k[2]?(g=parseFloat(k[2]),g/="%"===k[3]?100:b.width):g=d*j,c.colorStops.push({color:k[1],stop:g})}return c},d.Gradient=function(c,d){if(0!==d.width&&0!==d.height){var e,f,g=b.createElement("canvas"),h=g.getContext("2d");if(g.width=d.width,g.height=d.height,e=l.Generate.parseGradient(c,d))switch(e.type){case"linear":f=h.createLinearGradient(e.x0,e.y0,e.x1,e.y1),e.colorStops.forEach(a(f)),h.fillStyle=f,h.fillRect(0,0,d.width,d.height);break;case"circle":f=h.createRadialGradient(e.cx,e.cy,0,e.cx,e.cy,e.rx),e.colorStops.forEach(a(f)),h.fillStyle=f,h.fillRect(0,0,d.width,d.height);break;case"ellipse":var i=b.createElement("canvas"),j=i.getContext("2d"),k=Math.max(e.rx,e.ry),m=2*k;i.width=i.height=m,f=j.createRadialGradient(e.rx,e.ry,0,e.rx,e.ry,k),e.colorStops.forEach(a(f)),j.fillStyle=f,j.fillRect(0,0,m,m),h.fillStyle=e.colorStops[e.colorStops.length-1].color,h.fillRect(0,0,g.width,g.height),h.drawImage(i,e.cx-e.rx,e.cy-e.ry,2*e.rx,2*e.ry)}return g}},d.ListAlpha=function(a){var b,c="";do b=a%26,c=String.fromCharCode(b+64)+c,a/=26;while(26*a>26);return c},d.ListRoman=function(a){var b,c=["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"],d=[1e3,900,500,400,100,90,50,40,10,9,5,4,1],e="",f=c.length;if(0>=a||a>=4e3)return a;for(b=0;f>b;b+=1)for(;a>=d[b];)a-=d[b],e+=c[b];return e}}(),l.Parse=function(d,e){function f(){return Math.max(Math.max(ka.body.scrollWidth,ka.documentElement.scrollWidth),Math.max(ka.body.offsetWidth,ka.documentElement.offsetWidth),Math.max(ka.body.clientWidth,ka.documentElement.clientWidth))}function g(){return Math.max(Math.max(ka.body.scrollHeight,ka.documentElement.scrollHeight),Math.max(ka.body.offsetHeight,ka.documentElement.offsetHeight),Math.max(ka.body.clientHeight,ka.documentElement.clientHeight))}function j(a,b){var c=parseInt(pa(a,b),10);return isNaN(c)?0:c}function k(a,b,c,d,e,f){"transparent"!==f&&(a.setVariable("fillStyle",f),a.fillRect(b,c,d,e),ja+=1)}function m(a,b,c){return a.length>0?b+c.toUpperCase():void 0}function n(a,b){switch(b){case"lowercase":return a.toLowerCase();case"capitalize":return a.replace(/(^|\s|:|-|\(|\))([a-z])/g,m);case"uppercase":return a.toUpperCase();default:return a}}function o(a){return/^(normal|none|0px)$/.test(a)}function p(a,b,c,d){null!==a&&la.trimText(a).length>0&&(d.fillText(a,b,c),ja+=1)}function q(a,b,c,d){var e=!1,f=pa(b,"fontWeight"),g=pa(b,"fontFamily"),h=pa(b,"fontSize"),i=la.parseTextShadows(pa(b,"textShadow"));switch(parseInt(f,10)){case 401:f="bold";break;case 400:f="normal"}return a.setVariable("fillStyle",d),a.setVariable("font",[pa(b,"fontStyle"),pa(b,"fontVariant"),f,h,g].join(" ")),a.setVariable("textAlign",e?"right":"left"),i.length&&(a.setVariable("shadowColor",i[0].color),a.setVariable("shadowOffsetX",i[0].offsetX),a.setVariable("shadowOffsetY",i[0].offsetY),a.setVariable("shadowBlur",i[0].blur)),"none"!==c?la.Font(g,h,ka):void 0}function r(a,b,c,d,e){switch(b){case"underline":k(a,c.left,Math.round(c.top+d.baseline+d.lineWidth),c.width,1,e);break;case"overline":k(a,c.left,Math.round(c.top),c.width,1,e);break;case"line-through":k(a,c.left,Math.ceil(c.top+d.middle+d.lineWidth),c.width,1,e)}}function s(a,b,c,d,e){var f;if(ma.rangeBounds&&!e)("none"!==c||0!==la.trimText(b).length)&&(f=t(b,a.node,a.textOffset)),a.textOffset+=b.length;else if(a.node&&"string"==typeof a.node.nodeValue){var g=d?a.node.splitText(b.length):null;f=u(a.node,e),a.node=g}return f}function t(a,b,c){var d=ka.createRange();return d.setStart(b,c),d.setEnd(b,c+a.length),d.getBoundingClientRect()}function u(a,b){var c=a.parentNode,d=ka.createElement("wrapper"),e=a.cloneNode(!0);d.appendChild(a.cloneNode(!0)),c.replaceChild(d,a);var f=b?la.OffsetBounds(d):la.Bounds(d);return c.replaceChild(e,d),f}function v(a,b,c){var d,f,g=c.ctx,h=pa(a,"color"),i=pa(a,"textDecoration"),j=pa(a,"textAlign"),k={node:b,textOffset:0};la.trimText(b.nodeValue).length>0&&(b.nodeValue=n(b.nodeValue,pa(a,"textTransform")),j=j.replace(["-webkit-auto"],["auto"]),f=b.nodeValue.split(!e.letterRendering&&/^(left|right|justify|auto)$/.test(j)&&o(pa(a,"letterSpacing"))?/(\b| )/:""),d=q(g,a,i,h),e.chinese&&f.forEach(function(a,b){/.*[\u4E00-\u9FA5].*$/.test(a)&&(a=a.split(""),a.unshift(b,1),f.splice.apply(f,a))}),f.forEach(function(a,b){var e=s(k,a,i,bg,c&&c.zIndex.children.push(b)}function D(a,b,c,d,e){var f=j(b,"paddingLeft"),g=j(b,"paddingTop"),h=j(b,"paddingRight"),i=j(b,"paddingBottom");P(a,c,0,0,c.width,c.height,d.left+f+e[3].width,d.top+g+e[0].width,d.width-(e[1].width+e[3].width+f+h),d.height-(e[0].width+e[2].width+g+i))}function E(a){return["Top","Right","Bottom","Left"].map(function(b){return{width:j(a,"border"+b+"Width"),color:pa(a,"border"+b+"Color")}})}function F(a){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(b){return pa(a,"border"+b+"Radius")})}function G(a,b,c,d){var e=function(a,b,c){return{x:a.x+(b.x-a.x)*c,y:a.y+(b.y-a.y)*c}};return{start:a,startControl:b,endControl:c,end:d,subdivide:function(f){var g=e(a,b,f),h=e(b,c,f),i=e(c,d,f),j=e(g,h,f),k=e(h,i,f),l=e(j,k,f);return[G(a,g,j,l),G(l,k,i,d)]},curveTo:function(a){a.push(["bezierCurve",b.x,b.y,c.x,c.y,d.x,d.y])},curveToReversed:function(d){d.push(["bezierCurve",c.x,c.y,b.x,b.y,a.x,a.y])}}}function H(a,b,c,d,e,f,g){b[0]>0||b[1]>0?(a.push(["line",d[0].start.x,d[0].start.y]),d[0].curveTo(a),d[1].curveTo(a)):a.push(["line",f,g]),(c[0]>0||c[1]>0)&&a.push(["line",e[0].start.x,e[0].start.y])}function I(a,b,c,d,e,f,g){var h=[];return b[0]>0||b[1]>0?(h.push(["line",d[1].start.x,d[1].start.y]),d[1].curveTo(h)):h.push(["line",a.c1[0],a.c1[1]]),c[0]>0||c[1]>0?(h.push(["line",f[0].start.x,f[0].start.y]),f[0].curveTo(h),h.push(["line",g[0].end.x,g[0].end.y]),g[0].curveToReversed(h)):(h.push(["line",a.c2[0],a.c2[1]]),h.push(["line",a.c3[0],a.c3[1]])),b[0]>0||b[1]>0?(h.push(["line",e[1].end.x,e[1].end.y]),e[1].curveToReversed(h)):h.push(["line",a.c4[0],a.c4[1]]),h}function J(a,b,c){var d=a.left,e=a.top,f=a.width,g=a.height,h=b[0][0],i=b[0][1],j=b[1][0],k=b[1][1],l=b[2][0],m=b[2][1],n=b[3][0],o=b[3][1],p=f-j,q=g-m,r=f-l,s=g-o;return{topLeftOuter:sa(d,e,h,i).topLeft.subdivide(.5),topLeftInner:sa(d+c[3].width,e+c[0].width,Math.max(0,h-c[3].width),Math.max(0,i-c[0].width)).topLeft.subdivide(.5),topRightOuter:sa(d+p,e,j,k).topRight.subdivide(.5),topRightInner:sa(d+Math.min(p,f+c[3].width),e+c[0].width,p>f+c[3].width?0:j-c[3].width,k-c[0].width).topRight.subdivide(.5),bottomRightOuter:sa(d+r,e+q,l,m).bottomRight.subdivide(.5),bottomRightInner:sa(d+Math.min(r,f+c[3].width),e+Math.min(q,g+c[0].width),Math.max(0,l-c[1].width),Math.max(0,m-c[2].width)).bottomRight.subdivide(.5),bottomLeftOuter:sa(d,e+s,n,o).bottomLeft.subdivide(.5),bottomLeftInner:sa(d+c[3].width,e+s,Math.max(0,n-c[3].width),Math.max(0,o-c[2].width)).bottomLeft.subdivide(.5)}}function K(a,b,c,d,e){var f=pa(a,"backgroundClip"),g=[];switch(f){case"content-box":case"padding-box":H(g,d[0],d[1],b.topLeftInner,b.topRightInner,e.left+c[3].width,e.top+c[0].width),H(g,d[1],d[2],b.topRightInner,b.bottomRightInner,e.left+e.width-c[1].width,e.top+c[0].width),H(g,d[2],d[3],b.bottomRightInner,b.bottomLeftInner,e.left+e.width-c[1].width,e.top+e.height-c[2].width),H(g,d[3],d[0],b.bottomLeftInner,b.topLeftInner,e.left+c[3].width,e.top+e.height-c[2].width);break;default:H(g,d[0],d[1],b.topLeftOuter,b.topRightOuter,e.left,e.top),H(g,d[1],d[2],b.topRightOuter,b.bottomRightOuter,e.left+e.width,e.top),H(g,d[2],d[3],b.bottomRightOuter,b.bottomLeftOuter,e.left+e.width,e.top+e.height),H(g,d[3],d[0],b.bottomLeftOuter,b.topLeftOuter,e.left,e.top+e.height)}return g}function L(a,b,c){var d,e,f,g,h,i,j=b.left,k=b.top,l=b.width,m=b.height,n=F(a),o=J(b,n,c),p={clip:K(a,o,c,n,b),borders:[]};for(d=0;4>d;d++)if(c[d].width>0){switch(e=j,f=k,g=l,h=m-c[2].width,d){case 0:h=c[0].width,i=I({c1:[e,f],c2:[e+g,f],c3:[e+g-c[1].width,f+h],c4:[e+c[3].width,f+h]},n[0],n[1],o.topLeftOuter,o.topLeftInner,o.topRightOuter,o.topRightInner);break;case 1:e=j+l-c[1].width,g=c[1].width,i=I({c1:[e+g,f],c2:[e+g,f+h+c[2].width],c3:[e,f+h],c4:[e,f+c[0].width]},n[1],n[2],o.topRightOuter,o.topRightInner,o.bottomRightOuter,o.bottomRightInner);break;case 2:f=f+m-c[2].width,h=c[2].width,i=I({c1:[e+g,f+h],c2:[e,f+h],c3:[e+c[3].width,f],c4:[e+g-c[3].width,f]},n[2],n[3],o.bottomRightOuter,o.bottomRightInner,o.bottomLeftOuter,o.bottomLeftInner);break;case 3:g=c[3].width,i=I({c1:[e,f+h+c[2].width],c2:[e,f],c3:[e+g,f+c[0].width],c4:[e+g,f+h]},n[3],n[0],o.bottomLeftOuter,o.bottomLeftInner,o.topLeftOuter,o.topLeftInner)}p.borders.push({args:i,color:c[d].color})}return p}function M(a,b){var c=a.drawShape();return b.forEach(function(a,b){c[0===b?"moveTo":a[0]+"To"].apply(null,a.slice(1))}),c}function N(a,b,c){"transparent"!==c&&(a.setVariable("fillStyle",c),M(a,b),a.fill(),ja+=1)}function O(a,b,c){var d,e,f=ka.createElement("valuewrap"),g=["lineHeight","textAlign","fontFamily","color","fontSize","paddingLeft","paddingTop","width","height","border","borderLeftWidth","borderTopWidth"];g.forEach(function(b){try{f.style[b]=pa(a,b)}catch(c){la.log("html2canvas: Parse: Exception caught in renderFormValue: "+c.message)}}),f.style.borderColor="black",f.style.borderStyle="solid",f.style.display="block",f.style.position="absolute",(/^(submit|reset|button|text|password)$/.test(a.type)||"SELECT"===a.nodeName)&&(f.style.lineHeight=pa(a,"height")),f.style.top=b.top+"px",f.style.left=b.left+"px",d="SELECT"===a.nodeName?(a.options[a.selectedIndex]||0).text:a.value,d||(d=a.placeholder),e=ka.createTextNode(d),f.appendChild(e),oa.appendChild(f),v(a,e,c),oa.removeChild(f)}function P(a){a.drawImage.apply(a,Array.prototype.slice.call(arguments,1)),ja+=1}function Q(c,d){var e=a.getComputedStyle(c,d);if(e&&e.content&&"none"!==e.content&&"-moz-alt-content"!==e.content&&"none"!==e.display){var f=e.content+"",g=f.substr(0,1);g===f.substr(f.length-1)&&g.match(/'|"/)&&(f=f.substr(1,f.length-2));var h="url"===f.substr(0,3),i=b.createElement(h?"img":"span");return i.className=qa+"-before "+qa+"-after",Object.keys(e).filter(R).forEach(function(a){try{i.style[a]=e[a]}catch(b){la.log(["Tried to assign readonly property ",a,"Error:",b])}}),h?i.src=la.parseBackgroundImage(f)[0].args[0]:i.innerHTML=f,i}}function R(b){return isNaN(a.parseInt(b,10))}function S(a,b){var c=Q(a,":before"),d=Q(a,":after");(c||d)&&(c&&(a.className+=" "+qa+"-before",a.parentNode.insertBefore(c,a),fa(c,b,!0),a.parentNode.removeChild(c),a.className=a.className.replace(qa+"-before","").trim()),d&&(a.className+=" "+qa+"-after",a.appendChild(d),fa(d,b,!0),a.removeChild(d),a.className=a.className.replace(qa+"-after","").trim()))}function T(a,b,c,d){var e=Math.round(d.left+c.left),f=Math.round(d.top+c.top);a.createPattern(b),a.translate(e,f),a.fill(),a.translate(-e,-f)}function U(a,b,c,d,e,f,g,h){var i=[];i.push(["line",Math.round(e),Math.round(f)]),i.push(["line",Math.round(e+g),Math.round(f)]),i.push(["line",Math.round(e+g),Math.round(h+f)]),i.push(["line",Math.round(e),Math.round(h+f)]),M(a,i),a.save(),a.clip(),T(a,b,c,d),a.restore()}function V(a,b,c){k(a,b.left,b.top,b.width,b.height,c)}function W(a,b,c,d,e){var f=la.BackgroundSize(a,b,d,e),g=la.BackgroundPosition(a,b,d,e,f),h=pa(a,"backgroundRepeat").split(",").map(la.trimText);switch(d=Y(d,f),h=h[e]||h[0]){case"repeat-x":U(c,d,g,b,b.left,b.top+g.top,99999,d.height);break;case"repeat-y":U(c,d,g,b,b.left+g.left,b.top,d.width,99999);break;case"no-repeat":U(c,d,g,b,b.left+g.left,b.top+g.top,d.width,d.height);break;default:T(c,d,g,{top:b.top,left:b.left,width:d.width,height:d.height})}}function X(a,b,c){for(var d,e=pa(a,"backgroundImage"),f=la.parseBackgroundImage(e),g=f.length;g--;)if(e=f[g],e.args&&0!==e.args.length){var h="url"===e.method?e.args[0]:e.value;d=A(h),d?W(a,b,c,d,g):la.log("html2canvas: Error loading background:",e)}}function Y(a,b){if(a.width===b.width&&a.height===b.height)return a;var c,d=ka.createElement("canvas");return d.width=b.width,d.height=b.height,c=d.getContext("2d"),P(c,a,0,0,a.width,a.height,0,0,b.width,b.height),d}function Z(a,b,c){return a.setVariable("globalAlpha",pa(b,"opacity")*(c?c.opacity:1))}function $(a){return a.replace("px","")}function _(a){var b=pa(a,"transform")||pa(a,"-webkit-transform")||pa(a,"-moz-transform")||pa(a,"-ms-transform")||pa(a,"-o-transform"),c=pa(a,"transform-origin")||pa(a,"-webkit-transform-origin")||pa(a,"-moz-transform-origin")||pa(a,"-ms-transform-origin")||pa(a,"-o-transform-origin")||"0px 0px";c=c.split(" ").map($).map(la.asFloat);var d;if(b&&"none"!==b){var e=b.match(ta);if(e)switch(e[1]){case"matrix":d=e[2].split(",").map(la.trimText).map(la.asFloat)}}return{origin:c,matrix:d}}function aa(a,b,c,d){var i=h(b?c.width:f(),b?c.height:g()),j={ctx:i,opacity:Z(i,a,b),cssPosition:pa(a,"position"),borders:E(a),transform:d,clip:b&&b.clip?la.Extend({},b.clip):null};return C(a,j,b),e.useOverflow===!0&&/(hidden|scroll|auto)/.test(pa(a,"overflow"))===!0&&/(BODY)/i.test(a.nodeName)===!1&&(j.clip=j.clip?B(j.clip,c):c),j}function ba(a,b,c){var d={left:b.left+a[3].width,top:b.top+a[0].width,width:b.width-(a[1].width+a[3].width),height:b.height-(a[0].width+a[2].width)};return c&&(d=B(d,c)),d}function ca(a,b){var c=b.matrix?la.OffsetBounds(a):la.Bounds(a);return b.origin[0]+=c.left,b.origin[1]+=c.top,c}function da(a,b,c,d){var e,f=_(a,b),g=ca(a,f),h=aa(a,b,g,f),i=h.borders,j=h.ctx,k=ba(i,g,h.clip),l=L(a,g,i),m=na.test(a.nodeName)?"#efefef":pa(a,"backgroundColor");switch(M(j,l.clip),j.save(),j.clip(),k.height>0&&k.width>0&&!d?(V(j,g,m),X(a,k,j)):d&&(h.backgroundColor=m),j.restore(),l.borders.forEach(function(a){N(j,a.args,a.color)}),c||S(a,h),a.nodeName){case"IMG":(e=A(a.getAttribute("src")))?D(j,a,e,g,i):la.log("html2canvas: Error loading :"+a.getAttribute("src"));break;case"INPUT":/^(text|url|email|submit|button|reset)$/.test(a.type)&&(a.value||a.placeholder||"").length>0&&O(a,g,h);break;case"TEXTAREA":(a.value||a.placeholder||"").length>0&&O(a,g,h);break;case"SELECT":(a.options||a.placeholder||"").length>0&&O(a,g,h);break;case"LI":z(a,h,k);break;case"CANVAS":D(j,a,a,g,i)}return h}function ea(a){return"none"!==pa(a,"display")&&"hidden"!==pa(a,"visibility")&&!a.hasAttribute("data-html2canvas-ignore")}function fa(a,b,c){ea(a)&&(b=da(a,b,c,!1)||b,na.test(a.nodeName)||ga(a,b,c))}function ga(a,b,c){la.Children(a).forEach(function(d){d.nodeType===d.ELEMENT_NODE?fa(d,b,c):d.nodeType===d.TEXT_NODE&&v(a,d,b)})}function ha(){var a=pa(b.documentElement,"backgroundColor"),c=la.isTransparent(a)&&ia===b.body,d=da(ia,null,!1,c);return ga(ia,d),c&&(a=d.backgroundColor),oa.removeChild(ra),{backgroundColor:a,stack:d}}a.scroll(0,0);var ia=e.elements===c?b.body:e.elements[0],ja=0,ka=ia.ownerDocument,la=l.Util,ma=la.Support(e,ka),na=new RegExp("("+e.ignoreElements+")"),oa=ka.body,pa=la.getCSS,qa="___html2canvas___pseudoelement",ra=ka.createElement("style");ra.innerHTML="."+qa+'-before:before { content: "" !important; display: none !important; }.'+qa+'-after:after { content: "" !important; display: none !important; }',oa.appendChild(ra),d=d||{};var sa=function(a){return function(b,c,d,e){var f=d*a,g=e*a,h=b+d,i=c+e;return{topLeft:G({x:b,y:i},{x:b,y:i-g},{x:h-f,y:c},{x:h,y:c}),topRight:G({x:b,y:c},{x:b+f,y:c},{x:h,y:i-g},{x:h,y:i}),bottomRight:G({x:h,y:c},{x:h,y:c+g},{x:b+f,y:i},{x:b,y:i}),bottomLeft:G({x:h,y:i},{x:h-f,y:i},{x:b,y:c+g},{x:b,y:c})}}}(4*((Math.sqrt(2)-1)/3)),ta=/(matrix)\((.+)\)/;return ha()},l.Preload=function(d){function e(a){A.href=a,A.href=A.href;var b=A.protocol+A.host;return b===p}function f(){u.log("html2canvas: start: images: "+t.numLoaded+" / "+t.numTotal+" (failed: "+t.numFailed+")"),!t.firstRun&&t.numLoaded>=t.numTotal&&(u.log("Finished loading images: # "+t.numTotal+" (failed: "+t.numFailed+")"),"function"==typeof d.complete&&d.complete(t))}function g(b,e,g){var h,i,j=d.proxy;A.href=b,b=A.href,h="html2canvas_"+v++,g.callbackname=h,j+=j.indexOf("?")>-1?"&":"?",j+="url="+encodeURIComponent(b)+"&callback="+h,i=x.createElement("script"),a[h]=function(b){"error:"===b.substring(0,6)?(g.succeeded=!1,t.numLoaded++,t.numFailed++,f()):(o(e,g),e.src=b),a[h]=c;try{delete a[h]}catch(d){}i.parentNode.removeChild(i),i=null,delete g.script,delete g.callbackname},i.setAttribute("type","text/javascript"),i.setAttribute("src",j),g.script=i,a.document.body.appendChild(i)}function h(b,c){var d=a.getComputedStyle(b,c),e=d.content;"url"===e.substr(0,3)&&q.loadImage(l.Util.parseBackgroundImage(e)[0].args[0]),m(d.backgroundImage,b)}function i(a){h(a,":before"),h(a,":after")}function j(a,b){var d=l.Generate.Gradient(a,b);d!==c&&(t[a]={img:d,succeeded:!0},t.numTotal++,t.numLoaded++,f())}function k(a){return a&&a.method&&a.args&&a.args.length>0}function m(a,b){var d;l.Util.parseBackgroundImage(a).filter(k).forEach(function(a){"url"===a.method?q.loadImage(a.args[0]):a.method.match(/\-?gradient$/)&&(d===c&&(d=l.Util.Bounds(b)),j(a.value,d))})}function n(a){var b=!1;try{u.Children(a).forEach(n)}catch(d){}try{b=a.nodeType}catch(e){b=!1,u.log("html2canvas: failed to access some element's nodeType - Exception: "+e.message)}if(1===b||b===c){i(a);try{m(u.getCSS(a,"backgroundImage"),a)}catch(d){u.log("html2canvas: failed to get background-image - Exception: "+d.message)}m(a)}}function o(b,e){b.onload=function(){e.timer!==c&&a.clearTimeout(e.timer),t.numLoaded++,e.succeeded=!0,b.onerror=b.onload=null,f()},b.onerror=function(){if("anonymous"===b.crossOrigin&&(a.clearTimeout(e.timer),d.proxy)){var c=b.src;return b=new Image,e.img=b,b.src=c,void g(b.src,b,e)}t.numLoaded++,t.numFailed++,e.succeeded=!1,b.onerror=b.onload=null,f()}}var p,q,r,s,t={numLoaded:0,numFailed:0,numTotal:0,cleanupDone:!1},u=l.Util,v=0,w=d.elements[0]||b.body,x=w.ownerDocument,y=w.getElementsByTagName("img"),z=y.length,A=x.createElement("a"),B=function(a){return a.crossOrigin!==c}(new Image);for(A.href=a.location.href,p=A.protocol+A.host,q={loadImage:function(a){var b,f;a&&t[a]===c&&(b=new Image,a.match(/data:image\/.*;base64,/i)?(b.src=a.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),f=t[a]={img:b},t.numTotal++,o(b,f)):e(a)||d.allowTaint===!0?(f=t[a]={img:b},t.numTotal++,o(b,f),b.src=a):B&&!d.allowTaint&&d.useCORS?(b.crossOrigin="anonymous",f=t[a]={img:b},t.numTotal++,o(b,f),b.src=a):d.proxy&&(f=t[a]={img:b},t.numTotal++,g(a,b,f)))},cleanupDOM:function(e){var g,h;if(!t.cleanupDone){u.log(e&&"string"==typeof e?"html2canvas: Cleanup because: "+e:"html2canvas: Cleanup after timeout: "+d.timeout+" ms.");for(h in t)if(t.hasOwnProperty(h)&&(g=t[h],"object"==typeof g&&g.callbackname&&g.succeeded===c)){a[g.callbackname]=c;try{delete a[g.callbackname]}catch(i){}g.script&&g.script.parentNode&&(g.script.setAttribute("src","about:blank"),g.script.parentNode.removeChild(g.script)),t.numLoaded++,t.numFailed++,u.log("html2canvas: Cleaned up failed img: '"+h+"' Steps: "+t.numLoaded+" / "+t.numTotal)}a.stop!==c?a.stop():b.execCommand!==c&&b.execCommand("Stop",!1),b.close!==c&&b.close(),t.cleanupDone=!0,e&&"string"==typeof e||f()}},renderingDone:function(){s&&a.clearTimeout(s)}},d.timeout>0&&(s=a.setTimeout(q.cleanupDOM,d.timeout)),u.log("html2canvas: Preload starts: finding background-images"),t.firstRun=!0,n(w),u.log("html2canvas: Preload: Finding images"),r=0;z>r;r+=1)q.loadImage(y[r].getAttribute("src"));return t.firstRun=!1,u.log("html2canvas: Preload: Done."),t.numTotal===t.numLoaded&&f(),q},l.Renderer=function(a,d){function e(a){function b(a){Object.keys(a).sort().forEach(function(c){var d=[],f=[],g=[],h=[];a[c].forEach(function(a){a.node.zIndex.isPositioned||a.node.zIndex.opacity<1?g.push(a):a.node.zIndex.isFloated?f.push(a):d.push(a)}),function i(a){a.forEach(function(a){h.push(a),a.children&&i(a.children)})}(d.concat(f,g)),h.forEach(function(a){a.context?b(a.context):e.push(a.node)})})}var d,e=[];return d=function(a){function b(a,d,e){var f="auto"===d.zIndex.zindex?0:Number(d.zIndex.zindex),g=a,h=d.zIndex.isPositioned,i=d.zIndex.isFloated,j={node:d},k=e;d.zIndex.ownStacking?(g=j.context={"!":[{node:d,children:[]}]},k=c):(h||i)&&(k=j.children=[]),0===f&&e?e.push(j):(a[f]||(a[f]=[]),a[f].push(j)),d.zIndex.children.forEach(function(a){b(g,a,k)})}var d={};return b(d,a),d}(a),b(d),e}function f(a){var b;if("string"==typeof d.renderer&&l.Renderer[a]!==c)b=l.Renderer[a](d);else{if("function"!=typeof a)throw new Error("Unknown renderer");b=a(d)}if("function"!=typeof b)throw new Error("Invalid renderer defined");return b}return f(d.renderer)(a,d,b,e(a.stack),l)},l.Util.Support=function(a,b){function d(){var a=new Image,d=b.createElement("canvas"),e=d.getContext===c?!1:d.getContext("2d");if(e===!1)return!1;d.width=d.height=10,a.src=["data:image/svg+xml,","","","
        ","sup","
        ","
        ","
        "].join("");try{e.drawImage(a,0,0),d.toDataURL()}catch(f){return!1}return l.Util.log("html2canvas: Parse: SVG powered rendering available"),!0}function e(){var a,c,d,e,f=!1;return b.createRange&&(a=b.createRange(),a.getBoundingClientRect&&(c=b.createElement("boundtest"),c.style.height="123px",c.style.display="block",b.body.appendChild(c),a.selectNode(c),d=a.getBoundingClientRect(),e=d.height,123===e&&(f=!0),b.body.removeChild(c))),f}return{rangeBounds:e(),svgRendering:a.svgRendering&&d()}},a.html2canvas=function(b,c){b=b.length?b:[b];var d,e,f={logging:!1,elements:b,background:"#fff",proxy:null,timeout:0,useCORS:!1,allowTaint:!1,svgRendering:!1,ignoreElements:"IFRAME|OBJECT|PARAM",useOverflow:!0,letterRendering:!1,chinese:!1,width:null,height:null,taintTest:!0,renderer:"Canvas"};return f=l.Util.Extend(c,f),l.logging=f.logging,f.complete=function(a){("function"!=typeof f.onpreloaded||f.onpreloaded(a)!==!1)&&(d=l.Parse(a,f),("function"!=typeof f.onparsed||f.onparsed(d)!==!1)&&(e=l.Renderer(d,f),"function"==typeof f.onrendered&&f.onrendered(e)))},a.setTimeout(function(){l.Preload(f)},0),{render:function(a,b){return l.Renderer(a,l.Util.Extend(b,f))},parse:function(a,b){return l.Parse(a,l.Util.Extend(b,f))},preload:function(a){return l.Preload(l.Util.Extend(a,f))},log:l.Util.log}},a.html2canvas.log=l.Util.log,a.html2canvas.Renderer={Canvas:c},l.Renderer.Canvas=function(a){function d(a,b){a.beginPath(),b.forEach(function(b){a[b.name].apply(a,b.arguments)}),a.closePath()}function e(a){if(-1===h.indexOf(a.arguments[0].src)){j.drawImage(a.arguments[0],0,0);try{j.getImageData(0,0,1,1)}catch(b){return i=g.createElement("canvas"),j=i.getContext("2d"),!1}h.push(a.arguments[0].src)}return!0}function f(b,c){switch(c.type){case"variable":b[c.name]=c.arguments;break;case"function":switch(c.name){case"createPattern":if(c.arguments[0].width>0&&c.arguments[0].height>0)try{b.fillStyle=b.createPattern(c.arguments[0],"repeat")}catch(f){k.log("html2canvas: Renderer: Error creating pattern",f.message)}break;case"drawShape":d(b,c.arguments);break;case"drawImage":c.arguments[8]>0&&c.arguments[7]>0&&(!a.taintTest||a.taintTest&&e(c))&&b.drawImage.apply(b,c.arguments);break;default:b[c.name].apply(b,c.arguments)}}}a=a||{};var g=b,h=[],i=b.createElement("canvas"),j=i.getContext("2d"),k=l.Util,m=a.canvas||g.createElement("canvas");return function(a,b,d,e,g){var h,i,j,l=m.getContext("2d"),n=a.stack;return m.width=m.style.width=b.width||n.ctx.width,m.height=m.style.height=b.height||n.ctx.height,j=l.fillStyle,l.fillStyle=k.isTransparent(n.backgroundColor)&&b.background!==c?b.background:a.backgroundColor,l.fillRect(0,0,m.width,m.height),l.fillStyle=j,e.forEach(function(a){l.textBaseline="bottom",l.save(),a.transform.matrix&&(l.translate(a.transform.origin[0],a.transform.origin[1]),l.transform.apply(l,a.transform.matrix),l.translate(-a.transform.origin[0],-a.transform.origin[1])),a.clip&&(l.beginPath(),l.rect(a.clip.left,a.clip.top,a.clip.width,a.clip.height),l.clip()),a.ctx.storage&&a.ctx.storage.forEach(function(a){f(l,a)}),l.restore()}),k.log("html2canvas: Renderer: Canvas renderer done - returning canvas obj"),1===b.elements.length&&"object"==typeof b.elements[0]&&"BODY"!==b.elements[0].nodeName?(i=g.Util.Bounds(b.elements[0]),h=d.createElement("canvas"),h.width=Math.ceil(i.width),h.height=Math.ceil(i.height),l=h.getContext("2d"),l.drawImage(m,i.left,i.top,i.width,i.height,0,0,i.width,i.height),m=null,h):m}}}(window,document),!function(a,b){b["true"]=a;var c=function(a){"use strict";function b(b){var c={};this.subscribe=function(a,b,d){if("function"!=typeof b)return!1;c.hasOwnProperty(a)||(c[a]={});var e=Math.random().toString(35);return c[a][e]=[b,!!d],e},this.unsubscribe=function(a){for(var b in c)if(c[b][a])return delete c[b][a],!0;return!1},this.publish=function(d){if(c.hasOwnProperty(d)){var e=Array.prototype.slice.call(arguments,1),f=[];for(var g in c[d]){var h=c[d][g];try{h[0].apply(b,e)}catch(i){a.console&&console.error("jsPDF PubSub Error",i.message,i)}h[1]&&f.push(g)}f.length&&f.forEach(this.unsubscribe)}}}function c(h,i,j,k){var l={};"object"==typeof h&&(l=h,h=l.orientation,i=l.unit||i,j=l.format||j,k=l.compress||l.compressPdf||k),i=i||"mm",j=j||"a4",h=(""+(h||"P")).toLowerCase();var m,n,o,p,q,r,s,t,u,v=((""+j).toLowerCase(),!!k&&"function"==typeof Uint8Array),w=l.textColor||"0 g",x=l.drawColor||"0 G",y=l.fontSize||16,z=l.lineHeight||1.15,A=l.lineWidth||.200025,B=2,C=!1,D=[],E={},F={},G=0,H=[],I={},J=[],K=0,L=0,M=0,N={title:"",subject:"",author:"",keywords:"",creator:""},O={},P=new b(O),Q=function(a){return a.toFixed(2)},R=function(a){return a.toFixed(3)},S=function(a){return("0"+parseInt(a)).slice(-2)},T=function(a){C?H[p].push(a):(M+=a.length+1,J.push(a))},U=function(){return B++,D[B]=M,T(B+" 0 obj"),B},V=function(a){T("stream"),T(a),T("endstream")},W=function(){var b,d,f,g,h,i,j,k,l;for(j=a.adler32cs||c.adler32cs,v&&"undefined"==typeof j&&(v=!1),b=1;G>=b;b++){if(U(),k=(q=I[b].width)*n,l=(r=I[b].height)*n,T("<>"),T("endobj"),d=H[b].join("\n"),U(),v){for(f=[],g=d.length;g--;)f[g]=d.charCodeAt(g);i=j.from(d),h=new e(6),h.append(new Uint8Array(f)),d=h.flush(),f=new Uint8Array(d.length+6),f.set(new Uint8Array([120,156])),f.set(d,2),f.set(new Uint8Array([255&i,i>>8&255,i>>16&255,i>>24&255]),d.length+2),d=String.fromCharCode.apply(null,f),T("<>")}else T("<>");V(d),T("endobj")}D[1]=M,T("1 0 obj"),T("<g;g++)m+=3+2*g+" 0 R ";T(m+"]"),T("/Count "+G),T(">>"),T("endobj")},X=function(a){a.objectNumber=U(),T("<>"),T("endobj")},Y=function(){for(var a in E)E.hasOwnProperty(a)&&X(E[a])},Z=function(){P.publish("putXobjectDict")},$=function(){T("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),T("/Font <<");for(var a in E)E.hasOwnProperty(a)&&T("/"+a+" "+E[a].objectNumber+" 0 R");T(">>"),T("/XObject <<"),Z(),T(">>")},_=function(){Y(),P.publish("putResources"),D[2]=M,T("2 0 obj"),T("<<"),$(),T(">>"),T("endobj"),P.publish("postPutResources")},aa=function(a,b,c){F.hasOwnProperty(b)||(F[b]={}),F[b][c]=a},ba=function(a,b,c,d){var e="F"+(Object.keys(E).length+1).toString(10),f=E[e]={id:e,PostScriptName:a,fontName:b,fontStyle:c,encoding:d,metadata:{}};return aa(e,b,c),P.publish("addFont",f),e},ca=function(){for(var a="helvetica",b="times",c="courier",d="normal",e="bold",f="italic",g="bolditalic",h="StandardEncoding",i=[["Helvetica",a,d],["Helvetica-Bold",a,e],["Helvetica-Oblique",a,f],["Helvetica-BoldOblique",a,g],["Courier",c,d],["Courier-Bold",c,e],["Courier-Oblique",c,f],["Courier-BoldOblique",c,g],["Times-Roman",b,d],["Times-Bold",b,e],["Times-Italic",b,f],["Times-BoldItalic",b,g]],j=0,k=i.length;k>j;j++){var l=ba(i[j][0],i[j][1],i[j][2],h),m=i[j][0].split("-");aa(l,m[0],m[1]||"")}P.publish("addFonts",{fonts:E,dictionary:F})},da=function(b){return b.foo=function(){try{return b.apply(this,arguments)}catch(c){var d=c.stack||"";~d.indexOf(" at ")&&(d=d.split(" at ")[1]);var e="Error in function "+d.split("\n")[0].split("<")[0]+": "+c.message;if(!a.console)throw new Error(e);a.console.error(e,c),a.alert&&alert(e)}},b.foo.bar=b,b.foo},ea=function(a,b){var c,d,e,f,g,h,i,j,k;if(b=b||{},e=b.sourceEncoding||"Unicode",g=b.outputEncoding,(b.autoencode||g)&&E[m].metadata&&E[m].metadata[e]&&E[m].metadata[e].encoding&&(f=E[m].metadata[e].encoding,!g&&E[m].encoding&&(g=E[m].encoding),!g&&f.codePages&&(g=f.codePages[0]),"string"==typeof g&&(g=f[g]),g)){for(i=!1,h=[],c=0,d=a.length;d>c;c++)j=g[a.charCodeAt(c)],h.push(j?String.fromCharCode(j):a[c]),h[c].charCodeAt(0)>>8&&(i=!0);a=h.join("")}for(c=a.length;void 0===i&&0!==c;)a.charCodeAt(c-1)>>8&&(i=!0),c--;if(!i)return a;for(h=b.noBOM?[]:[254,255],c=0,d=a.length;d>c;c++){if(j=a.charCodeAt(c),k=j>>8,k>>8)throw new Error("Character at position "+c+" of string '"+a+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");h.push(k),h.push(j-(k<<8))}return String.fromCharCode.apply(void 0,h)},fa=function(a,b){return ea(a,b).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},ga=function(){T("/Producer (jsPDF "+c.version+")");for(var a in N)N.hasOwnProperty(a)&&N[a]&&T("/"+a.substr(0,1).toUpperCase()+a.substr(1)+" ("+fa(N[a])+")");var b=new Date,d=b.getTimezoneOffset(),e=0>d?"+":"-",f=Math.floor(Math.abs(d/60)),g=Math.abs(d%60),h=[e,S(f),"'",S(g),"'"].join("");T(["/CreationDate (D:",b.getFullYear(),S(b.getMonth()+1),S(b.getDate()),S(b.getHours()),S(b.getMinutes()),S(b.getSeconds()),h,")"].join(""))},ha=function(){switch(T("/Type /Catalog"),T("/Pages 1 0 R"),t||(t="fullwidth"),t){case"fullwidth":T("/OpenAction [3 0 R /FitH null]");break;case"fullheight":T("/OpenAction [3 0 R /FitV null]");break;case"fullpage":T("/OpenAction [3 0 R /Fit]");break;case"original":T("/OpenAction [3 0 R /XYZ null null 1]");break;default:var a=""+t;"%"===a.substr(a.length-1)&&(t=parseInt(t)/100),"number"==typeof t&&T("/OpenAction [3 0 R /XYZ null null "+Q(t)+"]"); + +}switch(u||(u="continuous"),u){case"continuous":T("/PageLayout /OneColumn");break;case"single":T("/PageLayout /SinglePage");break;case"two":case"twoleft":T("/PageLayout /TwoColumnLeft");break;case"tworight":T("/PageLayout /TwoColumnRight")}s&&T("/PageMode /"+s),P.publish("putCatalog")},ia=function(){T("/Size "+(B+1)),T("/Root "+B+" 0 R"),T("/Info "+(B-1)+" 0 R")},ja=function(a,b){var c="string"==typeof b&&b.toLowerCase();if("string"==typeof a){var d=a.toLowerCase();g.hasOwnProperty(d)&&(a=g[d][0]/n,b=g[d][1]/n)}if(Array.isArray(a)&&(b=a[1],a=a[0]),c){switch(c.substr(0,1)){case"l":b>a&&(c="s");break;case"p":a>b&&(c="s")}"s"===c&&(o=a,a=b,b=o)}C=!0,H[++G]=[],I[G]={width:Number(a)||q,height:Number(b)||r},la(G)},ka=function(){ja.apply(this,arguments),T(Q(A*n)+" w"),T(x),0!==K&&T(K+" J"),0!==L&&T(L+" j"),P.publish("addPage",{pageNumber:G})},la=function(a){a>0&&G>=a&&(p=a,q=I[a].width,r=I[a].height)},ma=function(a,b){var c;a=void 0!==a?a:E[m].fontName,b=void 0!==b?b:E[m].fontStyle;try{c=F[a][b]}catch(d){}if(!c)throw new Error("Unable to look up font label for font '"+a+"', '"+b+"'. Refer to getFontList() for available fonts.");return c},na=function(){C=!1,B=2,J=[],D=[],T("%PDF-"+f),W(),_(),U(),T("<<"),ga(),T(">>"),T("endobj"),U(),T("<<"),ha(),T(">>"),T("endobj");var a,b=M,c="0000000000";for(T("xref"),T("0 "+(B+1)),T(c+" 65535 f "),a=1;B>=a;a++)T((c+D[a]).slice(-10)+" 00000 n ");return T("trailer"),T("<<"),ia(),T(">>"),T("startxref"),T(b),T("%%EOF"),C=!0,J.join("\n")},oa=function(a){var b="S";return"F"===a?b="f":"FD"===a||"DF"===a?b="B":("f"===a||"f*"===a||"B"===a||"B*"===a)&&(b=a),b},pa=function(){for(var a=na(),b=a.length,c=new ArrayBuffer(b),d=new Uint8Array(c);b--;)d[b]=a.charCodeAt(b);return c},qa=function(){return new Blob([pa()],{type:"application/pdf"})},ra=da(function(b,c){var e="dataur"===(""+b).substr(0,6)?"data:application/pdf;base64,"+btoa(na()):0;switch(b){case void 0:return na();case"save":if(navigator.getUserMedia&&(void 0===a.URL||void 0===a.URL.createObjectURL))return O.output("dataurlnewwindow");d(qa(),c),"function"==typeof d.unload&&a.setTimeout&&setTimeout(d.unload,911);break;case"arraybuffer":return pa();case"blob":return qa();case"bloburi":case"bloburl":return a.URL&&a.URL.createObjectURL(qa())||void 0;case"datauristring":case"dataurlstring":return e;case"dataurlnewwindow":var f=a.open(e);if(f||"undefined"==typeof safari)return f;case"datauri":case"dataurl":return a.document.location.href=e;default:throw new Error('Output type "'+b+'" is not supported.')}});switch(i){case"pt":n=1;break;case"mm":n=72/25.4;break;case"cm":n=72/2.54;break;case"in":n=72;break;case"px":n=96/72;break;case"pc":n=12;break;case"em":n=12;break;case"ex":n=6;break;default:throw"Invalid unit: "+i}O.internal={pdfEscape:fa,getStyle:oa,getFont:function(){return E[ma.apply(O,arguments)]},getFontSize:function(){return y},getLineHeight:function(){return y*z},write:function(a){T(1===arguments.length?a:Array.prototype.join.call(arguments," "))},getCoordinateString:function(a){return Q(a*n)},getVerticalCoordinateString:function(a){return Q((r-a)*n)},collections:{},newObject:U,putStream:V,events:P,scaleFactor:n,pageSize:{get width(){return q},get height(){return r}},output:function(a,b){return ra(a,b)},getNumberOfPages:function(){return H.length-1},pages:H},O.addPage=function(){return ka.apply(this,arguments),this},O.setPage=function(){return la.apply(this,arguments),this},O.setDisplayMode=function(a,b,c){return t=a,u=b,s=c,this},O.text=function(a,b,c,d,e){function f(a){return a=a.split(" ").join(Array(l.TabLen||9).join(" ")),fa(a,d)}"number"==typeof a&&(o=c,c=b,b=a,a=o),"string"==typeof a&&a.match(/[\n\r]/)&&(a=a.split(/\r\n|\r|\n/g)),"number"==typeof d&&(e=d,d=null);var g,h="",i="Td";if(e){e*=Math.PI/180;var j=Math.cos(e),k=Math.sin(e);h=[Q(j),Q(k),Q(-1*k),Q(j),""].join(" "),i="Tm"}if(d=d||{},"noBOM"in d||(d.noBOM=!0),"autoencode"in d||(d.autoencode=!0),"string"==typeof a)a=f(a);else{if(!(a instanceof Array))throw new Error('Type of text must be string or Array. "'+a+'" is not recognized.');for(var p=a.concat(),q=[],s=p.length;s--;)q.push(f(p.shift()));var t=Math.ceil((r-c)*n/(y*z));t>=0&&te;e++,b+=d)this.text(a[e],b,c)},O.line=function(a,b,c,d){return this.lines([[c-a,d-b]],a,b)},O.clip=function(){T("W"),T("S")},O.lines=function(a,b,c,d,e,f){var g,h,i,j,k,l,m,p,q,s,t;for("number"==typeof a&&(o=c,c=b,b=a,a=o),d=d||[1,1],T(R(b*n)+" "+R((r-c)*n)+" m "),g=d[0],h=d[1],j=a.length,s=b,t=c,i=0;j>i;i++)k=a[i],2===k.length?(s=k[0]*g+s,t=k[1]*h+t,T(R(s*n)+" "+R((r-t)*n)+" l")):(l=k[0]*g+s,m=k[1]*h+t,p=k[2]*g+s,q=k[3]*h+t,s=k[4]*g+s,t=k[5]*h+t,T(R(l*n)+" "+R((r-m)*n)+" "+R(p*n)+" "+R((r-q)*n)+" "+R(s*n)+" "+R((r-t)*n)+" c"));return f&&T(" h"),null!==e&&T(oa(e)),this},O.rect=function(a,b,c,d,e){return oa(e),T([Q(a*n),Q((r-b)*n),Q(c*n),Q(-d*n),"re"].join(" ")),null!==e&&T(oa(e)),this},O.triangle=function(a,b,c,d,e,f,g){return this.lines([[c-a,d-b],[e-c,f-d],[a-e,b-f]],a,b,[1,1],g,!0),this},O.roundedRect=function(a,b,c,d,e,f,g){var h=4/3*(Math.SQRT2-1);return this.lines([[c-2*e,0],[e*h,0,e,f-f*h,e,f],[0,d-2*f],[0,f*h,-(e*h),f,-e,f],[-c+2*e,0],[-(e*h),0,-e,-(f*h),-e,-f],[0,-d+2*f],[0,-(f*h),e*h,-f,e,-f]],a+e,b,[1,1],g),this},O.ellipse=function(a,b,c,d,e){var f=4/3*(Math.SQRT2-1)*c,g=4/3*(Math.SQRT2-1)*d;return T([Q((a+c)*n),Q((r-b)*n),"m",Q((a+c)*n),Q((r-(b-g))*n),Q((a+f)*n),Q((r-(b-d))*n),Q(a*n),Q((r-(b-d))*n),"c"].join(" ")),T([Q((a-f)*n),Q((r-(b-d))*n),Q((a-c)*n),Q((r-(b-g))*n),Q((a-c)*n),Q((r-b)*n),"c"].join(" ")),T([Q((a-c)*n),Q((r-(b+g))*n),Q((a-f)*n),Q((r-(b+d))*n),Q(a*n),Q((r-(b+d))*n),"c"].join(" ")),T([Q((a+f)*n),Q((r-(b+d))*n),Q((a+c)*n),Q((r-(b+g))*n),Q((a+c)*n),Q((r-b)*n),"c"].join(" ")),null!==e&&T(oa(e)),this},O.circle=function(a,b,c,d){return this.ellipse(a,b,c,c,d)},O.setProperties=function(a){for(var b in N)N.hasOwnProperty(b)&&a[b]&&(N[b]=a[b]);return this},O.setFontSize=function(a){return y=a,this},O.setFont=function(a,b){return m=ma(a,b),this},O.setFontStyle=O.setFontType=function(a){return m=ma(void 0,a),this},O.getFontList=function(){var a,b,c,d={};for(a in F)if(F.hasOwnProperty(a)){d[a]=c=[];for(b in F[a])F[a].hasOwnProperty(b)&&c.push(b)}return d},O.setLineWidth=function(a){return T((a*n).toFixed(2)+" w"),this},O.setDrawColor=function(a,b,c,d){var e;return e=void 0===b||void 0===d&&a===b===c?"string"==typeof a?a+" G":Q(a/255)+" G":void 0===d?"string"==typeof a?[a,b,c,"RG"].join(" "):[Q(a/255),Q(b/255),Q(c/255),"RG"].join(" "):"string"==typeof a?[a,b,c,d,"K"].join(" "):[Q(a),Q(b),Q(c),Q(d),"K"].join(" "),T(e),this},O.setFillColor=function(a,b,c,d){var e;return e=void 0===b||void 0===d&&a===b===c?"string"==typeof a?a+" g":Q(a/255)+" g":void 0===d?"string"==typeof a?[a,b,c,"rg"].join(" "):[Q(a/255),Q(b/255),Q(c/255),"rg"].join(" "):"string"==typeof a?[a,b,c,d,"k"].join(" "):[Q(a),Q(b),Q(c),Q(d),"k"].join(" "),T(e),this},O.setTextColor=function(a,b,c){if("string"==typeof a&&/^#[0-9A-Fa-f]{6}$/.test(a)){var d=parseInt(a.substr(1),16);a=d>>16&255,b=d>>8&255,c=255&d}return w=0===a&&0===b&&0===c||"undefined"==typeof b?R(a/255)+" g":[R(a/255),R(b/255),R(c/255),"rg"].join(" "),this},O.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},O.setLineCap=function(a){var b=this.CapJoinStyles[a];if(void 0===b)throw new Error("Line cap style of '"+a+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return K=b,T(b+" J"),this},O.setLineJoin=function(a){var b=this.CapJoinStyles[a];if(void 0===b)throw new Error("Line join style of '"+a+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return L=b,T(b+" j"),this},O.output=ra,O.save=function(a){O.output("save",a)};for(var sa in c.API)c.API.hasOwnProperty(sa)&&("events"===sa&&c.API.events.length?!function(a,b){var c,d,e;for(e=b.length-1;-1!==e;e--)c=b[e][0],d=b[e][1],a.subscribe.apply(a,[c].concat("function"==typeof d?[d]:d))}(P,c.API.events):O[sa]=c.API[sa]);return ca(),m="F1",ka(j,h),P.publish("initialized"),O}var f="1.3",g={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};return c.API={events:[]},c.version="1.0.272-git 2014-09-29T15:09:diegocr","function"==typeof define&&define.amd?define("jsPDF",function(){return c}):a.jsPDF=c,c}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);!function(a){"use strict";a.addHTML=function(a,b,c,d,e){if("undefined"==typeof html2canvas&&"undefined"==typeof rasterizeHTML)throw new Error("You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js");"number"!=typeof b&&(d=b,e=c),"function"==typeof d&&(e=d,d=null);var f=this.internal,g=f.scaleFactor,h=f.pageSize.width,i=f.pageSize.height;if(d=d||{},d.onrendered=function(a){b=parseInt(b)||0,c=parseInt(c)||0;var f=d.dim||{},j=f.h||0,k=f.w||Math.min(h,a.width/g)-b,l="JPEG";if(d.format&&(l=d.format),a.height>i&&d.pagesplit){var m=function(){for(var d=0;;){var f=document.createElement("canvas");f.width=Math.min(h*g,a.width),f.height=Math.min(i*g,a.height-d);var j=f.getContext("2d");j.drawImage(a,0,d,a.width,f.height,0,0,f.width,f.height);var m=[f,b,d?0:c,f.width/g,f.height/g,l,null,"SLOW"];if(this.addImage.apply(this,m),d+=f.height,d>=a.height)break;this.addPage()}e(k,d,null,m)}.bind(this);if("CANVAS"===a.nodeName){var n=new Image;n.onload=m,n.src=a.toDataURL("image/png"),a=n}else m()}else{var o=Math.random().toString(35),p=[a,b,c,k,j,l,o,"SLOW"];this.addImage.apply(this,p),e(k,j,o,p)}}.bind(this),"undefined"!=typeof html2canvas&&!d.rstz)return html2canvas(a,d);if("undefined"!=typeof rasterizeHTML){var j="drawDocument";return"string"==typeof a&&(j=/^http/.test(a)?"drawURL":"drawHTML"),d.width=d.width||h*g,rasterizeHTML[j](a,void 0,d).then(function(a){d.onrendered(a.image)},function(a){e(null,a)})}return null}}(c.API),function(a){"use strict";var b="addImage_",c=["jpeg","jpg","png"],d=function(a){var b=this.internal.newObject(),c=this.internal.write,e=this.internal.putStream;if(a.n=b,c("<>"),"trns"in a&&a.trns.constructor==Array){for(var f="",g=0,h=a.trns.length;h>g;g++)f+=a.trns[g]+" "+a.trns[g]+" ";c("/Mask ["+f+"]")}if("smask"in a&&c("/SMask "+(b+1)+" 0 R"),c("/Length "+a.data.length+">>"),e(a.data),c("endobj"),"smask"in a){var i="/Predictor 15 /Colors 1 /BitsPerComponent "+a.bpc+" /Columns "+a.w,j={w:a.w,h:a.h,cs:"DeviceGray",bpc:a.bpc,dp:i,data:a.smask};"f"in a&&(j.f=a.f),d.call(this,j)}a.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),c("<< /Length "+a.pal.length+">>"),e(this.arrayBufferToBinaryString(new Uint8Array(a.pal))),c("endobj"))},e=function(){var a=this.internal.collections[b+"images"];for(var c in a)d.call(this,a[c])},f=function(){var a,c=this.internal.collections[b+"images"],d=this.internal.write;for(var e in c)a=c[e],d("/I"+a.i,a.n,"0","R")},g=function(b){return b&&"string"==typeof b&&(b=b.toUpperCase()),b in a.image_compression?b:a.image_compression.NONE},h=function(){var a=this.internal.collections[b+"images"];return a||(this.internal.collections[b+"images"]=a={},this.internal.events.subscribe("putResources",e),this.internal.events.subscribe("putXobjectDict",f)),a},i=function(a){var b=0;return a&&(b=Object.keys?Object.keys(a).length:function(a){var b=0;for(var c in a)a.hasOwnProperty(c)&&b++;return b}(a)),b},j=function(a){return"undefined"==typeof a||null===a},k=function(b){return"string"==typeof b&&a.sHashCode(b)},l=function(a){return-1===c.indexOf(a)},m=function(b){return"function"!=typeof a["process"+b.toUpperCase()]},n=function(a){return"object"==typeof a&&1===a.nodeType},o=function(a,b,c){if("IMG"===a.nodeName&&a.hasAttribute("src")){var d=""+a.getAttribute("src");if(!c&&0===d.indexOf("data:image/"))return d;!b&&/\.png(?:[?#].*)?$/i.test(d)&&(b="png")}if("CANVAS"===a.nodeName)var e=a;else{var e=document.createElement("canvas");e.width=a.clientWidth||a.width,e.height=a.clientHeight||a.height;var f=e.getContext("2d");if(!f)throw"addImage requires canvas to be supported by browser.";if(c){var g,h,i,j,k,l,m,n,o=Math.PI/180;"object"==typeof c&&(g=c.x,h=c.y,i=c.bg,c=c.angle),n=c*o,j=Math.abs(Math.cos(n)),k=Math.abs(Math.sin(n)),l=e.width,m=e.height,e.width=m*k+l*j,e.height=m*j+l*k,isNaN(g)&&(g=e.width/2),isNaN(h)&&(h=e.height/2),f.clearRect(0,0,e.width,e.height),f.fillStyle=i||"white",f.fillRect(0,0,e.width,e.height),f.save(),f.translate(g,h),f.rotate(n),f.drawImage(a,-(l/2),-(m/2)),f.rotate(-n),f.translate(-g,-h),f.restore()}else f.drawImage(a,0,0,e.width,e.height)}return e.toDataURL("png"==(""+b).toLowerCase()?"image/png":"image/jpeg")},p=function(a,b){var c;if(b)for(var d in b)if(a===b[d].alias){c=b[d];break}return c},q=function(a,b,c){return a||b||(a=-96,b=-96),0>a&&(a=-1*c.w*72/a/this.internal.scaleFactor),0>b&&(b=-1*c.h*72/b/this.internal.scaleFactor),0===a&&(a=b*c.w/c.h),0===b&&(b=a*c.h/c.w),[a,b]},r=function(a,b,c,d,e,f,g){var h=q.call(this,c,d,e),i=this.internal.getCoordinateString,j=this.internal.getVerticalCoordinateString;c=h[0],d=h[1],g[f]=e,this.internal.write("q",i(c),"0 0",i(d),i(a),j(b+d),"cm /I"+e.i,"Do Q")};a.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPERATION:"Seperation",DEVICE_N:"DeviceN"},a.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},a.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},a.sHashCode=function(a){return Array.prototype.reduce&&a.split("").reduce(function(a,b){return a=(a<<5)-a+b.charCodeAt(0),a&a},0)},a.isString=function(a){return"string"==typeof a},a.extractInfoFromBase64DataURI=function(a){return/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(a)},a.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},a.isArrayBuffer=function(a){return this.supportsArrayBuffer()?a instanceof ArrayBuffer:!1},a.isArrayBufferView=function(a){return this.supportsArrayBuffer()?"undefined"==typeof Uint32Array?!1:a instanceof Int8Array||a instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&a instanceof Uint8ClampedArray||a instanceof Int16Array||a instanceof Uint16Array||a instanceof Int32Array||a instanceof Uint32Array||a instanceof Float32Array||a instanceof Float64Array:!1},a.binaryStringToUint8Array=function(a){for(var b=a.length,c=new Uint8Array(b),d=0;b>d;d++)c[d]=a.charCodeAt(d);return c},a.arrayBufferToBinaryString=function(a){this.isArrayBuffer(a)&&(a=new Uint8Array(a));for(var b="",c=a.byteLength,d=0;c>d;d++)b+=String.fromCharCode(a[d]);return b},a.arrayBufferToBase64=function(a){for(var b,c,d,e,f,g="",h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=new Uint8Array(a),j=i.byteLength,k=j%3,l=j-k,m=0;l>m;m+=3)f=i[m]<<16|i[m+1]<<8|i[m+2],b=(16515072&f)>>18,c=(258048&f)>>12,d=(4032&f)>>6,e=63&f,g+=h[b]+h[c]+h[d]+h[e];return 1==k?(f=i[l],b=(252&f)>>2,c=(3&f)<<4,g+=h[b]+h[c]+"=="):2==k&&(f=i[l]<<8|i[l+1],b=(64512&f)>>10,c=(1008&f)>>4,d=(15&f)<<2,g+=h[b]+h[c]+h[d]+"="),g},a.createImageInfo=function(a,b,c,d,e,f,g,h,i,j,k,l){var m={alias:h,w:b,h:c,cs:d,bpc:e,i:g,data:a};return f&&(m.f=f),i&&(m.dp=i),j&&(m.trns=j),k&&(m.pal=k),l&&(m.smask=l),m},a.addImage=function(a,b,d,e,f,q,s,t,u){if("string"!=typeof b){var v=q;q=f,f=e,e=d,d=b,b=v}if("object"==typeof a&&!n(a)&&"imageData"in a){var w=a;a=w.imageData,b=w.format||b,d=w.x||d||0,e=w.y||e||0,f=w.w||f,q=w.h||q,s=w.alias||s,t=w.compression||t,u=w.rotation||w.angle||u}if(isNaN(d)||isNaN(e))throw console.error("jsPDF.addImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addImage");var x,y=h.call(this);if(!(x=p(a,y))){var z;if(n(a)&&(a=o(a,b,u)),j(s)&&(s=k(a)),!(x=p(s,y))){if(this.isString(a)){var A=this.extractInfoFromBase64DataURI(a);A?(b=A[2],a=atob(A[3])):137===a.charCodeAt(0)&&80===a.charCodeAt(1)&&78===a.charCodeAt(2)&&71===a.charCodeAt(3)&&(b="png")}if(b=(b||"JPEG").toLowerCase(),l(b))throw new Error("addImage currently only supports formats "+c+", not '"+b+"'");if(m(b))throw new Error("please ensure that the plugin for '"+b+"' support is added");if(this.supportsArrayBuffer()&&(z=a,a=this.binaryStringToUint8Array(a)),x=this["process"+b.toUpperCase()](a,i(y),s,g(t),z),!x)throw new Error("An unkwown error occurred whilst processing the image")}}return r.call(this,d,e,f,q,x,x.i,y),this};var s=function(a){var b,c,d;if(255===!a.charCodeAt(0)||216===!a.charCodeAt(1)||255===!a.charCodeAt(2)||224===!a.charCodeAt(3)||!a.charCodeAt(6)==="J".charCodeAt(0)||!a.charCodeAt(7)==="F".charCodeAt(0)||!a.charCodeAt(8)==="I".charCodeAt(0)||!a.charCodeAt(9)==="F".charCodeAt(0)||0===!a.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var e=256*a.charCodeAt(4)+a.charCodeAt(5),f=4,g=a.length;g>f;){if(f+=e,255!==a.charCodeAt(f))throw new Error("getJpegSize could not find the size of the image");if(192===a.charCodeAt(f+1)||193===a.charCodeAt(f+1)||194===a.charCodeAt(f+1)||195===a.charCodeAt(f+1)||196===a.charCodeAt(f+1)||197===a.charCodeAt(f+1)||198===a.charCodeAt(f+1)||199===a.charCodeAt(f+1))return c=256*a.charCodeAt(f+5)+a.charCodeAt(f+6),b=256*a.charCodeAt(f+7)+a.charCodeAt(f+8),d=a.charCodeAt(f+9),[b,c,d];f+=2,e=256*a.charCodeAt(f)+a.charCodeAt(f+1)}},t=function(a){var b=a[0]<<8|a[1];if(65496!==b)throw new Error("Supplied data is not a JPEG");for(var c,d,e,f,g=a.length,h=(a[4]<<8)+a[5],i=4;g>i;){if(i+=h,c=u(a,i),h=(c[2]<<8)+c[3],(192===c[1]||194===c[1])&&255===c[0]&&h>7)return c=u(a,i+5),d=(c[2]<<8)+c[3],e=(c[0]<<8)+c[1],f=c[4],{width:d,height:e,numcomponents:f};i+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")},u=function(a,b){return a.subarray(b,b+5)};a.processJPEG=function(a,b,c,d,e){var f,g=this.color_spaces.DEVICE_RGB,h=this.decode.DCT_DECODE,i=8;return this.isString(a)?(f=s(a),this.createImageInfo(a,f[0],f[1],1==f[3]?this.color_spaces.DEVICE_GRAY:g,i,h,b,c)):(this.isArrayBuffer(a)&&(a=new Uint8Array(a)),this.isArrayBufferView(a)?(f=t(a),a=e||this.arrayBufferToBinaryString(a),this.createImageInfo(a,f.width,f.height,1==f.numcomponents?this.color_spaces.DEVICE_GRAY:g,i,h,b,c)):null)},a.processJPG=function(){return this.processJPEG.apply(this,arguments)}}(c.API),function(a){"use strict";a.autoPrint=function(){var a;return this.internal.events.subscribe("postPutResources",function(){a=this.internal.newObject(),this.internal.write("<< /S/Named /Type/Action /N/Print >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.write("/OpenAction "+a+" 0 R")}),this}}(c.API),function(a){"use strict";var b,c,d,e,f=3,g=13,h={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},i=1,j=function(a,b,c,d,e){h={x:a,y:b,w:c,h:d,ln:e}},k=function(){return h},l={left:0,top:0,bottom:0};a.setHeaderFunction=function(a){e=a},a.getTextDimensions=function(a){b=this.internal.getFont().fontName,c=this.table_font_size||this.internal.getFontSize(),d=this.internal.getFont().fontStyle;var e,f,g=19.049976/25.4;return f=document.createElement("font"),f.id="jsPDFCell",f.style.fontStyle=d,f.style.fontName=b,f.style.fontSize=c+"pt",f.textContent=a,document.body.appendChild(f),e={w:(f.offsetWidth+1)*g,h:(f.offsetHeight+1)*g},document.body.removeChild(f),e},a.cellAddPage=function(){var a=this.margins||l;this.addPage(),j(a.left,a.top,void 0,void 0),i+=1},a.cellInitialize=function(){h={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},i=1},a.cell=function(a,b,c,d,e,h,i){var m=k();if(void 0!==m.ln)if(m.ln===h)a=m.x+m.w,b=m.y;else{var n=this.margins||l;m.y+m.h+d+g>=this.internal.pageSize.height-n.bottom&&(this.cellAddPage(),this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(h,!0)),b=k().y+k().h}if(void 0!==e[0])if(this.printingHeaderRow?this.rect(a,b,c,d,"FD"):this.rect(a,b,c,d),"right"===i){if(e instanceof Array)for(var o=0;oc;c+=1)e=a[c],b?-1===b(f,e)&&(f=e):e>f&&(f=e);return f},a.table=function(b,c,d,e,f){if(!d)throw"No data for PDF table";var g,j,k,m,n,o,p,q,r,s,t=[],u=[],v={},w={},x=[],y=[],z=!1,A=!0,B=12,C=l;if(C.width=this.internal.pageSize.width,f&&(f.autoSize===!0&&(z=!0),f.printHeaders===!1&&(A=!1),f.fontSize&&(B=f.fontSize),f.margins&&(C=f.margins)),this.lnMod=0,h={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},i=1,this.printHeaders=A,this.margins=C,this.setFontSize(B),this.table_font_size=B,void 0===e||null===e)t=Object.keys(d[0]);else if(e[0]&&"string"!=typeof e[0]){var D=19.049976/25.4;for(j=0,k=e.length;k>j;j+=1)g=e[j],t.push(g.name),u.push(g.prompt),w[g.name]=g.width*D}else t=e;if(z)for(s=function(a){return a[g]},j=0,k=t.length;k>j;j+=1){for(g=t[j],v[g]=d.map(s),x.push(this.getTextDimensions(u[j]||g).w),o=v[g],p=0,m=o.length;m>p;p+=1)n=o[p],x.push(this.getTextDimensions(n).w);w[g]=a.arrayMax(x)}if(A){var E=this.calculateLineHeight(t,w,u.length?u:t);for(j=0,k=t.length;k>j;j+=1)g=t[j],y.push([b,c,w[g],E,String(u.length?u[j]:g)]);this.setTableHeaderRow(y),this.printHeaderRow(1,!1)}for(j=0,k=d.length;k>j;j+=1){var E;for(q=d[j],E=this.calculateLineHeight(t,w,q),p=0,r=t.length;r>p;p+=1)g=t[p],this.cell(b,c,w[g],E,q[g],j+2,g.align)}return this.lastCellPos=h,this.table_x=b,this.table_y=c,this},a.calculateLineHeight=function(a,b,c){for(var d,e=0,g=0;ge&&(e=h)}return e},a.setTableHeaderRow=function(a){this.tableHeaderRow=a},a.printHeaderRow=function(a,b){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var c,d,f,g;if(this.printingHeaderRow=!0,void 0!==e){var h=e(this,i);j(h[0],h[1],h[2],h[3],-1)}this.setFontStyle("bold");var k=[];for(f=0,g=this.tableHeaderRow.length;g>f;f+=1)this.setFillColor(200,200,200),c=this.tableHeaderRow[f],b&&(c[1]=this.margins&&this.margins.top||0,k.push(c)),d=[].concat(c),this.cell.apply(this,d.concat(a));k.length>0&&this.setTableHeaderRow(k),this.setFontStyle("normal"),this.printingHeaderRow=!1}}(c.API),function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;b=function(){function a(){}return function(b){return a.prototype=b,new a}}(),j=function(a){var b,c,d,e,f,g,h;for(c=0,d=a.length,b=void 0,e=!1,g=!1;!e&&c!==d;)b=a[c]=a[c].trimLeft(),b&&(e=!0),c++;for(c=d-1;d&&!g&&-1!==c;)b=a[c]=a[c].trimRight(),b&&(g=!0),c--;for(f=/\s+$/g,h=!0,c=0;c!==d;)b=a[c].replace(/\s+/g," "),h&&(b=b.trimLeft()),b&&(h=f.test(b)),a[c]=b,c++;return a},k=function(a,b,c,d){return this.pdf=a,this.x=b,this.y=c,this.settings=d,this.watchFunctions=[],this.init(),this},l=function(a){var b,c,e;for(b=void 0,e=a.split(","),c=e.shift();!b&&c;)b=d[c.trim().toLowerCase()],c=e.shift();return b},m=function(a){a="auto"===a?"0px":a,a.indexOf("em")>-1&&!isNaN(Number(a.replace("em","")))&&(a=18.719*Number(a.replace("em",""))+"px"),a.indexOf("pt")>-1&&!isNaN(Number(a.replace("pt","")))&&(a=1.333*Number(a.replace("pt",""))+"px");var b,c,d;return c=void 0,b=16,(d=n[a])?d:(d={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[{css_line_height_string:a}],d!==c?n[a]=d/b:(d=parseFloat(a))?n[a]=d/b:(d=a.match(/([\d\.]+)(px)/),n[a]=3===d.length?parseFloat(d[1])/b:1))},i=function(a){var b,c,d;return d=function(a){var b;return b=function(a){return document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(a,null):a.currentStyle?a.currentStyle:a.style}(a),function(a){return a=a.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase()}),b[a]}}(a),b={},c=void 0,b["font-family"]=l(d("font-family"))||"times",b["font-style"]=e[d("font-style")]||"normal",b["text-align"]=TextAlignMap[d("text-align")]||"left",c=f[d("font-weight")]||"normal","bold"===c&&(b["font-style"]="normal"===b["font-style"]?c:c+b["font-style"]),b["font-size"]=m(d("font-size"))||1,b["line-height"]=m(d("line-height"))||1,b.display="inline"===d("display")?"inline":"block",c="block"===b.display,b["margin-top"]=c&&m(d("margin-top"))||0,b["margin-bottom"]=c&&m(d("margin-bottom"))||0,b["padding-top"]=c&&m(d("padding-top"))||0,b["padding-bottom"]=c&&m(d("padding-bottom"))||0,b["margin-left"]=c&&m(d("margin-left"))||0,b["margin-right"]=c&&m(d("margin-right"))||0,b["padding-left"]=c&&m(d("padding-left"))||0,b["padding-right"]=c&&m(d("padding-right"))||0,b["float"]=g[d("cssFloat")]||"none",b.clear=h[d("clear")]||"none",b},o=function(a,b,c){var d,e,f,g,h;if(f=!1,e=void 0,g=void 0,h=void 0,d=c["#"+a.id])if("function"==typeof d)f=d(a,b);else for(e=0,g=d.length;!f&&e!==g;)f=d[e](a,b),e++;if(d=c[a.nodeName],!f&&d)if("function"==typeof d)f=d(a,b);else for(e=0,g=d.length;!f&&e!==g;)f=d[e](a,b),e++;return f},t=function(a,b){var c,d,e,f,g,h,i,j,k,l;for(c=[],d=[],e=0,l=a.rows[0].cells.length,j=a.clientWidth;l>e;)k=a.rows[0].cells[e],d[e]={name:k.textContent.toLowerCase().replace(/\s+/g,""),prompt:k.textContent.replace(/\r?\n/g,""),width:k.clientWidth/j*b.pdf.internal.pageSize.width},e++;for(e=1;eh;){if(e=f[h],"object"==typeof e){if(b.executeWatchFunctions(e),1===e.nodeType&&"HEADER"===e.nodeName){var q=e,r=b.pdf.margins_doc.top;b.pdf.internal.events.subscribe("addPage",function(){b.y=r,c(q,b,d),b.pdf.margins_doc.top=b.y+10,b.y+=10},!1)}if(8===e.nodeType&&"#comment"===e.nodeName)~e.textContent.indexOf("ADD_PAGE")&&(b.pdf.addPage(),b.y=b.pdf.margins_doc.top);else if(1!==e.nodeType||u[e.nodeName])if(3===e.nodeType){var s=e.nodeValue;if(e.nodeValue&&"LI"===e.parentNode.nodeName)if("OL"===e.parentNode.parentNode.nodeName)s=v++ +". "+s;else{var w=16*g["font-size"],x=2;w>20&&(x=3),n=function(a,b){this.pdf.circle(a,b,x,"FD")}}b.addText(s,g)}else"string"==typeof e&&b.addText(e,g);else{var y;if("IMG"===e.nodeName){var z=e.getAttribute("src");y=p[b.pdf.sHashCode(z)||z]}if(y){b.pdf.internal.pageSize.height-b.pdf.margins_doc.bottomb.pdf.margins_doc.top&&(b.pdf.addPage(),b.y=b.pdf.margins_doc.top,b.executeWatchFunctions(e));var A=i(e),B=b.x,C=12/b.pdf.internal.scaleFactor,D=(A["margin-left"]+A["padding-left"])*C,E=(A["margin-right"]+A["padding-right"])*C,F=(A["margin-top"]+A["padding-top"])*C,G=(A["margin-bottom"]+A["padding-bottom"])*C;B+=void 0!==A["float"]&&"right"===A["float"]?b.settings.width-e.width-E:D,b.pdf.addImage(y,B,b.y+F,e.width,e.height),y=void 0,"right"===A["float"]||"left"===A["float"]?(b.watchFunctions.push(function(a,c,d,e){return b.y>=c?(b.x+=a,b.settings.width+=d,!0):e&&1===e.nodeType&&!u[e.nodeName]&&b.x+e.width>b.pdf.margins_doc.left+b.pdf.margins_doc.width?(b.x+=a,b.y=c,b.settings.width+=d,!0):!1}.bind(this,"left"===A["float"]?-e.width-D-E:0,b.y+e.height+F+G,e.width)),b.watchFunctions.push(function(a,c,d){return b.y0){e=e[0];var f=b.pdf.internal.write,g=b.y;b.pdf.internal.write=function(){},c(e,b,d);var h=Math.ceil(b.y-g)+5;b.y=g,b.pdf.internal.write=f,b.pdf.margins_doc.bottom+=h;for(var i=function(a){var f=void 0!==a?a.pageNumber:1,g=b.y;b.y=b.pdf.internal.pageSize.height-b.pdf.margins_doc.bottom,b.pdf.margins_doc.bottom-=h;for(var i=e.getElementsByTagName("span"),j=0;j-1&&(i[j].innerHTML=f),(" "+i[j].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&(i[j].innerHTML="###jsPDFVarTotalPages###");c(e,b,d),b.pdf.margins_doc.bottom+=h,b.y=g},j=e.getElementsByTagName("span"),k=0;k-1&&b.pdf.internal.events.subscribe("htmlRenderingFinished",b.pdf.putTotalPages.bind(b.pdf,"###jsPDFVarTotalPages###"),!0);b.pdf.internal.events.subscribe("addPage",i,!1),i(),u.FOOTER=1}},s=function(a,b,d,e,f,g){if(!b)return!1;"string"==typeof b||b.parentNode||(b=""+b.innerHTML),"string"==typeof b&&(b=function(a){var b,c,d,e;return d="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),e="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",c=document.createElement("div"),c.style.cssText=e,c.innerHTML='