--- /dev/null
+vendor
+composer.phar
+db/poche.sqlite
+output
+phpdoc*
\ No newline at end of file
--- /dev/null
+language: php
+
+php:
+ - 5.4
+
+branches:
+ only:
+ - dev
+
+before_script:
+ - composer install
+
+notifications:
+ email:
+ - nicolas.loeuillet@gmail.com
\ No newline at end of file
poche is based on :
-* ReadItYourself http://www.memiks.fr/readityourself/
-* PHP Readability http://www.keyvan.net/2010/08/php-readability/
+* PHP Readability https://bitbucket.org/fivefilters/php-readability
* Encoding https://github.com/neitanod/forceutf8
* logo by Brightmix http://www.iconfinder.com/icondetails/43256/128/jeans_monotone_pocket_icon
* icons http://icomoon.io
* PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
+* Twig http://twig.sensiolabs.org
+* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
+* Pagination https://github.com/daveismyname/pagination
poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License
-Contributors :
-Nicolas Lœuillet aka nico_somb
-Tom.C. aka tmos
-PeaceCopathe
-Gregoire_M
\ No newline at end of file
+Contributors : https://github.com/inthepoche/poche/graphs/contributors
\ No newline at end of file
--- /dev/null
+# Installing poche
+
+Get the [latest dev version](https://github.com/inthepoche/poche/archive/dev.zip) of poche on github. Unzip it and upload it on your server.
+
+your datas can be stored on sqlite, postgres or mysql databases.
+
+Edit /inc/poche/config.inc.php :
+
+```php
+define ('STORAGE','sqlite'); # postgres, mysql, sqlite
+define ('STORAGE_SERVER', 'localhost'); # leave blank for sqlite
+define ('STORAGE_DB', 'poche'); # only for postgres & mysql
+define ('STORAGE_SQLITE', './db/poche.sqlite');
+define ('STORAGE_USER', 'user'); # leave blank for sqlite
+define ('STORAGE_PASSWORD', 'pass'); # leave blank for sqlite
+```
+
+poche must have write access on assets, cache and db directories.
+
+[PHP cURL](http://www.php.net/manual/en/book.curl.php) & [tidy_parse_string](http://www.php.net/manual/en/tidy.parsestring.php) are recommended.
+
+## twig
+poche now uses twig for templating. You have to install twig.
+
+Install composer in your project :
+```bash
+curl -s http://getcomposer.org/installer | php
+```
+Install via composer :
+```bash
+php composer.phar install
+```
+
+If you don't want to install twig by yourself, you can download [this file](http://static.inthepoche.com/files/poche-1.0-latest-with-twig.zip).
+
+## storage in sqlite
+You have to install [sqlite for php](http://www.php.net/manual/en/book.sqlite.php) on your server.
+
+Copy /install/poche.sqlite in /db
+
+## storage in mysql
+Execute /install/mysql.sql file in your database.
+
+## storage in postgres
+Execute /install/postgres.sql file in your database.
+
+## upgrading from poche <= 0.3
+With poche <= 0.3, all your datas were stored in a sqlite file. The structure of this file changed.
+
+You have to execute http://yourpoche/install/update_sqlite_from_0_to_1.php before using this new version.
+
+## installing poche
+you can go on your poche http://yourpoche. You have to fill the fields and that's all !
\ No newline at end of file
# poche
-Abandon Pocket, Instapaper and other Readability service : adopt poche. It is the same, but it is open source.
+Abandon Pocket, Instapaper and other Readability service : adopt poche. It is the same, but it is open source. Moreover, you can migrate from Pocket & Readability.
![poche](http://inthepoche.com/img/logo.png)
[![flattr](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/1265480/poche-a-read-it-later-open-source-system)
-## Usage
-You can easily add a "poched" page with the bookmarklet.
-
-poche save the entire content of a poched links : text and pictures are stored on your server.
-
-You can :
-* read a page in a comfortable reading view
-* archive a link
-* put a link in favorite
-* delete a link
-
-## Requirements & installation
-You have to install [sqlite for php](http://www.php.net/manual/en/book.sqlite.php) on your server.
-
-Get the [latest version](https://github.com/inthepoche/poche) of poche on github. Unzip it and upload it on your server. poche must have write access on assets, cache and db directories.
-
-That's all, **poche works** !
-
## Security
You **have** to protect your db/poche.sqlite file. Modify the virtual host of your website to add this condition :
```apache
}
```
-## Import from Pocket
+## Usage
+See the documentation on our website : [inthepoche.com](http://inthepoche.com).
-If you want to import your Pocket datas, [export them here](https://getpocket.com/export). Put the HTML file in your poche directory, execute import.php file locally by following instructions. Be careful, the script can take a very long time.
+## Travis
+[![Build Status](https://api.travis-ci.org/inthepoche/poche.png?branch=dev)](http://travis-ci.org/#!/inthepoche/poche)
## License
-Copyright © 2010-2013 Nicolas Lœuillet <nicolas@loeuillet.org>
+Copyright © 2010-2013 Nicolas Lœuillet <nicolas.loeuillet@gmail.com>
This work is free. You can redistribute it and/or modify it under the
terms of the Do What The Fuck You Want To Public License, Version 2,
-as published by Sam Hocevar. See the COPYING file for more details.
+as published by Sam Hocevar. See the COPYING file for more details.
\ No newline at end of file
--- /dev/null
+# TODO
+
+pouvoir annuler la suppression
+conventions codage ? phing ? vérifier error_log qui trainent
+phpDocumentor
+minifier css
+revoir tous les css
+barre fixe d'admin sur la page d'un billet ?
+revoir export (export vers pocket &cie ? )
+raccourcis clavier
+date d'ajout d'un lien
\ No newline at end of file
--- /dev/null
+{
+ "require": {
+ "twig/twig": "1.*",
+ "twig/extensions": "1.0.*",
+ "umpirsky/twig-gettext-extractor": "1.1.*"
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
+ ],
+ "hash": "1c8badb14d91f4f3ef1cfae23252a2c4",
+ "packages": [
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/EventDispatcher",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/EventDispatcher.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/dependency-injection": "~2.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-05-13 14:36:40"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/Filesystem",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Filesystem.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Filesystem\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Filesystem Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-06-04 15:02:05"
+ },
+ {
+ "name": "symfony/form",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/Form",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Form.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Form/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/intl": "~2.3",
+ "symfony/options-resolver": "~2.1",
+ "symfony/property-access": "~2.2"
+ },
+ "require-dev": {
+ "symfony/http-foundation": "~2.2",
+ "symfony/validator": "~2.2"
+ },
+ "suggest": {
+ "symfony/http-foundation": "",
+ "symfony/validator": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Form\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Form Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-07-01 12:24:43"
+ },
+ {
+ "name": "symfony/icu",
+ "version": "v1.0.0",
+ "target-dir": "Symfony/Component/Icu",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Icu.git",
+ "reference": "v1.0.0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Icu/zipball/v1.0.0",
+ "reference": "v1.0.0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/intl": ">=2.3,<3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Icu\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Contains an excerpt of the ICU data and classes to load it.",
+ "homepage": "http://symfony.com",
+ "keywords": [
+ "icu",
+ "intl"
+ ],
+ "time": "2013-06-03 18:32:07"
+ },
+ {
+ "name": "symfony/intl",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/Intl",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Intl.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/icu": "~1.0-RC"
+ },
+ "require-dev": {
+ "symfony/filesystem": ">=2.1"
+ },
+ "suggest": {
+ "ext-intl": "to use the component with locales other than \"en\""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Intl\\": ""
+ },
+ "classmap": [
+ "Symfony/Component/Intl/Resources/stubs"
+ ],
+ "files": [
+ "Symfony/Component/Intl/Resources/stubs/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ },
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch",
+ "homepage": "http://wiedler.ch/igor/"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ },
+ {
+ "name": "Eriksen Costa",
+ "email": "eriksen.costa@infranology.com.br"
+ }
+ ],
+ "description": "A PHP replacement layer for the C intl extension that includes additional data from the ICU library.",
+ "homepage": "http://symfony.com",
+ "keywords": [
+ "i18n",
+ "icu",
+ "internationalization",
+ "intl",
+ "l10n",
+ "localization"
+ ],
+ "time": "2013-07-08 13:00:35"
+ },
+ {
+ "name": "symfony/options-resolver",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/OptionsResolver",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/OptionsResolver.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony OptionsResolver Component",
+ "homepage": "http://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "time": "2013-04-11 06:50:46"
+ },
+ {
+ "name": "symfony/property-access",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/PropertyAccess",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/PropertyAccess.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\PropertyAccess\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony PropertyAccess Component",
+ "homepage": "http://symfony.com",
+ "keywords": [
+ "access",
+ "array",
+ "extraction",
+ "index",
+ "injection",
+ "object",
+ "property",
+ "property path",
+ "reflection"
+ ],
+ "time": "2013-07-01 12:24:43"
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/Routing",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Routing.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "doctrine/common": "~2.2",
+ "psr/log": "~1.0",
+ "symfony/config": "~2.2",
+ "symfony/yaml": "~2.0"
+ },
+ "suggest": {
+ "doctrine/common": "",
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Routing\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Routing Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-06-23 08:16:02"
+ },
+ {
+ "name": "symfony/translation",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Component/Translation",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Translation.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/config": "~2.0",
+ "symfony/yaml": "~2.2"
+ },
+ "suggest": {
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Translation\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Translation Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-05-13 14:36:40"
+ },
+ {
+ "name": "symfony/twig-bridge",
+ "version": "v2.3.2",
+ "target-dir": "Symfony/Bridge/Twig",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/TwigBridge.git",
+ "reference": "v2.3.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/TwigBridge/zipball/v2.3.2",
+ "reference": "v2.3.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "twig/twig": "~1.11"
+ },
+ "require-dev": {
+ "symfony/form": "2.2.*",
+ "symfony/http-kernel": "~2.2",
+ "symfony/routing": "~2.2",
+ "symfony/security": "~2.0",
+ "symfony/templating": "~2.1",
+ "symfony/translation": "~2.2",
+ "symfony/yaml": "~2.0"
+ },
+ "suggest": {
+ "symfony/form": "",
+ "symfony/http-kernel": "",
+ "symfony/routing": "",
+ "symfony/security": "",
+ "symfony/templating": "",
+ "symfony/translation": "",
+ "symfony/yaml": ""
+ },
+ "type": "symfony-bridge",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Bridge\\Twig\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Twig Bridge",
+ "homepage": "http://symfony.com",
+ "time": "2013-05-16 10:19:58"
+ },
+ {
+ "name": "twig/extensions",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fabpot/Twig-extensions.git",
+ "reference": "v1.0.0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fabpot/Twig-extensions/zipball/v1.0.0",
+ "reference": "v1.0.0",
+ "shasum": ""
+ },
+ "require": {
+ "twig/twig": "1.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_Extensions_": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Common additional features for Twig that do not directly belong in core",
+ "homepage": "https://github.com/fabpot/Twig-extensions",
+ "keywords": [
+ "debug",
+ "i18n",
+ "text"
+ ],
+ "time": "2013-02-28 14:21:30"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v1.13.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fabpot/Twig.git",
+ "reference": "v1.13.2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.13.2",
+ "reference": "v1.13.2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.13-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Twig_": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "http://twig.sensiolabs.org",
+ "keywords": [
+ "templating"
+ ],
+ "time": "2013-08-03 15:35:31"
+ },
+ {
+ "name": "umpirsky/twig-gettext-extractor",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/umpirsky/Twig-Gettext-Extractor.git",
+ "reference": "1.1.3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/umpirsky/Twig-Gettext-Extractor/zipball/1.1.3",
+ "reference": "1.1.3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/filesystem": ">=2.0,<3.0",
+ "symfony/form": ">=2.0,<3.0",
+ "symfony/routing": ">=2.0,<3.0",
+ "symfony/translation": ">=2.0,<3.0",
+ "symfony/twig-bridge": ">=2.0,<3.0",
+ "twig/extensions": "1.0.*",
+ "twig/twig": ">=1.2.0,<2.0-dev"
+ },
+ "require-dev": {
+ "symfony/config": "2.1.*"
+ },
+ "bin": [
+ "twig-gettext-extractor"
+ ],
+ "type": "application",
+ "autoload": {
+ "psr-0": {
+ "Twig\\Gettext": "."
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Саша Стаменковић",
+ "email": "umpirsky@gmail.com",
+ "homepage": "http://umpirsky.com"
+ }
+ ],
+ "description": "The Twig Gettext Extractor is Poedit friendly tool which extracts translations from twig templates.",
+ "time": "2013-02-14 16:41:48"
+ }
+ ],
+ "packages-dev": [
+
+ ],
+ "aliases": [
+
+ ],
+ "minimum-stability": "stable",
+ "stability-flags": [
+
+ ],
+ "platform": [
+
+ ],
+ "platform-dev": [
+
+ ]
+}
+++ /dev/null
-/*** GENERAL ***/
-body {
- color: #fff;
- background-color: #0d0d0d;
-}
-
-a, a:hover, a:visited {
- color: #fff;
-}
-
-#main ul#links li a.current {
- background-color: #000;
- color: #fff;
-}
-
-#links a:hover, .backhome a:hover{
- background-color: #fff;
- color: #000;
-}
-
-input[type=submit].delete {
- background : url('../img/dark/remove.png') no-repeat center center;
- color : transparent;
-}
-
-#main .entrie {
- color: #fff;
- background-color: #000;
- border: 1px solid #fff;
-}
-
-#main .entrie h2 a:hover {
- color: #29B1E3;
-}
-
-a.fav span {
- background: url('../img/dark/star-on.png') no-repeat;
-}
-
-a.fav span:hover {
- background: url('../img/dark/star-off.png') no-repeat;
-}
-
-a.fav-off span {
- background: url('../img/dark/star-off.png') no-repeat;
-}
-
-a.fav-off span:hover {
- background: url('../img/dark/star-on.png') no-repeat;
-}
-
-a.archive span {
- background: url('../img/dark/checkmark-on.png') no-repeat;
-}
-
-a.archive span:hover {
- background: url('../img/dark/checkmark-off.png') no-repeat;
-}
-
-a.archive-off span {
- background: url('../img/dark/checkmark-off.png') no-repeat;
-}
-
-a.archive-off span:hover {
- background: url('../img/dark/checkmark-on.png') no-repeat;
-}
-
-/*** ***/
-/*** ARTICLE PAGE ***/
-
-body.article {
- color: #fff;
- background-color: #0d0d0d;
-}
-
-#article header {
- border-bottom: 1px solid #222222;
-}
-
-#article article {
- border-bottom: 1px solid #222222;
-}
-
-.vieworiginal a {
- color: #888888;
-}
-
-.entrie {
- background-color: #fff;
-}
+++ /dev/null
-/*** GENERAL ***/
-body {
- color: #222222;
- background-color: #F1F1F1;
-}
-
-a, a:hover, a:visited {
- color: #000;
-}
-
-.bouton {
- background-color: #000;
- color: #fff;
- border: none;
-}
-.bouton:hover {
- background-color: #222222;
- color: #F1F1F1;
-}
-
-#main ul#links li a.current {
- background-color: #000;
- color: #fff;
-}
-
-#links a:hover, .backhome a:hover{
- background-color: #040707;
- color: #F1F1F1;
-}
-
-input[type=submit].delete {
- background : url('../img/light/remove.png') no-repeat center center;
- color : transparent;
-}
-
-#main .entrie {
- color: #2e2e2e;
- background-color: #ffffff;
- border: 1px solid #000;
-}
-
-#main .entrie h2 a:hover {
- color: #F5BE00;
-}
-
-a.fav span {
- background: url('../img/light/star-on.png') no-repeat;
-}
-
-a.fav span:hover {
- background: url('../img/light/star-off.png') no-repeat;
-}
-
-a.fav-off span {
- background: url('../img/light/star-off.png') no-repeat;
-}
-
-a.fav-off span:hover {
- background: url('../img/light/star-on.png') no-repeat;
-}
-
-a.archive span {
- background: url('../img/light/checkmark-on.png') no-repeat;
-}
-
-a.archive span:hover {
- background: url('../img/light/checkmark-off.png') no-repeat;
-}
-
-a.archive-off span {
- background: url('../img/light/checkmark-off.png') no-repeat;
-}
-
-a.archive-off span:hover {
- background: url('../img/light/checkmark-on.png') no-repeat;
-}
-
-/*** ***/
-/*** ARTICLE PAGE ***/
-
-body.article {
- color: #222222;
- background-color: #F1F1F1;
-}
-
-#article header {
- border-bottom: 1px solid #222222;
-}
-
-#article article {
- border-bottom: 1px solid #222222;
-}
-
-.vieworiginal a {
- color: #888888;
-}
-
-.entrie {
- background-color: #fff;
-}
+++ /dev/null
-/*** GENERAL ***/
-body {
- font: 20px/1.3em Palatino,Georgia,serif;
- margin: 10px;
-}
-
-header {
- text-align: center;
-}
-
-.bouton {
- border-radius: 2px;
-}
-
-#main ul#links {
- padding: 0;
- list-style-type: none;
- text-align: center;
-}
-
-#main ul#links li {
- display: inline;
-}
-
-#main ul#links li a.current {
- -webkit-border-radius: 2px;
- border-radius: 2px;
-}
-
-#main ul#sort {
- padding: 0;
- list-style-type: none;
- text-align: center;
-}
-
-#main ul#sort li {
- display: inline;
- font-size: 0.9em;
-}
-
-#main ul#sort img:hover {
- cursor: pointer;
-}
-
-#main, #article {
- margin: 0 auto;
-}
-
-#links a, .backhome a{
- text-decoration: none;
- padding: 5px 10px;
-}
-#links a:hover, .backhome a:hover{
- -webkit-border-radius: 2px;
- border-radius: 2px;
-}
-
-footer {
- text-align: right;
-}
-
-/*** ***/
-/*** LINKS DISPLAY ***/
-
-#main a.tool {
- text-decoration: none;
- cursor: pointer;
-}
-
-input[type=submit].delete {
- width : 16px;
- height :16px;
- border : none;
- cursor: pointer;
- font-size : 0;
-}
-
-#main #content {
- margin-top: 20px;
-}
-
-#main .entrie {
- padding: 15px;
- min-height: 8em;
- border: 1px solid;
-}
-
-#main .entrie h2 a {
- text-decoration: none;
-}
-
-.tools {
- text-align: right;
-}
-
-.tools ul {
- padding: 0; margin: 0;
- list-style-type: none;
-}
-
-.tools ul li {
- line-height: 20px;
-}
-
-.tools a.tool {
- cursor: pointer;
-}
-
-#article .tools {
- position: relative;
- display: inline;
- top: 0px;
- right: 0px;
- width: 100%;
- text-align: left;
-}
-
-#article .tools ul li{
- display: inline;
-}
-
-#main .entrie .tools a.tool span, #article .tools a.tool span {
- display: inline-block;
- width: 16px;
- height: 16px;
-}
-
-
-/*** ***/
-/*** ARTICLE PAGE ***/
-
-body.article {
- font: 20px/1.3em Palatino,Georgia,serif;
-}
-
-#article header {
- text-align: left;
-}
-
-#article header a {
- text-decoration: none;
-}
-
-.vieworiginal a {
- text-decoration: none;
-}
-
-.backhome {
- display: inline;
-}
-
-/*** ***/
-
-#main
-{
- max-width: 60em; /* 960 px */
- margin: 0 auto;
-}
-#content
-{
- width: 103.125%; /* 990px */
- overflow: hidden;
- margin-left: -1.562%; /* 15px */
- margin-bottom: -1.875em; /* 30px */
-}
-
-.entrie
-{
- width: 30.303%; /* 300px */
- background-color: #fff;
- float: left;
- margin: 0 1.515% 1.875em; /* 15px 30px */
-}
-
-@media only screen and ( max-width: 40em ) /* 640px */
-{
- .entrie
- {
- width: 46.876%; /* 305px */
- margin-bottom: 0.938em; /* 15px */
- }
-}
-
-@media only screen and ( max-width: 20em ) /* 320px */
-{
- #content
- {
- width: 100%;
- margin-left: 0;
- }
-
- .entrie
- {
- width: 100%;
- margin-left: 0;
- margin-right: 0;
- }
-}
-
-/*** ***/
-/*** MESSAGES ***/
-
-.messages { width: 100%; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; }
-.messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; }
-/*.messages:hover a.closeMessage { visibility:visible; }*/
-.messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; }
-.messages.error { border: 1px solid #C42608; color: #c00 !important; background: #FFF0EF; }
-.messages.error p { background: url(../img/messages/cross.png ) no-repeat 0px 50%; color:#c00 !important; }
-.messages.success {background: #E0FBCC; border: 1px solid #6DC70C; }
-.messages.success p { background: url(../img/messages/tick.png) no-repeat 0px 50%; color: #2B6301 !important; }
-.messages.warning { background: #FFFCD3; border: 1px solid #EBCD41; color: #000; }
-.messages.warning p { background: url(../img/messages/warning.png ) no-repeat 0px 50%; color: #5F4E01; }
-.messages.information, .messages.info { background: #DFEBFB; border: 1px solid #82AEE7; }
-.messages.information p, .messages.info p { background: url(../img/messages/help.png ) no-repeat 0px 50%; color: #064393; }
-.messages.information a { text-decoration: underline; }
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <support@inthepoche.com>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-set_time_limit(0);
-
-include dirname(__FILE__).'/inc/config.php';
-include dirname(__FILE__).'/inc/simple_html_dom.php';
-
-if (!isset($_GET['start'])) {
- echo 'Please execute the import script locally, it can take a very long time. <br /><a href="import.php?start">Bye bye Pocket, let\'s go !</a>';
-}
-else {
- $html = new simple_html_dom();
- $html->load_file('ril_export.html');
-
- $read = 0;
- $errors = array();
- foreach($html->find('ul') as $ul)
- {
- foreach($ul->find('li') as $li)
- {
- $a = $li->find('a');
- $url = $a[0]->href;
-
-
- action_to_do('add', $url);
- if ($read == '1') {
- $last_id = $db->getHandle()->lastInsertId();
- $sql_update = "UPDATE entries SET is_read=~is_read WHERE id=?";
- $params_update = array($last_id);
- $query_update = $db->getHandle()->prepare($sql_update);
- $query_update->execute($params_update);
- }
- }
- # Pocket génère un fichier HTML avec deux <ul>
- # Le premier concerne les éléments non lus
- # Le second concerne les éléments archivés
- $read = 1;
- }
-
- echo 'Import from Pocket completed. <a href="index.php">Welcome to #poche !</a>';
- logm('import from pocket completed');
-}
\ No newline at end of file
*
* This class extends PHP's DOMElement to allow
* users to get and set the innerHTML property of
-* HTML elements in the same way it's done in
+* HTML elements in the same way it's done in
* JavaScript.
*
* Example usage:
* $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
* $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');
* $elem = $doc->getElementsByTagName('div')->item(0);
-*
+*
* // print innerHTML
* echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>'
* echo "\n\n";
-*
+*
* // set innerHTML
* $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>';
* echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>'
* echo "\n\n";
-*
+*
* // print document (with our changes)
* echo $doc->saveXML();
* @endcode
$value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8');
// Using <htmlfragment> will generate a warning, but so will bad HTML
// (and by this point, bad HTML is what we've got).
- // We use it (and suppress the warning) because an HTML fragment will
+ // We use it (and suppress the warning) because an HTML fragment will
// be wrapped around <html><body> tags which we don't really want to keep.
// Note: despite the warning, if loadHTML succeeds it will return true.
$result = @$f->loadHTML('<htmlfragment>'.$value.'</htmlfragment>');
* @code
* $string = $div->innerHTML;
* @endcode
- */
+ */
public function __get($name)
{
if ($name == 'innerHTML') {
<?php
-/**
+/**
* Arc90's Readability ported to PHP for FiveFilters.org
* Based on readability.js version 1.7.1 (without multi-page support)
* Updated to allow HTML5 parsing with html5lib
* License: Apache License, Version 2.0
* Requires: PHP5
* Date: 2012-09-19
-*
+*
* Differences between the PHP port and the original
* ------------------------------------------------------
-* Arc90's Readability is designed to run in the browser. It works on the DOM
-* tree (the parsed HTML) after the page's CSS styles have been applied and
-* Javascript code executed. This PHP port does not run inside a browser.
-* We use PHP's ability to parse HTML to build our DOM tree, but we cannot
-* rely on CSS or Javascript support. As such, the results will not always
-* match Arc90's Readability. (For example, if a web page contains CSS style
-* rules or Javascript code which hide certain HTML elements from display,
-* Arc90's Readability will dismiss those from consideration but our PHP port,
+* Arc90's Readability is designed to run in the browser. It works on the DOM
+* tree (the parsed HTML) after the page's CSS styles have been applied and
+* Javascript code executed. This PHP port does not run inside a browser.
+* We use PHP's ability to parse HTML to build our DOM tree, but we cannot
+* rely on CSS or Javascript support. As such, the results will not always
+* match Arc90's Readability. (For example, if a web page contains CSS style
+* rules or Javascript code which hide certain HTML elements from display,
+* Arc90's Readability will dismiss those from consideration but our PHP port,
* unable to understand CSS or Javascript, will not know any better.)
-*
-* Another significant difference is that the aim of Arc90's Readability is
-* to re-present the main content block of a given web page so users can
-* read it more easily in their browsers. Correct identification, clean up,
-* and separation of the content block is only a part of this process.
-* This PHP port is only concerned with this part, it does not include code
-* that relates to presentation in the browser - Arc90 already do
-* that extremely well, and for PDF output there's FiveFilters.org's
+*
+* Another significant difference is that the aim of Arc90's Readability is
+* to re-present the main content block of a given web page so users can
+* read it more easily in their browsers. Correct identification, clean up,
+* and separation of the content block is only a part of this process.
+* This PHP port is only concerned with this part, it does not include code
+* that relates to presentation in the browser - Arc90 already do
+* that extremely well, and for PDF output there's FiveFilters.org's
* PDF Newspaper: http://fivefilters.org/pdf-newspaper/.
-*
-* Finally, this class contains methods that might be useful for developers
-* working on HTML document fragments. So without deviating too much from
-* the original code (which I don't want to do because it makes debugging
-* and updating more difficult), I've tried to make it a little more
-* developer friendly. You should be able to use the methods here on
-* existing DOMElement objects without passing an entire HTML document to
+*
+* Finally, this class contains methods that might be useful for developers
+* working on HTML document fragments. So without deviating too much from
+* the original code (which I don't want to do because it makes debugging
+* and updating more difficult), I've tried to make it a little more
+* developer friendly. You should be able to use the methods here on
+* existing DOMElement objects without passing an entire HTML document to
* be parsed.
*/
require_once(dirname(__FILE__).'/JSLikeHTMLElement.php');
// Alternative usage (for testing only!)
-// uncomment the lines below and call Readability.php in your browser
+// uncomment the lines below and call Readability.php in your browser
// passing it the URL of the page you'd like content from, e.g.:
// Readability.php?url=http://medialens.org/alerts/09/090615_the_guardian_climate.php
public $url = null; // optional - URL where HTML was retrieved
public $debug = false;
public $lightClean = true; // preserves more content (experimental) added 2012-09-19
- protected $body = null; //
+ protected $body = null; //
protected $bodyCache = null; // Cache the body HTML in case we need to re-use it later
protected $flags = 7; // 1 | 2 | 4; // Start with all flags set.
protected $success = false; // indicates whether we were able to extract or not
-
+
/**
* All of the regular expressions in use within readability.
* Defined up here so we don't instantiate them repeatedly in loops.
'killBreaks' => '/(<br\s*\/?>(\s| ?)*){1,}/',
'video' => '!//(player\.|www\.)?(youtube|vimeo|viddler)\.com!i',
'skipFootnoteLink' => '/^\s*(\[?[a-z0-9]{1,2}\]?|^|edit|citation needed)\s*$/i'
- );
-
+ );
+
/* constants */
const FLAG_STRIP_UNLIKELYS = 1;
const FLAG_WEIGHT_CLASSES = 2;
const FLAG_CLEAN_CONDITIONALLY = 4;
-
+
/**
* Create instance of Readability
* @param string UTF-8 encoded string
* @param string (optional) URL associated with HTML (used for footnotes)
* @param string which parser to use for turning raw HTML into a DOMDocument (either 'libxml' or 'html5lib')
- */
+ */
function __construct($html, $url=null, $parser='libxml')
{
$this->url = $url;
public function getTitle() {
return $this->articleTitle;
}
-
+
/**
* Get article content element
* @return DOMElement
*/
public function getContent() {
return $this->articleContent;
- }
-
+ }
+
/**
* Runs readability.
- *
+ *
* Workflow:
* 1. Prep the document by removing script tags, css, etc.
* 2. Build readability's DOM tree.
if (!isset($this->dom->documentElement)) return false;
$this->removeScripts($this->dom);
//die($this->getInnerHTML($this->dom->documentElement));
-
+
// Assume successful outcome
$this->success = true;
}
$this->prepDocument();
-
+
//die($this->dom->documentElement->parentNode->nodeType);
//$this->setInnerHTML($this->dom->documentElement, $this->getInnerHTML($this->dom->documentElement));
//die($this->getInnerHTML($this->dom->documentElement));
$this->success = false;
$articleContent = $this->dom->createElement('div');
$articleContent->setAttribute('id', 'readability-content');
- $articleContent->innerHTML = '<p>Sorry, Readability was unable to parse this page for content.</p>';
+ $articleContent->innerHTML = '<p>Sorry, Readability was unable to parse this page for content.</p>';
}
-
+
$overlay->setAttribute('id', 'readOverlay');
$innerDiv->setAttribute('id', 'readInner');
$innerDiv->appendChild($articleTitle);
$innerDiv->appendChild($articleContent);
$overlay->appendChild($innerDiv);
-
+
/* Clear the old HTML, insert the new content. */
$this->body->innerHTML = '';
$this->body->appendChild($overlay);
$this->body->removeAttribute('style');
$this->postProcessContent($articleContent);
-
+
// Set title and content instance variables
$this->articleTitle = $articleTitle;
$this->articleContent = $articleContent;
-
+
return $this->success;
}
-
+
/**
* Debug
*/
protected function dbg($msg) {
if ($this->debug) echo '* ',$msg, "\n";
}
-
+
/**
* Run any post-process modifications to article content as necessary.
*
* @return void
*/
public function postProcessContent($articleContent) {
- if ($this->convertLinksToFootnotes && !preg_match('/wikipedia\.org/', @$this->url)) {
+ if ($this->convertLinksToFootnotes && !preg_match('/wikipedia\.org/', @$this->url)) {
$this->addFootnotes($articleContent);
}
}
-
+
/**
* Get the article title as an H1.
*
try {
$curTitle = $origTitle = $this->getInnerText($this->dom->getElementsByTagName('title')->item(0));
} catch(Exception $e) {}
-
+
if (preg_match('/ [\|\-] /', $curTitle))
{
$curTitle = preg_replace('/(.*)[\|\-] .*/i', '$1', $origTitle);
-
+
if (count(explode(' ', $curTitle)) < 3) {
$curTitle = preg_replace('/[^\|\-]*[\|\-](.*)/i', '$1', $origTitle);
}
if (count(explode(' ', $curTitle)) <= 4) {
$curTitle = $origTitle;
}
-
+
$articleTitle = $this->dom->createElement('h1');
$articleTitle->innerHTML = $curTitle;
-
+
return $articleTitle;
}
-
+
/**
* Prepare the HTML document for readability to scrape it.
* This includes things like stripping javascript, CSS, and handling terrible markup.
- *
+ *
* @return void
**/
protected function prepDocument() {
$footnotesWrapper = $this->dom->createElement('div');
$footnotesWrapper->setAttribute('id', 'readability-footnotes');
$footnotesWrapper->innerHTML = '<h3>References</h3>';
-
+
$articleFootnotes = $this->dom->createElement('ol');
$articleFootnotes->setAttribute('id', 'readability-footnotes-list');
$footnotesWrapper->appendChild($articleFootnotes);
-
+
$articleLinks = $articleContent->getElementsByTagName('a');
-
+
$linkCount = 0;
for ($i = 0; $i < $articleLinks->length; $i++)
{
if (!$linkDomain && isset($this->url)) $linkDomain = @parse_url($this->url, PHP_URL_HOST);
//linkDomain = footnoteLink.host ? footnoteLink.host : document.location.host,
$linkText = $this->getInnerText($articleLink);
-
+
if ((strpos($articleLink->getAttribute('class'), 'readability-DoNotFootnote') !== false) || preg_match($this->regexps['skipFootnoteLink'], $linkText)) {
continue;
}
-
+
$linkCount++;
/** Add a superscript reference after the article link */
$refLink->innerHTML = '<small><sup>[' . $linkCount . ']</sup></small>';
$refLink->setAttribute('class', 'readability-DoNotFootnote');
$refLink->setAttribute('style', 'color: inherit;');
-
+
//TODO: does this work or should we use DOMNode.isSameNode()?
if ($articleLink->parentNode->lastChild == $articleLink) {
$articleLink->parentNode->appendChild($refLink);
$footnoteLink->innerHTML = ($footnoteLink->getAttribute('title') != '' ? $footnoteLink->getAttribute('title') : $linkText);
$footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount);
-
+
$footnote->appendChild($footnoteLink);
if ($linkDomain) $footnote->innerHTML = $footnote->innerHTML . '<small> (' . $linkDomain . ')</small>';
-
+
$articleFootnotes->appendChild($footnote);
}
if ($linkCount > 0) {
- $articleContent->appendChild($footnotesWrapper);
+ $articleContent->appendChild($footnotesWrapper);
}
}
//}
}
}
-
+
/**
* Prepare the article node for display. Clean out any inline styles,
* iframes, forms, strip extraneous <p> tags, etc.
* as a header and not a subheader, so remove it since we already have a header.
***/
if (!$this->lightClean && ($articleContent->getElementsByTagName('h2')->length == 1)) {
- $this->clean($articleContent, 'h2');
+ $this->clean($articleContent, 'h2');
}
$this->clean($articleContent, 'iframe');
$embedCount = $articleParagraphs->item($i)->getElementsByTagName('embed')->length;
$objectCount = $articleParagraphs->item($i)->getElementsByTagName('object')->length;
$iframeCount = $articleParagraphs->item($i)->getElementsByTagName('iframe')->length;
-
+
if ($imgCount === 0 && $embedCount === 0 && $objectCount === 0 && $iframeCount === 0 && $this->getInnerText($articleParagraphs->item($i), false) == '')
{
$articleParagraphs->item($i)->parentNode->removeChild($articleParagraphs->item($i));
try {
$articleContent->innerHTML = preg_replace('/<br[^>]*>\s*<p/i', '<p', $articleContent->innerHTML);
- //articleContent.innerHTML = articleContent.innerHTML.replace(/<br[^>]*>\s*<p/gi, '<p');
+ //articleContent.innerHTML = articleContent.innerHTML.replace(/<br[^>]*>\s*<p/gi, '<p');
}
catch (Exception $e) {
$this->dbg("Cleaning innerHTML of breaks failed. This is an IE strict-block-elements bug. Ignoring.: " . $e);
}
}
-
+
/**
* Initialize a node with the readability object. Also checks the
* className/id for special names to add to its score.
protected function initializeNode($node) {
$readability = $this->dom->createAttribute('readability');
$readability->value = 0; // this is our contentScore
- $node->setAttributeNode($readability);
+ $node->setAttributeNode($readability);
switch (strtoupper($node->tagName)) { // unsure if strtoupper is needed, but using it just in case
case 'DIV':
case 'BLOCKQUOTE':
$readability->value += 3;
break;
-
+
case 'ADDRESS':
case 'OL':
case 'UL':
}
$readability->value += $this->getClassWeight($node);
}
-
+
/***
* grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is
* most likely to be the stuff a user wants to read. Then return it wrapped up in a div.
$node->parentNode->removeChild($node);
$nodeIndex--;
continue;
- }
+ }
}
if ($tagName == 'P' || $tagName == 'TD' || $tagName == 'PRE') {
}
}
}
-
+
/**
* Loop through all paragraphs, and assign a score to them based on how content-y they look.
* Then add their score to their parent node.
}
/* Initialize readability data for the parent. */
- if (!$parentNode->hasAttribute('readability'))
+ if (!$parentNode->hasAttribute('readability'))
{
$this->initializeNode($parentNode);
$candidates[] = $parentNode;
/* Add points for any commas within this paragraph */
$contentScore += count(explode(',', $innerText));
-
+
/* For every 100 characters in this paragraph, add another point. Up to 3 points. */
$contentScore += min(floor(strlen($innerText) / 100), 3);
-
+
/* Add the score to the parent. The grandparent gets half. */
$parentNode->getAttributeNode('readability')->value += $contentScore;
if ($grandParentNode) {
- $grandParentNode->getAttributeNode('readability')->value += $contentScore/2;
+ $grandParentNode->getAttributeNode('readability')->value += $contentScore/2;
}
}
{
$append = true;
}
-
+
if (strtoupper($siblingNode->nodeName) == 'P') {
$linkDensity = $this->getLinkDensity($siblingNode);
$nodeContent = $this->getInnerText($siblingNode);
$nodeLength = strlen($nodeContent);
-
+
if ($nodeLength > 80 && $linkDensity < 0.25)
{
$append = true;
$sibNodeName = strtoupper($siblingNode->nodeName);
if ($sibNodeName != 'DIV' && $sibNodeName != 'P') {
/* We have a node that isn't a common block level element, like a form or td tag. Turn it into a div so it doesn't get filtered out later by accident. */
-
+
$this->dbg('Altering siblingNode of ' . $sibNodeName . ' to div.');
$nodeToAppend = $this->dom->createElement('div');
try {
$s--;
$sl--;
}
-
+
/* To ensure a node does not interfere with readability styles, remove its classnames */
$nodeToAppend->removeAttribute('class');
// in the meantime, we check and create an empty element if it's not there.
if (!isset($this->body->childNodes)) $this->body = $this->dom->createElement('body');
$this->body->innerHTML = $this->bodyCache;
-
+
if ($this->flagIsActive(self::FLAG_STRIP_UNLIKELYS)) {
$this->removeFlag(self::FLAG_STRIP_UNLIKELYS);
return $this->grabArticle($this->body);
}
else if ($this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) {
$this->removeFlag(self::FLAG_WEIGHT_CLASSES);
- return $this->grabArticle($this->body);
+ return $this->grabArticle($this->body);
}
else if ($this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) {
$this->removeFlag(self::FLAG_CLEAN_CONDITIONALLY);
}
return $articleContent;
}
-
+
/**
* Remove script tags from document
*
$scripts->item($i)->parentNode->removeChild($scripts->item($i));
}
}
-
+
/**
* Get the inner text of a node.
* This also strips out any excess whitespace to be found.
$elem->removeAttribute('style');
}
}
-
+
/**
* Get the density of links as a percentage of the content
* This is the amount of text that is inside a link divided by the total text in the node.
- *
+ *
* @param DOMElement $e
* @return number (float)
*/
return 0;
}
}
-
+
/**
- * Get an elements class/id weight. Uses regular expressions to tell if this
+ * Get an elements class/id weight. Uses regular expressions to tell if this
* element looks good or bad.
*
* @param DOMElement $e
public function clean($e, $tag) {
$targetList = $e->getElementsByTagName($tag);
$isEmbed = ($tag == 'iframe' || $tag == 'object' || $tag == 'embed');
-
+
for ($y=$targetList->length-1; $y >= 0; $y--) {
/* Allow youtube and vimeo videos through as people usually want to see those. */
if ($isEmbed) {
for ($i=0, $il=$targetList->item($y)->attributes->length; $i < $il; $i++) {
$attributeValues .= $targetList->item($y)->attributes->item($i)->value . '|'; // DOMAttr? (TODO: test)
}
-
+
/* First, check the elements attributes to see if any of them contain youtube or vimeo */
if (preg_match($this->regexps['video'], $attributeValues)) {
continue;
$targetList->item($y)->parentNode->removeChild($targetList->item($y));
}
}
-
+
/**
* Clean an element of all tags of type "tag" if they look fishy.
- * "Fishy" is an algorithm based on content length, classnames,
+ * "Fishy" is an algorithm based on content length, classnames,
* link density, number of images & embeds, etc.
*
* @param DOMElement $e
for ($i=$curTagsLength-1; $i >= 0; $i--) {
$weight = $this->getClassWeight($tagsList->item($i));
$contentScore = ($tagsList->item($i)->hasAttribute('readability')) ? (int)$tagsList->item($i)->getAttribute('readability') : 0;
-
+
$this->dbg('Cleaning Conditionally ' . $tagsList->item($i)->tagName . ' (' . $tagsList->item($i)->getAttribute('class') . ':' . $tagsList->item($i)->getAttribute('id') . ')' . (($tagsList->item($i)->hasAttribute('readability')) ? (' with score ' . $tagsList->item($i)->getAttribute('readability')) : ''));
if ($weight + $contentScore < 0) {
$embeds = $tagsList->item($i)->getElementsByTagName('embed');
for ($ei=0, $il=$embeds->length; $ei < $il; $ei++) {
if (preg_match($this->regexps['video'], $embeds->item($ei)->getAttribute('src'))) {
- $embedCount++;
+ $embedCount++;
}
}
$embeds = $tagsList->item($i)->getElementsByTagName('iframe');
for ($ei=0, $il=$embeds->length; $ei < $il; $ei++) {
if (preg_match($this->regexps['video'], $embeds->item($ei)->getAttribute('src'))) {
- $embedCount++;
+ $embedCount++;
}
}
$toRemove = true;
} else if ( $input > floor($p/3) ) {
$this->dbg(' too many <input> elements');
- $toRemove = true;
+ $toRemove = true;
} else if ($contentLength < 25 && ($embedCount === 0 && ($img === 0 || $img > 2))) {
$this->dbg(' content length less than 25 chars, 0 embeds and either 0 images or more than 2 images');
$toRemove = true;
$toRemove = true;
} else if ( $input > floor($p/3) ) {
$this->dbg(' too many <input> elements');
- $toRemove = true;
+ $toRemove = true;
} else if ($contentLength < 25 && ($img === 0 || $img > 2) ) {
$this->dbg(' content length less than 25 chars and 0 images, or more than 2 images');
$toRemove = true;
public function flagIsActive($flag) {
return ($this->flags & $flag) > 0;
}
-
+
public function addFlag($flag) {
$this->flags = $this->flags | $flag;
}
-
+
public function removeFlag($flag) {
$this->flags = $this->flags & ~$flag;
}
// Force logout
public static function logout()
{
- unset($_SESSION['uid'],$_SESSION['info'],$_SESSION['expires_on'],$_SESSION['tokens'], $_SESSION['login'], $_SESSION['pass']);
+ unset($_SESSION['uid'],$_SESSION['info'],$_SESSION['expires_on'],$_SESSION['tokens'], $_SESSION['login'], $_SESSION['pass'], $_SESSION['poche_user']);
}
// Make sure user is logged in.
-<?php
-//--------------------------------------------------------------------------------------------------
-// Session-Based Flash Messages v1.0
-// Copyright 2012 Mike Everhart (http://mikeeverhart.net)
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//------------------------------------------------------------------------------
-// Description:
-//------------------------------------------------------------------------------
-//
-// Stores messages in Session data to be easily retrieved later on.
-// This class includes four different types of messages:
-// - Success
-// - Error
-// - Warning
-// - Information
-//
-// See README for basic usage instructions, or see samples/index.php for more advanced samples
-//
-//--------------------------------------------------------------------------------------------------
-// Changelog
-//--------------------------------------------------------------------------------------------------
-//
-// 2011-05-15 - v1.0 - Initial Version
-//
-//--------------------------------------------------------------------------------------------------
-
-class Messages {
-
- //-----------------------------------------------------------------------------------------------
- // Class Variables
- //-----------------------------------------------------------------------------------------------
- var $msgId;
- var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );
- var $msgClass = 'messages';
- var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'></a>\n%s</div>\n";
- var $msgBefore = '<p>';
- var $msgAfter = "</p>\n";
-
-
- /**
- * Constructor
- * @author Mike Everhart
- */
- public function __construct() {
-
- // Generate a unique ID for this user and session
- $this->msgId = md5(uniqid());
-
- // Create the session array if it doesnt already exist
- if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
-
- }
-
- /**
- * Add a message to the queue
- *
- * @author Mike Everhart
- *
- * @param string $type The type of message to add
- * @param string $message The message
- * @param string $redirect_to (optional) If set, the user will be redirected to this URL
- * @return bool
- *
- */
- public function add($type, $message, $redirect_to=null) {
-
- if( !isset($_SESSION['flash_messages']) ) return false;
-
- if( !isset($type) || !isset($message[0]) ) return false;
-
- // Replace any shorthand codes with their full version
- if( strlen(trim($type)) == 1 ) {
- $type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );
-
- // Backwards compatibility...
- } elseif( $type == 'information' ) {
- $type = 'info';
- }
-
- // Make sure it's a valid message type
- if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
-
- // If the session array doesn't exist, create it
- if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
-
- $_SESSION['flash_messages'][$type][] = $message;
-
- if( !is_null($redirect_to) ) {
- header("Location: $redirect_to");
- exit();
- }
-
- return true;
-
- }
-
- //-----------------------------------------------------------------------------------------------
- // display()
- // print queued messages to the screen
- //-----------------------------------------------------------------------------------------------
- /**
- * Display the queued messages
- *
- * @author Mike Everhart
- *
- * @param string $type Which messages to display
- * @param bool $print True = print the messages on the screen
- * @return mixed
- *
- */
- public function display($type='all', $print=true) {
- $messages = '';
- $data = '';
-
- if( !isset($_SESSION['flash_messages']) ) return false;
-
- if( $type == 'g' || $type == 'growl' ) {
- $this->displayGrowlMessages();
- return true;
- }
-
- // Print a certain type of message?
- if( in_array($type, $this->msgTypes) ) {
- foreach( $_SESSION['flash_messages'][$type] as $msg ) {
- $messages .= $this->msgBefore . $msg . $this->msgAfter;
- }
-
- $data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
-
- // Clear the viewed messages
- $this->clear($type);
-
- // Print ALL queued messages
- } elseif( $type == 'all' ) {
- foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
- $messages = '';
- foreach( $msgArray as $msg ) {
- $messages .= $this->msgBefore . $msg . $this->msgAfter;
- }
- $data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
- }
-
- // Clear ALL of the messages
- $this->clear();
-
- // Invalid Message Type?
- } else {
- return false;
- }
-
- // Print everything to the screen or return the data
- if( $print ) {
- echo $data;
- } else {
- return $data;
- }
- }
-
-
- /**
- * Check to see if there are any queued error messages
- *
- * @author Mike Everhart
- *
- * @return bool true = There ARE error messages
- * false = There are NOT any error messages
- *
- */
- public function hasErrors() {
- return empty($_SESSION['flash_messages']['error']) ? false : true;
- }
-
- /**
- * Check to see if there are any ($type) messages queued
- *
- * @author Mike Everhart
- *
- * @param string $type The type of messages to check for
- * @return bool
- *
- */
- public function hasMessages($type=null) {
- if( !is_null($type) ) {
- if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type];
- } else {
- foreach( $this->msgTypes as $type ) {
- if( !empty($_SESSION['flash_messages']) ) return true;
- }
- }
- return false;
- }
-
- /**
- * Clear messages from the session data
- *
- * @author Mike Everhart
- *
- * @param string $type The type of messages to clear
- * @return bool
- *
- */
- public function clear($type='all') {
- if( $type == 'all' ) {
- unset($_SESSION['flash_messages']);
- } else {
- unset($_SESSION['flash_messages'][$type]);
- }
- return true;
- }
-
- public function __toString() { return $this->hasMessages(); }
-
- public function __destruct() {
- //$this->clear();
- }
-
-
-} // end class
+<?php\r
+//--------------------------------------------------------------------------------------------------\r
+// Session-Based Flash Messages v1.0\r
+// Copyright 2012 Mike Everhart (http://mikeeverhart.net)\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+// http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+// \r
+//------------------------------------------------------------------------------\r
+// Description:\r
+//------------------------------------------------------------------------------\r
+//\r
+// Stores messages in Session data to be easily retrieved later on.\r
+// This class includes four different types of messages:\r
+// - Success\r
+// - Error\r
+// - Warning\r
+// - Information\r
+// \r
+// See README for basic usage instructions, or see samples/index.php for more advanced samples\r
+//\r
+//--------------------------------------------------------------------------------------------------\r
+// Changelog\r
+//--------------------------------------------------------------------------------------------------\r
+// \r
+// 2011-05-15 - v1.0 - Initial Version\r
+//\r
+//--------------------------------------------------------------------------------------------------\r
+\r
+class Messages {\r
+ \r
+ //-----------------------------------------------------------------------------------------------\r
+ // Class Variables\r
+ //----------------------------------------------------------------------------------------------- \r
+ var $msgId;\r
+ var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );\r
+ var $msgClass = 'messages';\r
+ var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'>X</a>\n%s</div>\n";\r
+ var $msgBefore = '<p>';\r
+ var $msgAfter = "</p>\n";\r
+\r
+ \r
+ /**\r
+ * Constructor\r
+ * @author Mike Everhart\r
+ */\r
+ public function __construct() {\r
+ \r
+ // Generate a unique ID for this user and session\r
+ $this->msgId = md5(uniqid());\r
+ \r
+ // Create the session array if it doesnt already exist\r
+ if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Add a message to the queue\r
+ * \r
+ * @author Mike Everhart\r
+ * \r
+ * @param string $type The type of message to add\r
+ * @param string $message The message\r
+ * @param string $redirect_to (optional) If set, the user will be redirected to this URL\r
+ * @return bool \r
+ * \r
+ */\r
+ public function add($type, $message, $redirect_to=null) {\r
+ \r
+ if( !isset($_SESSION['flash_messages']) ) return false;\r
+ \r
+ if( !isset($type) || !isset($message[0]) ) return false;\r
+\r
+ // Replace any shorthand codes with their full version\r
+ if( strlen(trim($type)) == 1 ) {\r
+ $type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );\r
+ \r
+ // Backwards compatibility...\r
+ } elseif( $type == 'information' ) {\r
+ $type = 'info'; \r
+ }\r
+ \r
+ // Make sure it's a valid message type\r
+ if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );\r
+ \r
+ // If the session array doesn't exist, create it\r
+ if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();\r
+ \r
+ $_SESSION['flash_messages'][$type][] = $message;\r
+\r
+ if( !is_null($redirect_to) ) {\r
+ header("Location: $redirect_to");\r
+ exit();\r
+ }\r
+ \r
+ return true;\r
+ \r
+ }\r
+ \r
+ //-----------------------------------------------------------------------------------------------\r
+ // display()\r
+ // print queued messages to the screen\r
+ //-----------------------------------------------------------------------------------------------\r
+ /**\r
+ * Display the queued messages\r
+ * \r
+ * @author Mike Everhart\r
+ * \r
+ * @param string $type Which messages to display\r
+ * @param bool $print True = print the messages on the screen\r
+ * @return mixed \r
+ * \r
+ */\r
+ public function display($type='all', $print=true) {\r
+ $messages = '';\r
+ $data = '';\r
+ \r
+ if( !isset($_SESSION['flash_messages']) ) return false;\r
+ \r
+ if( $type == 'g' || $type == 'growl' ) {\r
+ $this->displayGrowlMessages();\r
+ return true;\r
+ }\r
+ \r
+ // Print a certain type of message?\r
+ if( in_array($type, $this->msgTypes) ) {\r
+ foreach( $_SESSION['flash_messages'][$type] as $msg ) {\r
+ $messages .= $this->msgBefore . $msg . $this->msgAfter;\r
+ }\r
+\r
+ $data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);\r
+ \r
+ // Clear the viewed messages\r
+ $this->clear($type);\r
+ \r
+ // Print ALL queued messages\r
+ } elseif( $type == 'all' ) {\r
+ foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {\r
+ $messages = '';\r
+ foreach( $msgArray as $msg ) {\r
+ $messages .= $this->msgBefore . $msg . $this->msgAfter; \r
+ }\r
+ $data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);\r
+ }\r
+ \r
+ // Clear ALL of the messages\r
+ $this->clear();\r
+ \r
+ // Invalid Message Type?\r
+ } else { \r
+ return false;\r
+ }\r
+ \r
+ // Print everything to the screen or return the data\r
+ if( $print ) { \r
+ echo $data; \r
+ } else { \r
+ return $data; \r
+ }\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Check to see if there are any queued error messages\r
+ * \r
+ * @author Mike Everhart\r
+ * \r
+ * @return bool true = There ARE error messages\r
+ * false = There are NOT any error messages\r
+ * \r
+ */\r
+ public function hasErrors() { \r
+ return empty($_SESSION['flash_messages']['error']) ? false : true; \r
+ }\r
+ \r
+ /**\r
+ * Check to see if there are any ($type) messages queued\r
+ * \r
+ * @author Mike Everhart\r
+ * \r
+ * @param string $type The type of messages to check for\r
+ * @return bool \r
+ * \r
+ */\r
+ public function hasMessages($type=null) {\r
+ if( !is_null($type) ) {\r
+ if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type]; \r
+ } else {\r
+ foreach( $this->msgTypes as $type ) {\r
+ if( !empty($_SESSION['flash_messages']) ) return true; \r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ /**\r
+ * Clear messages from the session data\r
+ * \r
+ * @author Mike Everhart\r
+ * \r
+ * @param string $type The type of messages to clear\r
+ * @return bool \r
+ * \r
+ */\r
+ public function clear($type='all') { \r
+ if( $type == 'all' ) {\r
+ unset($_SESSION['flash_messages']); \r
+ } else {\r
+ unset($_SESSION['flash_messages'][$type]);\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ public function __toString() { return $this->hasMessages(); }\r
+\r
+ public function __destruct() {\r
+ //$this->clear();\r
+ }\r
+\r
+\r
+} // end class\r
?>
\ No newline at end of file
--- /dev/null
+<?php
+/*
+ * PHP Pagination Class
+ *
+ * @author David Carr - dave@daveismyname.com - http://www.daveismyname.com
+ * @version 1.0
+ * @date October 20, 2013
+ */
+class Paginator{
+
+ /**
+ * set the number of items per page.
+ *
+ * @var numeric
+ */
+ private $_perPage;
+
+ /**
+ * set get parameter for fetching the page number
+ *
+ * @var string
+ */
+ private $_instance;
+
+ /**
+ * sets the page number.
+ *
+ * @var numeric
+ */
+ private $_page;
+
+ /**
+ * set the limit for the data source
+ *
+ * @var string
+ */
+ private $_limit;
+
+ /**
+ * set the total number of records/items.
+ *
+ * @var numeric
+ */
+ private $_totalRows = 0;
+
+
+
+ /**
+ * __construct
+ *
+ * pass values when class is istantiated
+ *
+ * @param numeric $_perPage sets the number of iteems per page
+ * @param numeric $_instance sets the instance for the GET parameter
+ */
+ public function __construct($perPage,$instance){
+ $this->_instance = $instance;
+ $this->_perPage = $perPage;
+ $this->set_instance();
+ }
+
+ /**
+ * get_start
+ *
+ * creates the starting point for limiting the dataset
+ * @return numeric
+ */
+ private function get_start(){
+ return ($this->_page * $this->_perPage) - $this->_perPage;
+ }
+
+ /**
+ * set_instance
+ *
+ * sets the instance parameter, if numeric value is 0 then set to 1
+ *
+ * @var numeric
+ */
+ private function set_instance(){
+ $this->_page = (int) (!isset($_GET[$this->_instance]) ? 1 : $_GET[$this->_instance]);
+ $this->_page = ($this->_page == 0 ? 1 : $this->_page);
+ }
+
+ /**
+ * set_total
+ *
+ * collect a numberic value and assigns it to the totalRows
+ *
+ * @var numeric
+ */
+ public function set_total($_totalRows){
+ $this->_totalRows = $_totalRows;
+ }
+
+ /**
+ * get_limit
+ *
+ * returns the limit for the data source, calling the get_start method and passing in the number of items perp page
+ *
+ * @return string
+ */
+ public function get_limit(){
+ if (STORAGE == 'postgres') {
+ return "LIMIT ".$this->_perPage." OFFSET ".$this->get_start();
+ } else {
+ return "LIMIT ".$this->get_start().",".$this->_perPage;
+ }
+ }
+
+ /**
+ * page_links
+ *
+ * create the html links for navigating through the dataset
+ *
+ * @var sting $path optionally set the path for the link
+ * @var sting $ext optionally pass in extra parameters to the GET
+ * @return string returns the html menu
+ */
+ public function page_links($path='?',$ext=null)
+ {
+ $adjacents = "2";
+ $prev = $this->_page - 1;
+ $next = $this->_page + 1;
+ $lastpage = ceil($this->_totalRows/$this->_perPage);
+ $lpm1 = $lastpage - 1;
+
+ $pagination = "";
+ if($lastpage > 1)
+ {
+ $pagination .= "<div class='pagination'>";
+ if ($this->_page > 1)
+ $pagination.= "<a href='".$path."$this->_instance=$prev"."$ext'>« previous</a>";
+ else
+ $pagination.= "<span class='disabled'>« previous</span>";
+
+ if ($lastpage < 7 + ($adjacents * 2))
+ {
+ for ($counter = 1; $counter <= $lastpage; $counter++)
+ {
+ if ($counter == $this->_page)
+ $pagination.= "<span class='current'>$counter</span>";
+ else
+ $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
+ }
+ }
+ elseif($lastpage > 5 + ($adjacents * 2))
+ {
+ if($this->_page < 1 + ($adjacents * 2))
+ {
+ for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
+ {
+ if ($counter == $this->_page)
+ $pagination.= "<span class='current'>$counter</span>";
+ else
+ $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
+ }
+ $pagination.= "...";
+ $pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
+ $pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
+ }
+ elseif($lastpage - ($adjacents * 2) > $this->_page && $this->_page > ($adjacents * 2))
+ {
+ $pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
+ $pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
+ $pagination.= "...";
+ for ($counter = $this->_page - $adjacents; $counter <= $this->_page + $adjacents; $counter++)
+ {
+ if ($counter == $this->_page)
+ $pagination.= "<span class='current'>$counter</span>";
+ else
+ $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
+ }
+ $pagination.= "..";
+ $pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
+ $pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
+ }
+ else
+ {
+ $pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
+ $pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
+ $pagination.= "..";
+ for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++)
+ {
+ if ($counter == $this->_page)
+ $pagination.= "<span class='current'>$counter</span>";
+ else
+ $pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
+ }
+ }
+ }
+
+ if ($this->_page < $counter - 1)
+ $pagination.= "<a href='".$path."$this->_instance=$next"."$ext'>next »</a>";
+ else
+ $pagination.= "<span class='disabled'>next »</span>";
+ $pagination.= "</div>\n";
+ }
+
+
+ return $pagination;
+ }
+}
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <support@inthepoche.com>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-class MyTool
-{
- public static function initPhp()
- {
- define('START_TIME', microtime(true));
-
- if (phpversion() < 5) {
- die("Argh you don't have PHP 5 !");
- }
-
- error_reporting(E_ALL);
-
- function stripslashesDeep($value) {
- return is_array($value)
- ? array_map('stripslashesDeep', $value)
- : stripslashes($value);
- }
-
- if (get_magic_quotes_gpc()) {
- $_POST = array_map('stripslashesDeep', $_POST);
- $_GET = array_map('stripslashesDeep', $_GET);
- $_COOKIE = array_map('stripslashesDeep', $_COOKIE);
- }
-
- ob_start();
- register_shutdown_function('ob_end_flush');
- }
-
- public static function isUrl($url)
- {
- // http://neo22s.com/check-if-url-exists-and-is-online-php/
- $pattern='|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i';
-
- return preg_match($pattern, $url);
- }
-
- public static function isEmail($email)
- {
- $pattern = "/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2, 4}$/i";
-
- return (preg_match($pattern, $email));
- }
-
- public static function formatBBCode($text)
- {
- $replace = array(
- '/\[m\](.+?)\[\/m\]/is'
- => '/* moderate */',
- '/\[b\](.+?)\[\/b\]/is'
- => '<strong>$1</strong>',
- '/\[i\](.+?)\[\/i\]/is'
- => '<em>$1</em>',
- '/\[s\](.+?)\[\/s\]/is'
- => '<del>$1</del>',
- '/\[u\](.+?)\[\/u\]/is'
- => '<span style="text-decoration: underline;">$1</span>',
- '/\[url\](.+?)\[\/url]/is'
- => '<a href="$1">$1</a>',
- '/\[url=(\w+:\/\/[^\]]+)\](.+?)\[\/url]/is'
- => '<a href="$1">$2</a>',
- '/\[quote\](.+?)\[\/quote\]/is'
- => '<blockquote>$1</blockquote>',
- '/\[code\](.+?)\[\/code\]/is'
- => '<code>$1</code>',
- '/\[([^[]+)\|([^[]+)\]/is'
- => '<a href="$2">$1</a>'
- );
- $text = preg_replace(
- array_keys($replace),
- array_values($replace),
- $text
- );
-
- return $text;
- }
-
- public static function formatText($text)
- {
- $text = preg_replace_callback(
- '/<code_html>(.*?)<\/code_html>/is',
- create_function(
- '$matches',
- 'return htmlspecialchars($matches[1]);'
- ),
- $text
- );
- $text = preg_replace_callback(
- '/<code_php>(.*?)<\/code_php>/is',
- create_function(
- '$matches',
- 'return highlight_string("<?php $matches[1] ?>", true);'
- ),
- $text
- );
- $text = preg_replace('/<br \/>/is', '', $text);
-
- $text = preg_replace(
- '#(^|\s)([a-z]+://([^\s\w/]?[\w/])*)(\s|$)#im',
- '\\1<a href="\\2">\\2</a>\\4',
- $text
- );
- $text = preg_replace(
- '#(^|\s)wp:?([a-z]{2}|):([\w]+)#im',
- '\\1<a href="http://\\2.wikipedia.org/wiki/\\3">\\3</a>',
- $text
- );
- $text = str_replace(
- 'http://.wikipedia.org/wiki/',
- 'http://www.wikipedia.org/wiki/',
- $text
- );
- $text = str_replace('\wp:', 'wp:', $text);
- $text = str_replace('\http:', 'http:', $text);
- $text = MyTool::formatBBCode($text);
- $text = nl2br($text);
-
- return $text;
- }
-
- public static function getUrl()
- {
- $https = (!empty($_SERVER['HTTPS'])
- && (strtolower($_SERVER['HTTPS']) == 'on'))
- || (isset($_SERVER["SERVER_PORT"])
- && $_SERVER["SERVER_PORT"] == '443'); // HTTPS detection.
- $serverport = (!isset($_SERVER["SERVER_PORT"])
- || $_SERVER["SERVER_PORT"] == '80'
- || ($https && $_SERVER["SERVER_PORT"] == '443')
- ? ''
- : ':' . $_SERVER["SERVER_PORT"]);
-
- $scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]);
-
- if (!isset($_SERVER["SERVER_NAME"])) {
- return $scriptname;
- }
-
- return 'http' . ($https ? 's' : '') . '://'
- . $_SERVER["SERVER_NAME"] . $serverport . $scriptname;
- }
-
- public static function rrmdir($dir)
- {
- if (is_dir($dir) && ($d = @opendir($dir))) {
- while (($file = @readdir($d)) !== false) {
- if ( $file == '.' || $file == '..' ) {
- continue;
- } else {
- unlink($dir . '/' . $file);
- }
- }
- }
- }
-
- public static function humanBytes($bytes)
- {
- $siPrefix = array( 'bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB' );
- $base = 1024;
- $class = min((int) log($bytes, $base), count($siPrefix) - 1);
- $val = sprintf('%1.2f', $bytes / pow($base, $class));
-
- return $val . ' ' . $siPrefix[$class];
- }
-
- public static function returnBytes($val)
- {
- $val = trim($val);
- $last = strtolower($val[strlen($val)-1]);
- switch($last)
- {
- case 'g': $val *= 1024;
- case 'm': $val *= 1024;
- case 'k': $val *= 1024;
- }
-
- return $val;
- }
-
- public static function getMaxFileSize()
- {
- $sizePostMax = MyTool::returnBytes(ini_get('post_max_size'));
- $sizeUploadMax = MyTool::returnBytes(ini_get('upload_max_filesize'));
-
- // Return the smaller of two:
- return min($sizePostMax, $sizeUploadMax);
- }
-
- public static function smallHash($text)
- {
- $t = rtrim(base64_encode(hash('crc32', $text, true)), '=');
- // Get rid of characters which need encoding in URLs.
- $t = str_replace('+', '-', $t);
- $t = str_replace('/', '_', $t);
- $t = str_replace('=', '@', $t);
-
- return $t;
- }
-
- public static function renderJson($data)
- {
- header('Cache-Control: no-cache, must-revalidate');
- header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
- header('Content-type: application/json; charset=UTF-8');
-
- echo json_encode($data);
- exit();
- }
-
- public static function grabToLocal($url, $file, $force = false)
- {
- if ((!file_exists($file) || $force) && in_array('curl', get_loaded_extensions())){
- $ch = curl_init ($url);
- curl_setopt($ch, CURLOPT_HEADER, false);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
- $raw = curl_exec($ch);
- if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) {
- $fp = fopen($file, 'x');
- fwrite($fp, $raw);
- fclose($fp);
- }
- curl_close ($ch);
- }
- }
-
- public static function redirect($rurl = '')
- {
- if ($rurl === '') {
- // if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['SERVER_NAME'])==0)
- $rurl = (empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER']);
- if (isset($_POST['returnurl'])) {
- $rurl = $_POST['returnurl'];
- }
- }
-
- // prevent loop
- if (empty($rurl) || parse_url($rurl, PHP_URL_QUERY) === $_SERVER['QUERY_STRING']) {
- $rurl = MyTool::getUrl();
- }
-
- if (substr($rurl, 0, 1) !== '?') {
- $ref = MyTool::getUrl();
- if (substr($rurl, 0, strlen($ref)) !== $ref) {
- $rurl = $ref;
- }
- }
- header('Location: '.$rurl);
- exit();
- }
-
- public static function silence_errors($num, $str)
- {
-// No-op
- }
-}
\ No newline at end of file
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <nicolas@loeuillet.org>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-define ('POCHE_VERSION', '0.2.1');
-
-if (!is_dir('db/')) {
- @mkdir('db/',0705);
-}
-
-define ('MODE_DEMO', FALSE);
-define ('ABS_PATH', 'assets/');
-define ('CONVERT_LINKS_FOOTNOTES', TRUE);
-define ('REVERT_FORCED_PARAGRAPH_ELEMENTS',FALSE);
-define ('DOWNLOAD_PICTURES', TRUE);
-define ('SALT', '464v54gLLw928uz4zUBqkRJeiPY68zCX');
-$storage_type = 'sqlite'; # sqlite or file
-
-include 'functions.php';
-require_once 'Readability.php';
-require_once 'Encoding.php';
-require_once 'rain.tpl.class.php';
-require_once 'MyTool.class.php';
-require_once 'Session.class.php';
-require_once 'store/store.class.php';
-require_once 'store/sqlite.class.php';
-require_once 'store/file.class.php';
-require_once 'class.messages.php';
-
-Session::init();
-
-$store = new $storage_type();
-# initialisation de RainTPL
-raintpl::$tpl_dir = './tpl/';
-raintpl::$cache_dir = './cache/';
-raintpl::$base_url = get_poche_url();
-raintpl::configure('path_replace', false);
-raintpl::configure('debug', false);
-$tpl = new raintpl();
-
-if(!$store->isInstalled())
-{
- logm('poche still not installed');
- $tpl->draw('install');
- if (isset($_GET['install'])) {
- if (($_POST['password'] == $_POST['password_repeat'])
- && $_POST['password'] != "" && $_POST['login'] != "") {
- $store->install($_POST['login'], encode_string($_POST['password'] . $_POST['login']));
- Session::logout();
- MyTool::redirect();
- }
- }
- exit();
-}
-
-$_SESSION['login'] = (isset ($_SESSION['login'])) ? $_SESSION['login'] : $store->getLogin();
-$_SESSION['pass'] = (isset ($_SESSION['pass'])) ? $_SESSION['pass'] : $store->getPassword();
-
-$msg = new Messages();
-$tpl->assign('msg', $msg);
\ No newline at end of file
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <support@inthepoche.com>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-/**
- * Permet de générer l'URL de poche pour le bookmarklet
- */
-function get_poche_url()
-{
- $protocol = "http";
- if(isset($_SERVER['HTTPS'])) {
- if($_SERVER['HTTPS'] != "off" && $_SERVER['HTTPS'] != "") {
- $protocol = "https";
- }
- }
-
- return $protocol . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
-}
-
-function encode_string($string)
-{
- return sha1($string . SALT);
-}
-
-// function define to retrieve url content
-function get_external_file($url)
-{
- $timeout = 15;
- // spoofing FireFox 18.0
- $useragent="Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0";
-
- if (in_array ('curl', get_loaded_extensions())) {
- // Fetch feed from URL
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_HEADER, false);
-
- // FOR SSL do not verified certificate
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE );
-
- // FeedBurner requires a proper USER-AGENT...
- curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
- curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate");
- curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
-
- $data = curl_exec($curl);
-
- $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
-
- $httpcodeOK = isset($httpcode) and ($httpcode == 200 or $httpcode == 301);
-
- curl_close($curl);
- } else {
-
- // create http context and add timeout and user-agent
- $context = stream_context_create(array(
- 'http'=>array('timeout' => $timeout,
- 'header'=> "User-Agent: ".$useragent, /*spoot Mozilla Firefox*/
- 'follow_location' => true),
- // FOR SSL do not verified certificate
- 'ssl' => array('verify_peer' => false,
- 'allow_self_signed' => true)
- )
- );
-
- // only download page lesser than 4MB
- $data = @file_get_contents($url, false, $context, -1, 4000000); // We download at most 4 MB from source.
-
- if(isset($http_response_header) and isset($http_response_header[0])) {
- $httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== FALSE) or (strpos($http_response_header[0], '301 Moved Permanently') !== FALSE));
- }
- }
-
- // if response is not empty and response is OK
- if (isset($data) and isset($httpcodeOK) and $httpcodeOK ) {
-
- // take charset of page and get it
- preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
-
- // if meta tag is found
- if (!empty($meta[0])) {
- // retrieve encoding in $enc
- preg_match('#charset="?(.*)"#si', $meta[0], $enc);
-
- // if charset is found set it otherwise, set it to utf-8
- $html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
-
- } else {
- $html_charset = 'utf-8';
- $enc[1] = '';
- }
-
- // replace charset of url to charset of page
- $data = str_replace('charset='.$enc[1], 'charset='.$html_charset, $data);
-
- return $data;
- }
- else {
- return FALSE;
- }
-}
-
-/**
- * Préparation de l'URL avec récupération du contenu avant insertion en base
- */
-function prepare_url($url)
-{
- $parametres = array();
- $url = html_entity_decode(trim($url));
-
- // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...)
- // from shaarli, by sebsauvage
- $i=strpos($url,'&utm_source='); if ($i!==false) $url=substr($url,0,$i);
- $i=strpos($url,'?utm_source='); if ($i!==false) $url=substr($url,0,$i);
- $i=strpos($url,'#xtor=RSS-'); if ($i!==false) $url=substr($url,0,$i);
-
- $title = $url;
- $html = Encoding::toUTF8(get_external_file($url,15));
- // If get_external_file if not able to retrieve HTTPS content try the same URL with HTTP protocol
- if (!preg_match('!^https?://!i', $url) && (!isset($html) || strlen($html) <= 0)) {
- $url = 'http://' . $url;
- $html = Encoding::toUTF8(get_external_file($url,15));
- }
-
- if (function_exists('tidy_parse_string')) {
- $tidy = tidy_parse_string($html, array(), 'UTF8');
- $tidy->cleanRepair();
- $html = $tidy->value;
- }
-
- if (isset($html) and strlen($html) > 0)
- {
- $r = new Readability($html, $url);
-
- $r->convertLinksToFootnotes = CONVERT_LINKS_FOOTNOTES;
- $r->revertForcedParagraphElements = REVERT_FORCED_PARAGRAPH_ELEMENTS;
-
- if($r->init())
- {
- $content = $r->articleContent->innerHTML;
- $parametres['title'] = $r->articleTitle->innerHTML;
- $parametres['content'] = $content;
- return $parametres;
- }
- }
-
- return FALSE;
-}
-
-/**
- * On modifie les URLS des images dans le corps de l'article
- */
-function filtre_picture($content, $url, $id)
-{
- $matches = array();
- preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
- foreach($matches as $i => $link)
- {
- $link[1] = trim($link[1]);
- if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1]) )
- {
- $absolute_path = get_absolute_link($link[2],$url);
- $filename = basename(parse_url($absolute_path, PHP_URL_PATH));
- $directory = create_assets_directory($id);
- $fullpath = $directory . '/' . $filename;
- download_pictures($absolute_path, $fullpath);
- $content = str_replace($matches[$i][2], $fullpath, $content);
- }
-
- }
-
- return $content;
-}
-
-/**
- * Retourne le lien absolu
- */
-function get_absolute_link($relative_link, $url)
-{
- /* return if already absolute URL */
- if (parse_url($relative_link, PHP_URL_SCHEME) != '') return $relative_link;
-
- /* queries and anchors */
- if ($relative_link[0]=='#' || $relative_link[0]=='?') return $url . $relative_link;
-
- /* parse base URL and convert to local variables:
- $scheme, $host, $path */
- extract(parse_url($url));
-
- /* remove non-directory element from path */
- $path = preg_replace('#/[^/]*$#', '', $path);
-
- /* destroy path if relative url points to root */
- if ($relative_link[0] == '/') $path = '';
-
- /* dirty absolute URL */
- $abs = $host . $path . '/' . $relative_link;
-
- /* replace '//' or '/./' or '/foo/../' with '/' */
- $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
- for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
-
- /* absolute URL is ready! */
- return $scheme.'://'.$abs;
-}
-
-/**
- * Téléchargement des images
- */
-
-function download_pictures($absolute_path, $fullpath)
-{
- $rawdata = get_external_file($absolute_path);
-
- if(file_exists($fullpath)) {
- unlink($fullpath);
- }
- $fp = fopen($fullpath, 'x');
- fwrite($fp, $rawdata);
- fclose($fp);
-}
-
-/**
- * Crée un répertoire de médias pour l'article
- */
-function create_assets_directory($id)
-{
- $assets_path = ABS_PATH;
- if(!is_dir($assets_path)) {
- mkdir($assets_path, 0705);
- }
-
- $article_directory = $assets_path . $id;
- if(!is_dir($article_directory)) {
- mkdir($article_directory, 0705);
- }
-
- return $article_directory;
-}
-
-/**
- * Suppression du répertoire d'images
- */
-function remove_directory($directory)
-{
- if(is_dir($directory)) {
- $files = array_diff(scandir($directory), array('.','..'));
- foreach ($files as $file) {
- (is_dir("$directory/$file")) ? remove_directory("$directory/$file") : unlink("$directory/$file");
- }
- return rmdir($directory);
- }
-}
-
-function display_view($view, $id = 0, $full_head = 'yes')
-{
- global $tpl, $store, $msg;
-
- switch ($view)
- {
- case 'export':
- $entries = $store->retrieveAll();
- $tpl->assign('export', myTool::renderJson($entries));
- $tpl->draw('export');
- logm('export view');
- break;
- case 'config':
- $tpl->assign('load_all_js', 0);
- $tpl->draw('head');
- $tpl->draw('home');
- $tpl->draw('config');
- $tpl->draw('js');
- $tpl->draw('footer');
- logm('config view');
- break;
- case 'view':
- $entry = $store->retrieveOneById($id);
-
- if ($entry != NULL) {
- $tpl->assign('id', $entry['id']);
- $tpl->assign('url', $entry['url']);
- $tpl->assign('title', $entry['title']);
- $content = $entry['content'];
- if (function_exists('tidy_parse_string')) {
- $tidy = tidy_parse_string($content, array('indent'=>true, 'show-body-only' => true), 'UTF8');
- $tidy->cleanRepair();
- $content = $tidy->value;
- }
- $tpl->assign('content', $content);
- $tpl->assign('is_fav', $entry['is_fav']);
- $tpl->assign('is_read', $entry['is_read']);
- $tpl->assign('load_all_js', 0);
- $tpl->draw('view');
- }
- else {
- logm('error in view call : entry is NULL');
- }
-
- logm('view link #' . $id);
- break;
- default: # home view
- $entries = $store->getEntriesByView($view);
-
- $tpl->assign('entries', $entries);
-
- if ($full_head == 'yes') {
- $tpl->assign('load_all_js', 1);
- $tpl->draw('head');
- $tpl->draw('home');
- }
-
- $tpl->draw('entries');
-
- if ($full_head == 'yes') {
- $tpl->draw('js');
- $tpl->draw('footer');
- }
- break;
- }
-}
-
-/**
- * Appel d'une action (mark as fav, archive, delete)
- */
-function action_to_do($action, $url, $id = 0)
-{
- global $store, $msg;
-
- switch ($action)
- {
- case 'add':
- if ($url == '')
- continue;
-
- if (MyTool::isUrl($url)) {
- if($parametres_url = prepare_url($url)) {
- if ($store->add($url, $parametres_url['title'], $parametres_url['content'])) {
- $last_id = $store->getLastId();
- if (DOWNLOAD_PICTURES) {
- $content = filtre_picture($parametres_url['content'], $url, $last_id);
- }
- $msg->add('s', 'the link has been added successfully');
- }
- else {
- $msg->add('e', 'error during insertion : the link wasn\'t added');
- }
- }
- else {
- $msg->add('e', 'error during url preparation : the link wasn\'t added');
- logm('error during url preparation');
- }
- }
- else {
- $msg->add('e', 'error during url preparation : the link is not valid');
- logm($url . ' is not a valid url');
- }
-
- logm('add link ' . $url);
- break;
- case 'delete':
- if ($store->deleteById($id)) {
- remove_directory(ABS_PATH . $id);
- $msg->add('s', 'the link has been deleted successfully');
- logm('delete link #' . $id);
- }
- else {
- $msg->add('e', 'the link wasn\'t deleted');
- logm('error : can\'t delete link #' . $id);
- }
- break;
- case 'toggle_fav' :
- $store->favoriteById($id);
- logm('mark as favorite link #' . $id);
- break;
- case 'toggle_archive' :
- $store->archiveById($id);
- logm('archive link #' . $id);
- break;
- default:
- break;
- }
-}
-
-function logm($message)
-{
- $t = strval(date('Y/m/d_H:i:s')).' - '.$_SERVER["REMOTE_ADDR"].' - '.strval($message)."\n";
- file_put_contents('./log.txt',$t,FILE_APPEND);
-}
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <support@inthepoche.com>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+class Database {
+ var $handle;
+
+ function __construct()
+ {
+ switch (STORAGE) {
+ case 'sqlite':
+ $db_path = 'sqlite:' . STORAGE_SQLITE;
+ $this->handle = new PDO($db_path);
+ break;
+ case 'mysql':
+ $db_path = 'mysql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
+ $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
+ break;
+ case 'postgres':
+ $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
+ $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
+ break;
+ }
+
+ $this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ Tools::logm('storage type ' . STORAGE);
+ }
+
+ private function getHandle() {
+ return $this->handle;
+ }
+
+ public function isInstalled() {
+ $sql = "SELECT username FROM users";
+ $query = $this->executeQuery($sql, array());
+ $hasAdmin = count($query->fetchAll());
+
+ if ($hasAdmin == 0)
+ return FALSE;
+
+ return TRUE;
+ }
+
+ public function install($login, $password) {
+ $sql = 'INSERT INTO users ( username, password, name, email) VALUES (?, ?, ?, ?)';
+ $params = array($login, $password, $login, ' ');
+ $query = $this->executeQuery($sql, $params);
+
+ $sequence = '';
+ if (STORAGE == 'postgres') {
+ $sequence = 'users_id_seq';
+ }
+
+ $id_user = intval($this->getLastId($sequence));
+
+ $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
+ $params = array($id_user, 'pager', '10');
+ $query = $this->executeQuery($sql, $params);
+
+ $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
+ $params = array($id_user, 'language', 'en_EN.UTF8');
+ $query = $this->executeQuery($sql, $params);
+
+ return TRUE;
+ }
+
+ private function getConfigUser($id) {
+ $sql = "SELECT * FROM users_config WHERE user_id = ?";
+ $query = $this->executeQuery($sql, array($id));
+ $result = $query->fetchAll();
+ $user_config = array();
+
+ foreach ($result as $key => $value) {
+ $user_config[$value['name']] = $value['value'];
+ }
+
+ return $user_config;
+ }
+
+ public function login($username, $password) {
+ $sql = "SELECT * FROM users WHERE username=? AND password=?";
+ $query = $this->executeQuery($sql, array($username, $password));
+ $login = $query->fetchAll();
+
+ $user = array();
+ if (isset($login[0])) {
+ $user['id'] = $login[0]['id'];
+ $user['username'] = $login[0]['username'];
+ $user['password'] = $login[0]['password'];
+ $user['name'] = $login[0]['name'];
+ $user['email'] = $login[0]['email'];
+ $user['config'] = $this->getConfigUser($login[0]['id']);
+ }
+
+ return $user;
+ }
+
+ public function updatePassword($id, $password)
+ {
+ $sql_update = "UPDATE users SET password=? WHERE id=?";
+ $params_update = array($password, $id);
+ $query = $this->executeQuery($sql_update, $params_update);
+ }
+
+ private function executeQuery($sql, $params) {
+ try
+ {
+ $query = $this->getHandle()->prepare($sql);
+ $query->execute($params);
+ return $query;
+ }
+ catch (Exception $e)
+ {
+ Tools::logm('execute query error : '.$e->getMessage());
+ return FALSE;
+ }
+ }
+
+ public function retrieveAll($user_id) {
+ $sql = "SELECT * FROM entries WHERE user_id=? ORDER BY id";
+ $query = $this->executeQuery($sql, array($user_id));
+ $entries = $query->fetchAll();
+
+ return $entries;
+ }
+
+ public function retrieveOneById($id, $user_id) {
+ $entry = NULL;
+ $sql = "SELECT * FROM entries WHERE id=? AND user_id=?";
+ $params = array(intval($id), $user_id);
+ $query = $this->executeQuery($sql, $params);
+ $entry = $query->fetchAll();
+
+ return $entry[0];
+ }
+
+ public function getEntriesByView($view, $user_id, $limit = '') {
+ switch ($_SESSION['sort'])
+ {
+ case 'ia':
+ $order = 'ORDER BY id';
+ break;
+ case 'id':
+ $order = 'ORDER BY id DESC';
+ break;
+ case 'ta':
+ $order = 'ORDER BY lower(title)';
+ break;
+ case 'td':
+ $order = 'ORDER BY lower(title) DESC';
+ break;
+ default:
+ $order = 'ORDER BY id';
+ break;
+ }
+
+ switch ($view)
+ {
+ case 'archive':
+ $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? " . $order;
+ $params = array($user_id, 1);
+ break;
+ case 'fav' :
+ $sql = "SELECT * FROM entries WHERE user_id=? AND is_fav=? " . $order;
+ $params = array($user_id, 1);
+ break;
+ default:
+ $sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? " . $order;
+ $params = array($user_id, 0);
+ break;
+ }
+
+ $sql .= ' ' . $limit;
+
+ $query = $this->executeQuery($sql, $params);
+ $entries = $query->fetchAll();
+
+ return $entries;
+ }
+
+ public function add($url, $title, $content, $user_id) {
+ $sql_action = 'INSERT INTO entries ( url, title, content, user_id ) VALUES (?, ?, ?, ?)';
+ $params_action = array($url, $title, $content, $user_id);
+ $query = $this->executeQuery($sql_action, $params_action);
+ return $query;
+ }
+
+ public function deleteById($id, $user_id) {
+ $sql_action = "DELETE FROM entries WHERE id=? AND user_id=?";
+ $params_action = array($id, $user_id);
+ $query = $this->executeQuery($sql_action, $params_action);
+ return $query;
+ }
+
+ public function favoriteById($id, $user_id) {
+ $sql_action = "UPDATE entries SET is_fav=NOT is_fav WHERE id=? AND user_id=?";
+ $params_action = array($id, $user_id);
+ $query = $this->executeQuery($sql_action, $params_action);
+ }
+
+ public function archiveById($id, $user_id) {
+ $sql_action = "UPDATE entries SET is_read=NOT is_read WHERE id=? AND user_id=?";
+ $params_action = array($id, $user_id);
+ $query = $this->executeQuery($sql_action, $params_action);
+ }
+
+ public function getLastId($column = '') {
+ return $this->getHandle()->lastInsertId($column);
+ }
+}
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <support@inthepoche.com>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+class Poche
+{
+ public $user;
+ public $store;
+ public $tpl;
+ public $messages;
+ public $pagination;
+
+ function __construct()
+ {
+ $this->store = new Database();
+ $this->init();
+ $this->messages = new Messages();
+
+ # installation
+ if(!$this->store->isInstalled())
+ {
+ $this->install();
+ }
+ }
+
+ private function init()
+ {
+ if (file_exists('./install') && !DEBUG_POCHE) {
+ Tools::logm('folder /install exists');
+ die('the folder /install exists, you have to delete it before using poche.');
+ }
+
+ Tools::initPhp();
+ Session::init();
+
+ if (isset($_SESSION['poche_user']) && $_SESSION['poche_user'] != array()) {
+ $this->user = $_SESSION['poche_user'];
+ }
+ else {
+ # fake user, just for install & login screens
+ $this->user = new User();
+ $this->user->setConfig($this->getDefaultConfig());
+ }
+
+ # l10n
+ $language = $this->user->getConfigValue('language');
+ putenv('LC_ALL=' . $language);
+ setlocale(LC_ALL, $language);
+ bindtextdomain($language, LOCALE);
+ textdomain($language);
+
+ # template engine
+ $loader = new Twig_Loader_Filesystem(TPL);
+ if (DEBUG_POCHE) {
+ $twig_params = array();
+ }
+ else {
+ $twig_params = array('cache' => CACHE);
+ }
+ $this->tpl = new Twig_Environment($loader, $twig_params);
+ $this->tpl->addExtension(new Twig_Extensions_Extension_I18n());
+ # filter to display domain name of an url
+ $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
+ $this->tpl->addFilter($filter);
+
+ # Pagination
+ $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p');
+ }
+
+ private function install()
+ {
+ Tools::logm('poche still not installed');
+ echo $this->tpl->render('install.twig', array(
+ 'token' => Session::getToken()
+ ));
+ if (isset($_GET['install'])) {
+ if (($_POST['password'] == $_POST['password_repeat'])
+ && $_POST['password'] != "" && $_POST['login'] != "") {
+ # let's rock, install poche baby !
+ $this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']));
+ Session::logout();
+ Tools::logm('poche is now installed');
+ Tools::redirect();
+ }
+ else {
+ Tools::logm('error during installation');
+ Tools::redirect();
+ }
+ }
+ exit();
+ }
+
+ public function getDefaultConfig()
+ {
+ return array(
+ 'pager' => PAGINATION,
+ 'language' => LANG,
+ );
+ }
+
+ /**
+ * Call action (mark as fav, archive, delete, etc.)
+ */
+ public function action($action, Url $url, $id = 0, $import = FALSE)
+ {
+ switch ($action)
+ {
+ case 'add':
+ if($parametres_url = $url->fetchContent()) {
+ if ($this->store->add($url->getUrl(), $parametres_url['title'], $parametres_url['content'], $this->user->getId())) {
+ Tools::logm('add link ' . $url->getUrl());
+ $sequence = '';
+ if (STORAGE == 'postgres') {
+ $sequence = 'entries_id_seq';
+ }
+ $last_id = $this->store->getLastId($sequence);
+ if (DOWNLOAD_PICTURES) {
+ $content = filtre_picture($parametres_url['content'], $url->getUrl(), $last_id);
+ }
+ if (!$import) {
+ $this->messages->add('s', _('the link has been added successfully'));
+ }
+ }
+ else {
+ if (!$import) {
+ $this->messages->add('e', _('error during insertion : the link wasn\'t added'));
+ Tools::logm('error during insertion : the link wasn\'t added ' . $url->getUrl());
+ }
+ }
+ }
+ else {
+ if (!$import) {
+ $this->messages->add('e', _('error during fetching content : the link wasn\'t added'));
+ Tools::logm('error during content fetch ' . $url->getUrl());
+ }
+ }
+ if (!$import) {
+ Tools::redirect();
+ }
+ break;
+ case 'delete':
+ $msg = 'delete link #' . $id;
+ if ($this->store->deleteById($id, $this->user->getId())) {
+ if (DOWNLOAD_PICTURES) {
+ remove_directory(ABS_PATH . $id);
+ }
+ $this->messages->add('s', _('the link has been deleted successfully'));
+ }
+ else {
+ $this->messages->add('e', _('the link wasn\'t deleted'));
+ $msg = 'error : can\'t delete link #' . $id;
+ }
+ Tools::logm($msg);
+ Tools::redirect('?');
+ break;
+ case 'toggle_fav' :
+ $this->store->favoriteById($id, $this->user->getId());
+ Tools::logm('mark as favorite link #' . $id);
+ if (!$import) {
+ Tools::redirect();
+ }
+ break;
+ case 'toggle_archive' :
+ $this->store->archiveById($id, $this->user->getId());
+ Tools::logm('archive link #' . $id);
+ if (!$import) {
+ Tools::redirect();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ function displayView($view, $id = 0)
+ {
+ $tpl_vars = array();
+
+ switch ($view)
+ {
+ case 'config':
+ $dev = $this->getPocheVersion('dev');
+ $prod = $this->getPocheVersion('prod');
+ $compare_dev = version_compare(POCHE_VERSION, $dev);
+ $compare_prod = version_compare(POCHE_VERSION, $prod);
+ $tpl_vars = array(
+ 'dev' => $dev,
+ 'prod' => $prod,
+ 'compare_dev' => $compare_dev,
+ 'compare_prod' => $compare_prod,
+ );
+ Tools::logm('config view');
+ break;
+ case 'view':
+ $entry = $this->store->retrieveOneById($id, $this->user->getId());
+ if ($entry != NULL) {
+ Tools::logm('view link #' . $id);
+ $content = $entry['content'];
+ if (function_exists('tidy_parse_string')) {
+ $tidy = tidy_parse_string($content, array('indent'=>true, 'show-body-only' => true), 'UTF8');
+ $tidy->cleanRepair();
+ $content = $tidy->value;
+ }
+ $tpl_vars = array(
+ 'entry' => $entry,
+ 'content' => $content,
+ );
+ }
+ else {
+ Tools::logm('error in view call : entry is NULL');
+ }
+ break;
+ default: # home view
+ $entries = $this->store->getEntriesByView($view, $this->user->getId());
+ $this->pagination->set_total(count($entries));
+ $page_links = $this->pagination->page_links('?view=' . $view . '&sort=' . $_SESSION['sort'] . '&');
+ $datas = $this->store->getEntriesByView($view, $this->user->getId(), $this->pagination->get_limit());
+ $tpl_vars = array(
+ 'entries' => $datas,
+ 'page_links' => $page_links,
+ );
+ Tools::logm('display ' . $view . ' view');
+ break;
+ }
+
+ return $tpl_vars;
+ }
+
+ /**
+ * update the password of the current user.
+ * if MODE_DEMO is TRUE, the password can't be updated.
+ * @todo add the return value
+ * @todo set the new password in function header like this updatePassword($newPassword)
+ * @return boolean
+ */
+ public function updatePassword()
+ {
+ if (MODE_DEMO) {
+ $this->messages->add('i', _('in demo mode, you can\'t update your password'));
+ Tools::logm('in demo mode, you can\'t do this');
+ Tools::redirect('?view=config');
+ }
+ else {
+ if (isset($_POST['password']) && isset($_POST['password_repeat'])) {
+ if ($_POST['password'] == $_POST['password_repeat'] && $_POST['password'] != "") {
+ $this->messages->add('s', _('your password has been updated'));
+ $this->store->updatePassword($this->user->getId(), Tools::encodeString($_POST['password'] . $this->user->getUsername()));
+ Session::logout();
+ Tools::logm('password updated');
+ Tools::redirect();
+ }
+ else {
+ $this->messages->add('e', _('the two fields have to be filled & the password must be the same in the two fields'));
+ Tools::redirect('?view=config');
+ }
+ }
+ }
+ }
+
+ /**
+ * checks if login & password are correct and save the user in session.
+ * it redirects the user to the $referer link
+ * @param string $referer the url to redirect after login
+ * @todo add the return value
+ * @return boolean
+ */
+ public function login($referer)
+ {
+ if (!empty($_POST['login']) && !empty($_POST['password'])) {
+ $user = $this->store->login($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']));
+ if ($user != array()) {
+ # Save login into Session
+ Session::login($user['username'], $user['password'], $_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']), array('poche_user' => new User($user)));
+
+ $this->messages->add('s', _('welcome to your poche'));
+ if (!empty($_POST['longlastingsession'])) {
+ $_SESSION['longlastingsession'] = 31536000;
+ $_SESSION['expires_on'] = time() + $_SESSION['longlastingsession'];
+ session_set_cookie_params($_SESSION['longlastingsession']);
+ } else {
+ session_set_cookie_params(0);
+ }
+ session_regenerate_id(true);
+ Tools::logm('login successful');
+ Tools::redirect($referer);
+ }
+ $this->messages->add('e', _('login failed: bad login or password'));
+ Tools::logm('login failed');
+ Tools::redirect();
+ } else {
+ $this->messages->add('e', _('login failed: you have to fill all fields'));
+ Tools::logm('login failed');
+ Tools::redirect();
+ }
+ }
+
+ /**
+ * log out the poche user. It cleans the session.
+ * @todo add the return value
+ * @return boolean
+ */
+ public function logout()
+ {
+ $this->user = array();
+ Session::logout();
+ $this->messages->add('s', _('see you soon!'));
+ Tools::logm('logout');
+ Tools::redirect();
+ }
+
+ /**
+ * import from Instapaper. poche needs a ./instapaper-export.html file
+ * @todo add the return value
+ * @return boolean
+ */
+ private function importFromInstapaper()
+ {
+ # TODO gestion des articles favs
+ $html = new simple_html_dom();
+ $html->load_file('./instapaper-export.html');
+ Tools::logm('starting import from instapaper');
+
+ $read = 0;
+ $errors = array();
+ foreach($html->find('ol') as $ul)
+ {
+ foreach($ul->find('li') as $li)
+ {
+ $a = $li->find('a');
+ $url = new Url(base64_encode($a[0]->href));
+ $this->action('add', $url, 0, TRUE);
+ if ($read == '1') {
+ $sequence = '';
+ if (STORAGE == 'postgres') {
+ $sequence = 'entries_id_seq';
+ }
+ $last_id = $this->store->getLastId($sequence);
+ $this->action('toggle_archive', $url, $last_id, TRUE);
+ }
+ }
+
+ # the second <ol> is for read links
+ $read = 1;
+ }
+ $this->messages->add('s', _('import from instapaper completed'));
+ Tools::logm('import from instapaper completed');
+ Tools::redirect();
+ }
+
+ /**
+ * import from Pocket. poche needs a ./ril_export.html file
+ * @todo add the return value
+ * @return boolean
+ */
+ private function importFromPocket()
+ {
+ # TODO gestion des articles favs
+ $html = new simple_html_dom();
+ $html->load_file('./ril_export.html');
+ Tools::logm('starting import from pocket');
+
+ $read = 0;
+ $errors = array();
+ foreach($html->find('ul') as $ul)
+ {
+ foreach($ul->find('li') as $li)
+ {
+ $a = $li->find('a');
+ $url = new Url(base64_encode($a[0]->href));
+ $this->action('add', $url, 0, TRUE);
+ if ($read == '1') {
+ $sequence = '';
+ if (STORAGE == 'postgres') {
+ $sequence = 'entries_id_seq';
+ }
+ $last_id = $this->store->getLastId($sequence);
+ $this->action('toggle_archive', $url, $last_id, TRUE);
+ }
+ }
+
+ # the second <ul> is for read links
+ $read = 1;
+ }
+ $this->messages->add('s', _('import from pocket completed'));
+ Tools::logm('import from pocket completed');
+ Tools::redirect();
+ }
+
+ /**
+ * import from Readability. poche needs a ./readability file
+ * @todo add the return value
+ * @return boolean
+ */
+ private function importFromReadability()
+ {
+ # TODO gestion des articles lus / favs
+ $str_data = file_get_contents("./readability");
+ $data = json_decode($str_data,true);
+ Tools::logm('starting import from Readability');
+
+ foreach ($data as $key => $value) {
+ $url = '';
+ foreach ($value as $attr => $attr_value) {
+ if ($attr == 'article__url') {
+ $url = new Url(base64_encode($attr_value));
+ }
+ $sequence = '';
+ if (STORAGE == 'postgres') {
+ $sequence = 'entries_id_seq';
+ }
+ // if ($attr_value == 'favorite' && $attr_value == 'true') {
+ // $last_id = $this->store->getLastId($sequence);
+ // $this->store->favoriteById($last_id);
+ // $this->action('toogle_fav', $url, $last_id, TRUE);
+ // }
+ if ($attr_value == 'archive' && $attr_value == 'true') {
+ $last_id = $this->store->getLastId($sequence);
+ $this->action('toggle_archive', $url, $last_id, TRUE);
+ }
+ }
+ if ($url->isCorrect())
+ $this->action('add', $url, 0, TRUE);
+ }
+ $this->messages->add('s', _('import from Readability completed'));
+ Tools::logm('import from Readability completed');
+ Tools::redirect();
+ }
+
+ /**
+ * import datas into your poche
+ * @param string $from name of the service to import : pocket, instapaper or readability
+ * @todo add the return value
+ * @return boolean
+ */
+ public function import($from)
+ {
+ if ($from == 'pocket') {
+ return $this->importFromPocket();
+ }
+ else if ($from == 'readability') {
+ return $this->importFromReadability();
+ }
+ else if ($from == 'instapaper') {
+ return $this->importFromInstapaper();
+ }
+ }
+
+ /**
+ * export poche entries in json
+ * @return json all poche entries
+ */
+ public function export()
+ {
+ $entries = $this->store->retrieveAll($this->user->getId());
+ echo $this->tpl->render('export.twig', array(
+ 'export' => Tools::renderJson($entries),
+ ));
+ Tools::logm('export view');
+ }
+
+ /**
+ * Checks online the latest version of poche and cache it
+ * @param string $which 'prod' or 'dev'
+ * @return string latest $which version
+ */
+ private function getPocheVersion($which = 'prod')
+ {
+ $cache_file = CACHE . '/' . $which;
+
+ # checks if the cached version file exists
+ if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) {
+ $version = file_get_contents($cache_file);
+ } else {
+ $version = file_get_contents('http://static.inthepoche.com/versions/' . $which);
+ file_put_contents($cache_file, $version, LOCK_EX);
+ }
+ return $version;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <support@inthepoche.com>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+class Tools
+{
+ public static function initPhp()
+ {
+ define('START_TIME', microtime(true));
+
+ if (phpversion() < 5) {
+ die(_('Oops, it seems you don\'t have PHP 5.'));
+ }
+
+ error_reporting(E_ALL);
+
+ function stripslashesDeep($value) {
+ return is_array($value)
+ ? array_map('stripslashesDeep', $value)
+ : stripslashes($value);
+ }
+
+ if (get_magic_quotes_gpc()) {
+ $_POST = array_map('stripslashesDeep', $_POST);
+ $_GET = array_map('stripslashesDeep', $_GET);
+ $_COOKIE = array_map('stripslashesDeep', $_COOKIE);
+ }
+
+ ob_start();
+ register_shutdown_function('ob_end_flush');
+ }
+
+ public static function getPocheUrl()
+ {
+ $https = (!empty($_SERVER['HTTPS'])
+ && (strtolower($_SERVER['HTTPS']) == 'on'))
+ || (isset($_SERVER["SERVER_PORT"])
+ && $_SERVER["SERVER_PORT"] == '443'); // HTTPS detection.
+ $serverport = (!isset($_SERVER["SERVER_PORT"])
+ || $_SERVER["SERVER_PORT"] == '80'
+ || ($https && $_SERVER["SERVER_PORT"] == '443')
+ ? '' : ':' . $_SERVER["SERVER_PORT"]);
+
+ $scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]);
+
+ if (!isset($_SERVER["SERVER_NAME"])) {
+ return $scriptname;
+ }
+
+ return 'http' . ($https ? 's' : '') . '://'
+ . $_SERVER["SERVER_NAME"] . $serverport . $scriptname;
+ }
+
+ public static function redirect($url = '')
+ {
+ if ($url === '') {
+ $url = (empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER']);
+ if (isset($_POST['returnurl'])) {
+ $url = $_POST['returnurl'];
+ }
+ }
+
+ # prevent loop
+ if (empty($url) || parse_url($url, PHP_URL_QUERY) === $_SERVER['QUERY_STRING']) {
+ $url = Tools::getPocheUrl();
+ }
+
+ if (substr($url, 0, 1) !== '?') {
+ $ref = Tools::getPocheUrl();
+ if (substr($url, 0, strlen($ref)) !== $ref) {
+ $url = $ref;
+ }
+ }
+ self::logm('redirect to ' . $url);
+ header('Location: '.$url);
+ exit();
+ }
+
+ public static function getTplFile($view)
+ {
+ $tpl_file = 'home.twig';
+ switch ($view)
+ {
+ case 'install':
+ $tpl_file = 'install.twig';
+ break;
+ case 'import';
+ $tpl_file = 'import.twig';
+ break;
+ case 'export':
+ $tpl_file = 'export.twig';
+ break;
+ case 'config':
+ $tpl_file = 'config.twig';
+ break;
+ case 'view':
+ $tpl_file = 'view.twig';
+ break;
+ default:
+ break;
+ }
+ return $tpl_file;
+ }
+
+ public static function getFile($url)
+ {
+ $timeout = 15;
+ $useragent = "Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0";
+
+ if (in_array ('curl', get_loaded_extensions())) {
+ # Fetch feed from URL
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_HEADER, false);
+
+ # for ssl, do not verified certificate
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE );
+
+ # FeedBurner requires a proper USER-AGENT...
+ curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
+ curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate");
+ curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
+
+ $data = curl_exec($curl);
+ $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+ $httpcodeOK = isset($httpcode) and ($httpcode == 200 or $httpcode == 301);
+ curl_close($curl);
+ } else {
+ # create http context and add timeout and user-agent
+ $context = stream_context_create(
+ array(
+ 'http' => array(
+ 'timeout' => $timeout,
+ 'header' => "User-Agent: " . $useragent,
+ 'follow_location' => true
+ ),
+ 'ssl' => array(
+ 'verify_peer' => false,
+ 'allow_self_signed' => true
+ )
+ )
+ );
+
+ # only download page lesser than 4MB
+ $data = @file_get_contents($url, false, $context, -1, 4000000);
+
+ if (isset($http_response_header) and isset($http_response_header[0])) {
+ $httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== FALSE) or (strpos($http_response_header[0], '301 Moved Permanently') !== FALSE));
+ }
+ }
+
+ # if response is not empty and response is OK
+ if (isset($data) and isset($httpcodeOK) and $httpcodeOK) {
+
+ # take charset of page and get it
+ preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
+
+ # if meta tag is found
+ if (!empty($meta[0])) {
+ preg_match('#charset="?(.*)"#si', $meta[0], $encoding);
+ # if charset is found set it otherwise, set it to utf-8
+ $html_charset = (!empty($encoding[1])) ? strtolower($encoding[1]) : 'utf-8';
+ } else {
+ $html_charset = 'utf-8';
+ $encoding[1] = '';
+ }
+
+ # replace charset of url to charset of page
+ $data = str_replace('charset=' . $encoding[1], 'charset=' . $html_charset, $data);
+
+ return $data;
+ }
+ else {
+ return FALSE;
+ }
+ }
+
+ public static function renderJson($data)
+ {
+ header('Cache-Control: no-cache, must-revalidate');
+ header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
+ header('Content-type: application/json; charset=UTF-8');
+ echo json_encode($data);
+ exit();
+ }
+
+ public static function logm($message)
+ {
+ if (DEBUG_POCHE) {
+ $t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n";
+ file_put_contents(CACHE . '/log.txt', $t, FILE_APPEND);
+ error_log('DEBUG POCHE : ' . $message);
+ }
+ }
+
+ public static function encodeString($string)
+ {
+ return sha1($string . SALT);
+ }
+
+ public static function checkVar($var, $default = '')
+ {
+ return ((isset ($_REQUEST["$var"])) ? htmlentities($_REQUEST["$var"]) : $default);
+ }
+
+ public static function getDomain($url)
+ {
+ $pieces = parse_url($url);
+ $domain = isset($pieces['host']) ? $pieces['host'] : '';
+ if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
+ return $regs['domain'];
+ }
+
+ return FALSE;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <support@inthepoche.com>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+class Url
+{
+ public $url;
+
+ function __construct($url)
+ {
+ $this->url = base64_decode($url);
+ }
+
+ public function getUrl() {
+ return $this->url;
+ }
+
+ public function setUrl($url) {
+ $this->url = $url;
+ }
+
+ public function isCorrect()
+ {
+ $pattern = '|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i';
+
+ return preg_match($pattern, $this->url);
+ }
+
+ public function clean()
+ {
+ $url = html_entity_decode(trim($this->url));
+
+ $stuff = strpos($url,'&utm_source=');
+ if ($stuff !== FALSE)
+ $url = substr($url, 0, $stuff);
+ $stuff = strpos($url,'?utm_source=');
+ if ($stuff !== FALSE)
+ $url = substr($url, 0, $stuff);
+ $stuff = strpos($url,'#xtor=RSS-');
+ if ($stuff !== FALSE)
+ $url = substr($url, 0, $stuff);
+
+ $this->url = $url;
+ }
+
+ public function fetchContent()
+ {
+ if ($this->isCorrect()) {
+ $this->clean();
+ $html = Encoding::toUTF8(Tools::getFile($this->getUrl()));
+
+ # if Tools::getFile() if not able to retrieve HTTPS content, try the same URL with HTTP protocol
+ if (!preg_match('!^https?://!i', $this->getUrl()) && (!isset($html) || strlen($html) <= 0)) {
+ $this->setUrl('http://' . $this->getUrl());
+ $html = Encoding::toUTF8(Tools::getFile($this->getUrl()));
+ }
+
+ if (function_exists('tidy_parse_string')) {
+ $tidy = tidy_parse_string($html, array(), 'UTF8');
+ $tidy->cleanRepair();
+ $html = $tidy->value;
+ }
+
+ $parameters = array();
+ if (isset($html) and strlen($html) > 0)
+ {
+ $readability = new Readability($html, $this->getUrl());
+ $readability->convertLinksToFootnotes = CONVERT_LINKS_FOOTNOTES;
+ $readability->revertForcedParagraphElements = REVERT_FORCED_PARAGRAPH_ELEMENTS;
+
+ if($readability->init())
+ {
+ $content = $readability->articleContent->innerHTML;
+ $parameters['title'] = $readability->articleTitle->innerHTML;
+ $parameters['content'] = $content;
+
+ return $parameters;
+ }
+ }
+ }
+ else {
+ #$msg->add('e', _('error during url preparation : the link is not valid'));
+ Tools::logm($this->getUrl() . ' is not a valid url');
+ }
+
+ return FALSE;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <support@inthepoche.com>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+class User
+{
+ public $id;
+ public $username;
+ public $name;
+ public $password;
+ public $email;
+ public $config;
+
+ function __construct($user = array())
+ {
+ if ($user != array()) {
+ $this->id = $user['id'];
+ $this->username = $user['username'];
+ $this->name = $user['name'];
+ $this->password = $user['password'];
+ $this->email = $user['email'];
+ $this->config = $user['config'];
+ }
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function getUsername()
+ {
+ return $this->username;
+ }
+
+ public function setConfig($config)
+ {
+ $this->config = $config;
+ }
+
+ public function getConfigValue($name) {
+ return (isset($this->config[$name])) ? $this->config[$name] : FALSE;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <nicolas@loeuillet.org>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+# storage
+define ('STORAGE','sqlite'); # postgres, mysql, sqlite
+define ('STORAGE_SERVER', 'localhost'); # leave blank for sqlite
+define ('STORAGE_DB', 'poche'); # only for postgres & mysql
+define ('STORAGE_SQLITE', './db/poche.sqlite');
+define ('STORAGE_USER', 'postgres'); # leave blank for sqlite
+define ('STORAGE_PASSWORD', 'postgres'); # leave blank for sqlite
+
+define ('POCHE_VERSION', '1.0-beta1');
+define ('MODE_DEMO', FALSE);
+define ('DEBUG_POCHE', TRUE);
+define ('CONVERT_LINKS_FOOTNOTES', FALSE);
+define ('REVERT_FORCED_PARAGRAPH_ELEMENTS', FALSE);
+define ('DOWNLOAD_PICTURES', FALSE);
+define ('SHARE_TWITTER', TRUE);
+define ('SHARE_MAIL', TRUE);
+define ('SALT', '464v54gLLw928uz4zUBqkRJeiPY68zCX');
+define ('ABS_PATH', 'assets/');
+define ('TPL', './tpl');
+define ('LOCALE', './locale');
+define ('CACHE', './cache');
+define ('LANG', 'en_EN.UTF8');
+define ('PAGINATION', '10');
+define ('THEME', 'light');
+
+# /!\ Be careful if you change the lines below /!\
+require_once './inc/poche/User.class.php';
+require_once './inc/poche/Tools.class.php';
+require_once './inc/poche/Url.class.php';
+require_once './inc/3rdparty/class.messages.php';
+require_once './inc/poche/Poche.class.php';
+require_once './inc/3rdparty/Readability.php';
+require_once './inc/3rdparty/Encoding.php';
+require_once './inc/poche/Database.class.php';
+require_once './vendor/autoload.php';
+require_once './inc/3rdparty/simple_html_dom.php';
+require_once './inc/3rdparty/paginator.php';
+require_once './inc/3rdparty/Session.class.php';
+
+if (DOWNLOAD_PICTURES) {
+ require_once './inc/poche/pochePictures.php';
+}
+
+$poche = new Poche();
+#XSRF protection with token
+// if (!empty($_POST)) {
+// if (!Session::isToken($_POST['token'])) {
+// die(_('Wrong token'));
+// }
+// unset($_SESSION['tokens']);
+// }
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * poche, a read it later open source system
+ *
+ * @category poche
+ * @author Nicolas Lœuillet <support@inthepoche.com>
+ * @copyright 2013
+ * @license http://www.wtfpl.net/ see COPYING file
+ */
+
+/**
+ * On modifie les URLS des images dans le corps de l'article
+ */
+function filtre_picture($content, $url, $id)
+{
+ $matches = array();
+ preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
+ foreach($matches as $i => $link) {
+ $link[1] = trim($link[1]);
+ if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1])) {
+ $absolute_path = get_absolute_link($link[2],$url);
+ $filename = basename(parse_url($absolute_path, PHP_URL_PATH));
+ $directory = create_assets_directory($id);
+ $fullpath = $directory . '/' . $filename;
+ download_pictures($absolute_path, $fullpath);
+ $content = str_replace($matches[$i][2], $fullpath, $content);
+ }
+
+ }
+
+ return $content;
+}
+
+/**
+ * Retourne le lien absolu
+ */
+function get_absolute_link($relative_link, $url) {
+ /* return if already absolute URL */
+ if (parse_url($relative_link, PHP_URL_SCHEME) != '') return $relative_link;
+
+ /* queries and anchors */
+ if ($relative_link[0]=='#' || $relative_link[0]=='?') return $url . $relative_link;
+
+ /* parse base URL and convert to local variables:
+ $scheme, $host, $path */
+ extract(parse_url($url));
+
+ /* remove non-directory element from path */
+ $path = preg_replace('#/[^/]*$#', '', $path);
+
+ /* destroy path if relative url points to root */
+ if ($relative_link[0] == '/') $path = '';
+
+ /* dirty absolute URL */
+ $abs = $host . $path . '/' . $relative_link;
+
+ /* replace '//' or '/./' or '/foo/../' with '/' */
+ $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
+ for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
+
+ /* absolute URL is ready! */
+ return $scheme.'://'.$abs;
+}
+
+/**
+ * Téléchargement des images
+ */
+function download_pictures($absolute_path, $fullpath)
+{
+ $rawdata = Tools::getFile($absolute_path);
+
+ if(file_exists($fullpath)) {
+ unlink($fullpath);
+ }
+ $fp = fopen($fullpath, 'x');
+ fwrite($fp, $rawdata);
+ fclose($fp);
+}
+
+/**
+ * Crée un répertoire de médias pour l'article
+ */
+function create_assets_directory($id)
+{
+ $assets_path = ABS_PATH;
+ if(!is_dir($assets_path)) {
+ mkdir($assets_path, 0705);
+ }
+
+ $article_directory = $assets_path . $id;
+ if(!is_dir($article_directory)) {
+ mkdir($article_directory, 0705);
+ }
+
+ return $article_directory;
+}
+
+/**
+ * Suppression du répertoire d'images
+ */
+function remove_directory($directory)
+{
+ if(is_dir($directory)) {
+ $files = array_diff(scandir($directory), array('.','..'));
+ foreach ($files as $file) {
+ (is_dir("$directory/$file")) ? remove_directory("$directory/$file") : unlink("$directory/$file");
+ }
+ return rmdir($directory);
+ }
+}
\ No newline at end of file
+++ /dev/null
-<?php
-
-/**
- * RainTPL
- * -------
- * Realized by Federico Ulfo & maintained by the Rain Team
- * Distributed under GNU/LGPL 3 License
- *
- * @version 2.7.2
- */
-
-
-class RainTPL{
-
- // -------------------------
- // CONFIGURATION
- // -------------------------
-
- /**
- * Template directory
- *
- * @var string
- */
- static $tpl_dir = "tpl/";
-
-
- /**
- * Cache directory. Is the directory where RainTPL will compile the template and save the cache
- *
- * @var string
- */
- static $cache_dir = "tmp/";
-
-
- /**
- * Template base URL. RainTPL will add this URL to the relative paths of element selected in $path_replace_list.
- *
- * @var string
- */
- static $base_url = null;
-
-
- /**
- * Template extension.
- *
- * @var string
- */
- static $tpl_ext = "html";
-
-
- /**
- * Path replace is a cool features that replace all relative paths of images (<img src="...">), stylesheet (<link href="...">), script (<script src="...">) and link (<a href="...">)
- * Set true to enable the path replace.
- *
- * @var unknown_type
- */
- static $path_replace = true;
-
-
- /**
- * You can set what the path_replace method will replace.
- * Avaible options: a, img, link, script, input
- *
- * @var array
- */
- static $path_replace_list = array( 'a', 'img', 'link', 'script', 'input' );
-
-
- /**
- * You can define in the black list what string are disabled into the template tags
- *
- * @var unknown_type
- */
- static $black_list = array( '\$this', 'raintpl::', 'self::', '_SESSION', '_SERVER', '_ENV', 'eval', 'exec', 'unlink', 'rmdir' );
-
-
- /**
- * Check template.
- * true: checks template update time, if changed it compile them
- * false: loads the compiled template. Set false if server doesn't have write permission for cache_directory.
- *
- */
- static $check_template_update = true;
-
-
- /**
- * PHP tags <? ?>
- * True: php tags are enabled into the template
- * False: php tags are disabled into the template and rendered as html
- *
- * @var bool
- */
- static $php_enabled = true;
-
-
- /**
- * Debug mode flag.
- * True: debug mode is used, syntax errors are displayed directly in template. Execution of script is not terminated.
- * False: exception is thrown on found error.
- *
- * @var bool
- */
- static $debug = false;
-
- // -------------------------
-
-
- // -------------------------
- // RAINTPL VARIABLES
- // -------------------------
-
- /**
- * Is the array where RainTPL keep the variables assigned
- *
- * @var array
- */
- public $var = array();
-
- protected $tpl = array(), // variables to keep the template directories and info
- $cache = false, // static cache enabled / disabled
- $cache_id = null; // identify only one cache
-
- protected static $config_name_sum = array(); // takes all the config to create the md5 of the file
-
- // -------------------------
-
-
-
- const CACHE_EXPIRE_TIME = 3600; // default cache expire time = hour
-
-
-
- /**
- * Assign variable
- * eg. $t->assign('name','mickey');
- *
- * @param mixed $variable_name Name of template variable or associative array name/value
- * @param mixed $value value assigned to this variable. Not set if variable_name is an associative array
- */
-
- function assign( $variable, $value = null ){
- if( is_array( $variable ) )
- $this->var += $variable;
- else
- $this->var[ $variable ] = $value;
- }
-
-
-
- /**
- * Draw the template
- * eg. $html = $tpl->draw( 'demo', TRUE ); // return template in string
- * or $tpl->draw( $tpl_name ); // echo the template
- *
- * @param string $tpl_name template to load
- * @param boolean $return_string true=return a string, false=echo the template
- * @return string
- */
-
- function draw( $tpl_name, $return_string = false ){
-
- try {
- // compile the template if necessary and set the template filepath
- $this->check_template( $tpl_name );
- } catch (RainTpl_Exception $e) {
- $output = $this->printDebug($e);
- die($output);
- }
-
- // Cache is off and, return_string is false
- // Rain just echo the template
-
- if( !$this->cache && !$return_string ){
- extract( $this->var );
- include $this->tpl['compiled_filename'];
- unset( $this->tpl );
- }
-
-
- // cache or return_string are enabled
- // rain get the output buffer to save the output in the cache or to return it as string
-
- else{
-
- //----------------------
- // get the output buffer
- //----------------------
- ob_start();
- extract( $this->var );
- include $this->tpl['compiled_filename'];
- $raintpl_contents = ob_get_clean();
- //----------------------
-
-
- // save the output in the cache
- if( $this->cache )
- file_put_contents( $this->tpl['cache_filename'], "<?php if(!class_exists('raintpl')){exit;}?>" . $raintpl_contents );
-
- // free memory
- unset( $this->tpl );
-
- // return or print the template
- if( $return_string ) return $raintpl_contents; else echo $raintpl_contents;
-
- }
-
- }
-
-
-
- /**
- * If exists a valid cache for this template it returns the cache
- *
- * @param string $tpl_name Name of template (set the same of draw)
- * @param int $expiration_time Set after how many seconds the cache expire and must be regenerated
- * @return string it return the HTML or null if the cache must be recreated
- */
-
- function cache( $tpl_name, $expire_time = self::CACHE_EXPIRE_TIME, $cache_id = null ){
-
- // set the cache_id
- $this->cache_id = $cache_id;
-
- if( !$this->check_template( $tpl_name ) && file_exists( $this->tpl['cache_filename'] ) && ( time() - filemtime( $this->tpl['cache_filename'] ) < $expire_time ) )
- return substr( file_get_contents( $this->tpl['cache_filename'] ), 43 );
- else{
- //delete the cache of the selected template
- if (file_exists($this->tpl['cache_filename']))
- unlink($this->tpl['cache_filename'] );
- $this->cache = true;
- }
- }
-
-
-
- /**
- * Configure the settings of RainTPL
- *
- */
- static function configure( $setting, $value = null ){
- if( is_array( $setting ) )
- foreach( $setting as $key => $value )
- self::configure( $key, $value );
- else if( property_exists( __CLASS__, $setting ) ){
- self::$$setting = $value;
- self::$config_name_sum[ $setting ] = $value; // take trace of all config
- }
- }
-
-
-
- // check if has to compile the template
- // return true if the template has changed
- protected function check_template( $tpl_name ){
-
- if( !isset($this->tpl['checked']) ){
-
- $tpl_basename = basename( $tpl_name ); // template basename
- $tpl_basedir = strpos($tpl_name,"/") ? dirname($tpl_name) . '/' : null; // template basedirectory
- $tpl_dir = self::$tpl_dir . $tpl_basedir; // template directory
- $this->tpl['tpl_filename'] = $tpl_dir . $tpl_basename . '.' . self::$tpl_ext; // template filename
- $temp_compiled_filename = self::$cache_dir . $tpl_basename . "." . md5( $tpl_dir . serialize(self::$config_name_sum));
- $this->tpl['compiled_filename'] = $temp_compiled_filename . '.rtpl.php'; // cache filename
- $this->tpl['cache_filename'] = $temp_compiled_filename . '.s_' . $this->cache_id . '.rtpl.php'; // static cache filename
-
- // if the template doesn't exsist throw an error
- if( self::$check_template_update && !file_exists( $this->tpl['tpl_filename'] ) ){
- $e = new RainTpl_NotFoundException( 'Template '. $tpl_basename .' not found!' );
- throw $e->setTemplateFile($this->tpl['tpl_filename']);
- }
-
- // file doesn't exsist, or the template was updated, Rain will compile the template
- if( !file_exists( $this->tpl['compiled_filename'] ) || ( self::$check_template_update && filemtime($this->tpl['compiled_filename']) < filemtime( $this->tpl['tpl_filename'] ) ) ){
- $this->compileFile( $tpl_basename, $tpl_basedir, $this->tpl['tpl_filename'], self::$cache_dir, $this->tpl['compiled_filename'] );
- return true;
- }
- $this->tpl['checked'] = true;
- }
- }
-
-
- /**
- * execute stripslaches() on the xml block. Invoqued by preg_replace_callback function below
- * @access protected
- */
- protected function xml_reSubstitution($capture) {
- return "<?php echo '<?xml ".stripslashes($capture[1])." ?>'; ?>";
- }
-
- /**
- * Compile and write the compiled template file
- * @access protected
- */
- protected function compileFile( $tpl_basename, $tpl_basedir, $tpl_filename, $cache_dir, $compiled_filename ){
-
- //read template file
- $this->tpl['source'] = $template_code = file_get_contents( $tpl_filename );
-
- //xml substitution
- $template_code = preg_replace( "/<\?xml(.*?)\?>/s", "##XML\\1XML##", $template_code );
-
- //disable php tag
- if( !self::$php_enabled )
- $template_code = str_replace( array("<?","?>"), array("<?","?>"), $template_code );
-
- //xml re-substitution
- $template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code );
-
- //compile template
- $template_compiled = "<?php if(!class_exists('raintpl')){exit;}?>" . $this->compileTemplate( $template_code, $tpl_basedir );
-
-
- // fix the php-eating-newline-after-closing-tag-problem
- $template_compiled = str_replace( "?>\n", "?>\n\n", $template_compiled );
-
- // create directories
- if( !is_dir( $cache_dir ) )
- mkdir( $cache_dir, 0755, true );
-
- if( !is_writable( $cache_dir ) )
- throw new RainTpl_Exception ('Cache directory ' . $cache_dir . 'doesn\'t have write permission. Set write permission or set RAINTPL_CHECK_TEMPLATE_UPDATE to false. More details on http://www.raintpl.com/Documentation/Documentation-for-PHP-developers/Configuration/');
-
- //write compiled file
- file_put_contents( $compiled_filename, $template_compiled );
- }
-
-
-
- /**
- * Compile template
- * @access protected
- */
- protected function compileTemplate( $template_code, $tpl_basedir ){
-
- //tag list
- $tag_regexp = array( 'loop' => '(\{loop(?: name){0,1}="\${0,1}[^"]*"\})',
- 'loop_close' => '(\{\/loop\})',
- 'if' => '(\{if(?: condition){0,1}="[^"]*"\})',
- 'elseif' => '(\{elseif(?: condition){0,1}="[^"]*"\})',
- 'else' => '(\{else\})',
- 'if_close' => '(\{\/if\})',
- 'function' => '(\{function="[^"]*"\})',
- 'noparse' => '(\{noparse\})',
- 'noparse_close'=> '(\{\/noparse\})',
- 'ignore' => '(\{ignore\}|\{\*)',
- 'ignore_close' => '(\{\/ignore\}|\*\})',
- 'include' => '(\{include="[^"]*"(?: cache="[^"]*")?\})',
- 'template_info'=> '(\{\$template_info\})',
- 'function' => '(\{function="(\w*?)(?:.*?)"\})'
- );
-
- $tag_regexp = "/" . join( "|", $tag_regexp ) . "/";
-
- //split the code with the tags regexp
- $template_code = preg_split ( $tag_regexp, $template_code, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
-
- //path replace (src of img, background and href of link)
- $template_code = $this->path_replace( $template_code, $tpl_basedir );
-
- //compile the code
- $compiled_code = $this->compileCode( $template_code );
-
- //return the compiled code
- return $compiled_code;
-
- }
-
-
-
- /**
- * Compile the code
- * @access protected
- */
- protected function compileCode( $parsed_code ){
-
- //variables initialization
- $compiled_code = $open_if = $comment_is_open = $ignore_is_open = null;
- $loop_level = 0;
-
- //read all parsed code
- while( $html = array_shift( $parsed_code ) ){
-
- //close ignore tag
- if( !$comment_is_open && ( strpos( $html, '{/ignore}' ) !== FALSE || strpos( $html, '*}' ) !== FALSE ) )
- $ignore_is_open = false;
-
- //code between tag ignore id deleted
- elseif( $ignore_is_open ){
- //ignore the code
- }
-
- //close no parse tag
- elseif( strpos( $html, '{/noparse}' ) !== FALSE )
- $comment_is_open = false;
-
- //code between tag noparse is not compiled
- elseif( $comment_is_open )
- $compiled_code .= $html;
-
- //ignore
- elseif( strpos( $html, '{ignore}' ) !== FALSE || strpos( $html, '{*' ) !== FALSE )
- $ignore_is_open = true;
-
- //noparse
- elseif( strpos( $html, '{noparse}' ) !== FALSE )
- $comment_is_open = true;
-
- //include tag
- elseif( preg_match( '/\{include="([^"]*)"(?: cache="([^"]*)"){0,1}\}/', $html, $code ) ){
-
- //variables substitution
- $include_var = $this->var_replace( $code[ 1 ], $left_delimiter = null, $right_delimiter = null, $php_left_delimiter = '".' , $php_right_delimiter = '."', $loop_level );
-
- // if the cache is active
- if( isset($code[ 2 ]) ){
-
- //dynamic include
- $compiled_code .= '<?php $tpl = new '.get_class($this).';' .
- 'if( $cache = $tpl->cache( $template = basename("'.$include_var.'") ) )' .
- ' echo $cache;' .
- 'else{' .
- ' $tpl_dir_temp = self::$tpl_dir;' .
- ' $tpl->assign( $this->var );' .
- ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
- ' $tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'.
- '} ?>';
- }
- else{
-
- //dynamic include
- $compiled_code .= '<?php $tpl = new '.get_class($this).';' .
- '$tpl_dir_temp = self::$tpl_dir;' .
- '$tpl->assign( $this->var );' .
- ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
- '$tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'.
- '?>';
-
-
- }
-
- }
-
- //loop
- elseif( preg_match( '/\{loop(?: name){0,1}="\${0,1}([^"]*)"\}/', $html, $code ) ){
-
- //increase the loop counter
- $loop_level++;
-
- //replace the variable in the loop
- $var = $this->var_replace( '$' . $code[ 1 ], $tag_left_delimiter=null, $tag_right_delimiter=null, $php_left_delimiter=null, $php_right_delimiter=null, $loop_level-1 );
-
- //loop variables
- $counter = "\$counter$loop_level"; // count iteration
- $key = "\$key$loop_level"; // key
- $value = "\$value$loop_level"; // value
-
- //loop code
- $compiled_code .= "<?php $counter=-1; if( isset($var) && is_array($var) && sizeof($var) ) foreach( $var as $key => $value ){ $counter++; ?>";
-
- }
-
- //close loop tag
- elseif( strpos( $html, '{/loop}' ) !== FALSE ) {
-
- //iterator
- $counter = "\$counter$loop_level";
-
- //decrease the loop counter
- $loop_level--;
-
- //close loop code
- $compiled_code .= "<?php } ?>";
-
- }
-
- //if
- elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){
-
- //increase open if counter (for intendation)
- $open_if++;
-
- //tag
- $tag = $code[ 0 ];
-
- //condition attribute
- $condition = $code[ 1 ];
-
- // check if there's any function disabled by black_list
- $this->function_check( $tag );
-
- //variable substitution into condition (no delimiter into the condition)
- $parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
- //if code
- $compiled_code .= "<?php if( $parsed_condition ){ ?>";
-
- }
-
- //elseif
- elseif( preg_match( '/\{elseif(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){
-
- //tag
- $tag = $code[ 0 ];
-
- //condition attribute
- $condition = $code[ 1 ];
-
- //variable substitution into condition (no delimiter into the condition)
- $parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
- //elseif code
- $compiled_code .= "<?php }elseif( $parsed_condition ){ ?>";
- }
-
- //else
- elseif( strpos( $html, '{else}' ) !== FALSE ) {
-
- //else code
- $compiled_code .= '<?php }else{ ?>';
-
- }
-
- //close if tag
- elseif( strpos( $html, '{/if}' ) !== FALSE ) {
-
- //decrease if counter
- $open_if--;
-
- // close if code
- $compiled_code .= '<?php } ?>';
-
- }
-
- //function
- elseif( preg_match( '/\{function="(\w*)(.*?)"\}/', $html, $code ) ){
-
- //tag
- $tag = $code[ 0 ];
-
- //function
- $function = $code[ 1 ];
-
- // check if there's any function disabled by black_list
- $this->function_check( $tag );
-
- if( empty( $code[ 2 ] ) )
- $parsed_function = $function . "()";
- else
- // parse the function
- $parsed_function = $function . $this->var_replace( $code[ 2 ], $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
- //if code
- $compiled_code .= "<?php echo $parsed_function; ?>";
- }
-
- // show all vars
- elseif ( strpos( $html, '{$template_info}' ) !== FALSE ) {
-
- //tag
- $tag = '{$template_info}';
-
- //if code
- $compiled_code .= '<?php echo "<pre>"; print_r( $this->var ); echo "</pre>"; ?>';
- }
-
-
- //all html code
- else{
-
- //variables substitution (es. {$title})
- $html = $this->var_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
- //const substitution (es. {#CONST#})
- $html = $this->const_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
- //functions substitution (es. {"string"|functions})
- $compiled_code .= $this->func_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
- }
- }
-
- if( $open_if > 0 ) {
- $e = new RainTpl_SyntaxException('Error! You need to close an {if} tag in ' . $this->tpl['tpl_filename'] . ' template');
- throw $e->setTemplateFile($this->tpl['tpl_filename']);
- }
- return $compiled_code;
- }
-
-
- /**
- * Reduce a path, eg. www/library/../filepath//file => www/filepath/file
- * @param type $path
- * @return type
- */
- protected function reduce_path( $path ){
- $path = str_replace( "://", "@not_replace@", $path );
- $path = str_replace( "//", "/", $path );
- $path = str_replace( "@not_replace@", "://", $path );
- return preg_replace('/\w+\/\.\.\//', '', $path );
- }
-
-
-
- /**
- * replace the path of image src, link href and a href.
- * url => template_dir/url
- * url# => url
- * http://url => http://url
- *
- * @param string $html
- * @return string html sostituito
- */
- protected function path_replace( $html, $tpl_basedir ){
-
- if( self::$path_replace ){
-
- $tpl_dir = self::$base_url . self::$tpl_dir . $tpl_basedir;
-
- // reduce the path
- $path = $this->reduce_path($tpl_dir);
-
- $exp = $sub = array();
-
- if( in_array( "img", self::$path_replace_list ) ){
- $exp = array( '/<img(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<img(.*?)src=(?:")([^"]+?)#(?:")/i', '/<img(.*?)src="(.*?)"/', '/<img(.*?)src=(?:\@)([^"]+?)(?:\@)/i' );
- $sub = array( '<img$1src=@$2://$3@', '<img$1src=@$2@', '<img$1src="' . $path . '$2"', '<img$1src="$2"' );
- }
-
- if( in_array( "script", self::$path_replace_list ) ){
- $exp = array_merge( $exp , array( '/<script(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<script(.*?)src=(?:")([^"]+?)#(?:")/i', '/<script(.*?)src="(.*?)"/', '/<script(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) );
- $sub = array_merge( $sub , array( '<script$1src=@$2://$3@', '<script$1src=@$2@', '<script$1src="' . $path . '$2"', '<script$1src="$2"' ) );
- }
-
- if( in_array( "link", self::$path_replace_list ) ){
- $exp = array_merge( $exp , array( '/<link(.*?)href=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<link(.*?)href=(?:")([^"]+?)#(?:")/i', '/<link(.*?)href="(.*?)"/', '/<link(.*?)href=(?:\@)([^"]+?)(?:\@)/i' ) );
- $sub = array_merge( $sub , array( '<link$1href=@$2://$3@', '<link$1href=@$2@' , '<link$1href="' . $path . '$2"', '<link$1href="$2"' ) );
- }
-
- if( in_array( "a", self::$path_replace_list ) ){
- $exp = array_merge( $exp , array( '/<a(.*?)href=(?:")(http\:\/\/|https\:\/\/|javascript:)([^"]+?)(?:")/i', '/<a(.*?)href="(.*?)"/', '/<a(.*?)href=(?:\@)([^"]+?)(?:\@)/i' ) );
- $sub = array_merge( $sub , array( '<a$1href=@$2$3@', '<a$1href="' . self::$base_url . '$2"', '<a$1href="$2"' ) );
- }
-
- if( in_array( "input", self::$path_replace_list ) ){
- $exp = array_merge( $exp , array( '/<input(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<input(.*?)src=(?:")([^"]+?)#(?:")/i', '/<input(.*?)src="(.*?)"/', '/<input(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) );
- $sub = array_merge( $sub , array( '<input$1src=@$2://$3@', '<input$1src=@$2@', '<input$1src="' . $path . '$2"', '<input$1src="$2"' ) );
- }
-
- return preg_replace( $exp, $sub, $html );
-
- }
- else
- return $html;
-
- }
-
-
-
-
-
- // replace const
- function const_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
- // const
- return preg_replace( '/\{\#(\w+)\#{0,1}\}/', $php_left_delimiter . ( $echo ? " echo " : null ) . '\\1' . $php_right_delimiter, $html );
- }
-
-
-
- // replace functions/modifiers on constants and strings
- function func_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-
- preg_match_all( '/' . '\{\#{0,1}(\"{0,1}.*?\"{0,1})(\|\w.*?)\#{0,1}\}' . '/', $html, $matches );
-
- for( $i=0, $n=count($matches[0]); $i<$n; $i++ ){
-
- //complete tag ex: {$news.title|substr:0,100}
- $tag = $matches[ 0 ][ $i ];
-
- //variable name ex: news.title
- $var = $matches[ 1 ][ $i ];
-
- //function and parameters associate to the variable ex: substr:0,100
- $extra_var = $matches[ 2 ][ $i ];
-
- // check if there's any function disabled by black_list
- $this->function_check( $tag );
-
- $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-
-
- // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
- $is_init_variable = preg_match( "/^(\s*?)\=[^=](.*?)$/", $extra_var );
-
- //function associate to variable
- $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
-
- //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title)
- $temp = preg_split( "/\.|\[|\-\>/", $var );
-
- //variable name
- $var_name = $temp[ 0 ];
-
- //variable path
- $variable_path = substr( $var, strlen( $var_name ) );
-
- //parentesis transform [ e ] in [" e in "]
- $variable_path = str_replace( '[', '["', $variable_path );
- $variable_path = str_replace( ']', '"]', $variable_path );
-
- //transform .$variable in ["$variable"]
- $variable_path = preg_replace('/\.\$(\w+)/', '["$\\1"]', $variable_path );
-
- //transform [variable] in ["variable"]
- $variable_path = preg_replace('/\.(\w+)/', '["\\1"]', $variable_path );
-
- //if there's a function
- if( $function_var ){
-
- // check if there's a function or a static method and separate, function by parameters
- $function_var = str_replace("::", "@double_dot@", $function_var );
-
- // get the position of the first :
- if( $dot_position = strpos( $function_var, ":" ) ){
-
- // get the function and the parameters
- $function = substr( $function_var, 0, $dot_position );
- $params = substr( $function_var, $dot_position+1 );
-
- }
- else{
-
- //get the function
- $function = str_replace( "@double_dot@", "::", $function_var );
- $params = null;
-
- }
-
- // replace back the @double_dot@ with ::
- $function = str_replace( "@double_dot@", "::", $function );
- $params = str_replace( "@double_dot@", "::", $params );
-
-
- }
- else
- $function = $params = null;
-
- $php_var = $var_name . $variable_path;
-
- // compile the variable for php
- if( isset( $function ) ){
- if( $php_var )
- $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
- else
- $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $params ) )" : "$function()" ) . $php_right_delimiter;
- }
- else
- $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-
- $html = str_replace( $tag, $php_var, $html );
-
- }
-
- return $html;
-
- }
-
-
-
- function var_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-
- //all variables
- if( preg_match_all( '/' . $tag_left_delimiter . '\$(\w+(?:\.\${0,1}[A-Za-z0-9_]+)*(?:(?:\[\${0,1}[A-Za-z0-9_]+\])|(?:\-\>\${0,1}[A-Za-z0-9_]+))*)(.*?)' . $tag_right_delimiter . '/', $html, $matches ) ){
-
- for( $parsed=array(), $i=0, $n=count($matches[0]); $i<$n; $i++ )
- $parsed[$matches[0][$i]] = array('var'=>$matches[1][$i],'extra_var'=>$matches[2][$i]);
-
- foreach( $parsed as $tag => $array ){
-
- //variable name ex: news.title
- $var = $array['var'];
-
- //function and parameters associate to the variable ex: substr:0,100
- $extra_var = $array['extra_var'];
-
- // check if there's any function disabled by black_list
- $this->function_check( $tag );
-
- $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-
- // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
- $is_init_variable = preg_match( "/^[a-z_A-Z\.\[\](\-\>)]*=[^=]*$/", $extra_var );
-
- //function associate to variable
- $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
-
- //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title)
- $temp = preg_split( "/\.|\[|\-\>/", $var );
-
- //variable name
- $var_name = $temp[ 0 ];
-
- //variable path
- $variable_path = substr( $var, strlen( $var_name ) );
-
- //parentesis transform [ e ] in [" e in "]
- $variable_path = str_replace( '[', '["', $variable_path );
- $variable_path = str_replace( ']', '"]', $variable_path );
-
- //transform .$variable in ["$variable"] and .variable in ["variable"]
- $variable_path = preg_replace('/\.(\${0,1}\w+)/', '["\\1"]', $variable_path );
-
- // if is an assignment also assign the variable to $this->var['value']
- if( $is_init_variable )
- $extra_var = "=\$this->var['{$var_name}']{$variable_path}" . $extra_var;
-
-
-
- //if there's a function
- if( $function_var ){
-
- // check if there's a function or a static method and separate, function by parameters
- $function_var = str_replace("::", "@double_dot@", $function_var );
-
-
- // get the position of the first :
- if( $dot_position = strpos( $function_var, ":" ) ){
-
- // get the function and the parameters
- $function = substr( $function_var, 0, $dot_position );
- $params = substr( $function_var, $dot_position+1 );
-
- }
- else{
-
- //get the function
- $function = str_replace( "@double_dot@", "::", $function_var );
- $params = null;
-
- }
-
- // replace back the @double_dot@ with ::
- $function = str_replace( "@double_dot@", "::", $function );
- $params = str_replace( "@double_dot@", "::", $params );
- }
- else
- $function = $params = null;
-
- //if it is inside a loop
- if( $loop_level ){
- //verify the variable name
- if( $var_name == 'key' )
- $php_var = '$key' . $loop_level;
- elseif( $var_name == 'value' )
- $php_var = '$value' . $loop_level . $variable_path;
- elseif( $var_name == 'counter' )
- $php_var = '$counter' . $loop_level;
- else
- $php_var = '$' . $var_name . $variable_path;
- }else
- $php_var = '$' . $var_name . $variable_path;
-
- // compile the variable for php
- if( isset( $function ) )
- $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
- else
- $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-
- $html = str_replace( $tag, $php_var, $html );
-
-
- }
- }
-
- return $html;
- }
-
-
-
- /**
- * Check if function is in black list (sandbox)
- *
- * @param string $code
- * @param string $tag
- */
- protected function function_check( $code ){
-
- $preg = '#(\W|\s)' . implode( '(\W|\s)|(\W|\s)', self::$black_list ) . '(\W|\s)#';
-
- // check if the function is in the black list (or not in white list)
- if( count(self::$black_list) && preg_match( $preg, $code, $match ) ){
-
- // find the line of the error
- $line = 0;
- $rows=explode("\n",$this->tpl['source']);
- while( !strpos($rows[$line],$code) )
- $line++;
-
- // stop the execution of the script
- $e = new RainTpl_SyntaxException('Unallowed syntax in ' . $this->tpl['tpl_filename'] . ' template');
- throw $e->setTemplateFile($this->tpl['tpl_filename'])
- ->setTag($code)
- ->setTemplateLine($line);
- }
-
- }
-
- /**
- * Prints debug info about exception or passes it further if debug is disabled.
- *
- * @param RainTpl_Exception $e
- * @return string
- */
- protected function printDebug(RainTpl_Exception $e){
- if (!self::$debug) {
- throw $e;
- }
- $output = sprintf('<h2>Exception: %s</h2><h3>%s</h3><p>template: %s</p>',
- get_class($e),
- $e->getMessage(),
- $e->getTemplateFile()
- );
- if ($e instanceof RainTpl_SyntaxException) {
- if (null != $e->getTemplateLine()) {
- $output .= '<p>line: ' . $e->getTemplateLine() . '</p>';
- }
- if (null != $e->getTag()) {
- $output .= '<p>in tag: ' . htmlspecialchars($e->getTag()) . '</p>';
- }
- if (null != $e->getTemplateLine() && null != $e->getTag()) {
- $rows=explode("\n", htmlspecialchars($this->tpl['source']));
- $rows[$e->getTemplateLine()] = '<font color=red>' . $rows[$e->getTemplateLine()] . '</font>';
- $output .= '<h3>template code</h3>' . implode('<br />', $rows) . '</pre>';
- }
- }
- $output .= sprintf('<h3>trace</h3><p>In %s on line %d</p><pre>%s</pre>',
- $e->getFile(), $e->getLine(),
- nl2br(htmlspecialchars($e->getTraceAsString()))
- );
- return $output;
- }
-}
-
-
-/**
- * Basic Rain tpl exception.
- */
-class RainTpl_Exception extends Exception{
- /**
- * Path of template file with error.
- */
- protected $templateFile = '';
-
- /**
- * Returns path of template file with error.
- *
- * @return string
- */
- public function getTemplateFile()
- {
- return $this->templateFile;
- }
-
- /**
- * Sets path of template file with error.
- *
- * @param string $templateFile
- * @return RainTpl_Exception
- */
- public function setTemplateFile($templateFile)
- {
- $this->templateFile = (string) $templateFile;
- return $this;
- }
-}
-
-/**
- * Exception thrown when template file does not exists.
- */
-class RainTpl_NotFoundException extends RainTpl_Exception{
-}
-
-/**
- * Exception thrown when syntax error occurs.
- */
-class RainTpl_SyntaxException extends RainTpl_Exception{
- /**
- * Line in template file where error has occured.
- *
- * @var int | null
- */
- protected $templateLine = null;
-
- /**
- * Tag which caused an error.
- *
- * @var string | null
- */
- protected $tag = null;
-
- /**
- * Returns line in template file where error has occured
- * or null if line is not defined.
- *
- * @return int | null
- */
- public function getTemplateLine()
- {
- return $this->templateLine;
- }
-
- /**
- * Sets line in template file where error has occured.
- *
- * @param int $templateLine
- * @return RainTpl_SyntaxException
- */
- public function setTemplateLine($templateLine)
- {
- $this->templateLine = (int) $templateLine;
- return $this;
- }
-
- /**
- * Returns tag which caused an error.
- *
- * @return string
- */
- public function getTag()
- {
- return $this->tag;
- }
-
- /**
- * Sets tag which caused an error.
- *
- * @param string $tag
- * @return RainTpl_SyntaxException
- */
- public function setTag($tag)
- {
- $this->tag = (string) $tag;
- return $this;
- }
-}
-
-// -- end
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <support@inthepoche.com>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-class File extends Store {
- function __construct() {
-
- }
-
- public function add() {
-
- }
-
- public function retrieveOneById($id) {
-
- }
-
- public function retrieveOneByURL($url) {
-
- }
-
- public function deleteById($id) {
-
- }
-
- public function favoriteById($id) {
-
- }
-
- public function archiveById($id) {
-
- }
-
- public function getEntriesByView($view) {
-
- }
-
- public function getLastId() {
-
- }
-
- public function updateContentById($id) {
-
- }
-}
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <support@inthepoche.com>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-class Sqlite extends Store {
-
- public static $db_path = 'sqlite:./db/poche.sqlite';
- var $handle;
-
- function __construct() {
- parent::__construct();
-
- $this->handle = new PDO(self::$db_path);
- $this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- }
-
- private function getHandle() {
- return $this->handle;
- }
-
- public function isInstalled() {
- $sql = "SELECT name FROM sqlite_sequence WHERE name=?";
- $query = $this->executeQuery($sql, array('config'));
- $hasConfig = $query->fetchAll();
-
- if (count($hasConfig) == 0)
- return FALSE;
-
- if (!$this->getLogin() || !$this->getPassword())
- return FALSE;
-
- return TRUE;
- }
-
- public function install($login, $password) {
- $this->getHandle()->exec('CREATE TABLE IF NOT EXISTS "config" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , "name" VARCHAR UNIQUE, "value" BLOB)');
-
- $this->handle->exec('CREATE TABLE IF NOT EXISTS "entries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , "title" VARCHAR, "url" VARCHAR UNIQUE , "is_read" INTEGER DEFAULT 0, "is_fav" INTEGER DEFAULT 0, "content" BLOB)');
-
- if (!$this->getLogin()) {
- $sql_login = 'INSERT INTO config ( name, value ) VALUES (?, ?)';
- $params_login = array('login', $login);
- $query = $this->executeQuery($sql_login, $params_login);
- }
-
- if (!$this->getPassword()) {
- $sql_pass = 'INSERT INTO config ( name, value ) VALUES (?, ?)';
- $params_pass = array('password', $password);
- $query = $this->executeQuery($sql_pass, $params_pass);
- }
-
- return TRUE;
- }
-
- public function getLogin() {
- $sql = "SELECT value FROM config WHERE name=?";
- $query = $this->executeQuery($sql, array('login'));
- $login = $query->fetchAll();
-
- return isset($login[0]['value']) ? $login[0]['value'] : FALSE;
- }
-
- public function getPassword() {
- $sql = "SELECT value FROM config WHERE name=?";
- $query = $this->executeQuery($sql, array('password'));
- $pass = $query->fetchAll();
-
- return isset($pass[0]['value']) ? $pass[0]['value'] : FALSE;
- }
-
- public function updatePassword($password)
- {
- $sql_update = "UPDATE config SET value=? WHERE name='password'";
- $params_update = array($password);
- $query = $this->executeQuery($sql_update, $params_update);
- }
-
- private function executeQuery($sql, $params) {
- try
- {
- $query = $this->getHandle()->prepare($sql);
- $query->execute($params);
- return $query;
- }
- catch (Exception $e)
- {
- logm('execute query error : '.$e->getMessage());
- }
- }
-
- public function retrieveAll() {
- $sql = "SELECT * FROM entries ORDER BY id";
- $query = $this->executeQuery($sql, array());
- $entries = $query->fetchAll();
-
- return $entries;
- }
-
- public function retrieveOneById($id) {
- parent::__construct();
-
- $entry = NULL;
- $sql = "SELECT * FROM entries WHERE id=?";
- $params = array(intval($id));
- $query = $this->executeQuery($sql, $params);
- $entry = $query->fetchAll();
-
- return $entry[0];
- }
-
- public function getEntriesByView($view) {
- parent::__construct();
-
- switch ($_SESSION['sort'])
- {
- case 'ia':
- $order = 'ORDER BY id';
- break;
- case 'id':
- $order = 'ORDER BY id DESC';
- break;
- case 'ta':
- $order = 'ORDER BY lower(title)';
- break;
- case 'td':
- $order = 'ORDER BY lower(title) DESC';
- break;
- default:
- $order = 'ORDER BY id';
- break;
- }
-
- switch ($view)
- {
- case 'archive':
- $sql = "SELECT * FROM entries WHERE is_read=? " . $order;
- $params = array(-1);
- break;
- case 'fav' :
- $sql = "SELECT * FROM entries WHERE is_fav=? " . $order;
- $params = array(-1);
- break;
- default:
- $sql = "SELECT * FROM entries WHERE is_read=? " . $order;
- $params = array(0);
- break;
- }
-
- $query = $this->executeQuery($sql, $params);
- $entries = $query->fetchAll();
-
- return $entries;
- }
-
- public function add($url, $title, $content) {
- parent::__construct();
- $sql_action = 'INSERT INTO entries ( url, title, content ) VALUES (?, ?, ?)';
- $params_action = array($url, $title, $content);
- $query = $this->executeQuery($sql_action, $params_action);
- return $query;
- }
-
- public function deleteById($id) {
- parent::__construct();
- $sql_action = "DELETE FROM entries WHERE id=?";
- $params_action = array($id);
- $query = $this->executeQuery($sql_action, $params_action);
- return $query;
- }
-
- public function favoriteById($id) {
- parent::__construct();
- $sql_action = "UPDATE entries SET is_fav=~is_fav WHERE id=?";
- $params_action = array($id);
- $query = $this->executeQuery($sql_action, $params_action);
- }
-
- public function archiveById($id) {
- parent::__construct();
- $sql_action = "UPDATE entries SET is_read=~is_read WHERE id=?";
- $params_action = array($id);
- $query = $this->executeQuery($sql_action, $params_action);
- }
-
- public function getLastId() {
- parent::__construct();
- return $this->getHandle()->lastInsertId();
- }
-
- public function updateContentById($id) {
- parent::__construct();
- $sql_update = "UPDATE entries SET content=? WHERE id=?";
- $params_update = array($content, $id);
- $query = $this->executeQuery($sql_update, $params_update);
- }
-}
+++ /dev/null
-<?php
-/**
- * poche, a read it later open source system
- *
- * @category poche
- * @author Nicolas Lœuillet <support@inthepoche.com>
- * @copyright 2013
- * @license http://www.wtfpl.net/ see COPYING file
- */
-
-class Store {
- function __construct() {
-
- }
-
- public function getLogin() {
-
- }
-
- public function getPassword() {
-
- }
-
- public function add() {
-
- }
-
- public function retrieveAll() {
-
- }
-
- public function retrieveOneById($id) {
-
- }
-
- public function retrieveOneByURL($url) {
-
- }
-
- public function deleteById($id) {
-
- }
-
- public function favoriteById($id) {
-
- }
-
- public function archiveById($id) {
-
- }
-
- public function getEntriesByView($view) {
-
- }
-
- public function getLastId() {
-
- }
-
- public function updateContentById($id) {
-
- }
-}
* @license http://www.wtfpl.net/ see COPYING file
*/
-include dirname(__FILE__).'/inc/config.php';
+include dirname(__FILE__).'/inc/poche/config.inc.php';
-myTool::initPhp();
-
-# XSRF protection with token
-if (!empty($_POST)) {
- if (!Session::isToken($_POST['token'])) {
- die('Wrong token.');
- }
- unset($_SESSION['tokens']);
-}
-
-$ref = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
+# Parse GET & REFERER vars
+$referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
+$view = Tools::checkVar('view', 'home');
+$action = Tools::checkVar('action');
+$id = Tools::checkVar('id');
+$_SESSION['sort'] = Tools::checkVar('sort', 'id');
+$url = new Url((isset ($_GET['url'])) ? $_GET['url'] : '');
+# poche actions
if (isset($_GET['login'])) {
- // Login
- if (!empty($_POST['login']) && !empty($_POST['password'])) {
- if (Session::login($_SESSION['login'], $_SESSION['pass'], $_POST['login'], encode_string($_POST['password'] . $_POST['login']))) {
- logm('login successful');
- $msg->add('s', 'welcome in your poche!');
- if (!empty($_POST['longlastingsession'])) {
- $_SESSION['longlastingsession'] = 31536000;
- $_SESSION['expires_on'] = time() + $_SESSION['longlastingsession'];
- session_set_cookie_params($_SESSION['longlastingsession']);
- } else {
- session_set_cookie_params(0); // when browser closes
- }
- session_regenerate_id(true);
-
- MyTool::redirect($ref);
- }
- logm('login failed');
- die("Login failed !");
- } else {
- logm('login failed');
- }
+ # hello you
+ $poche->login($referer);
}
elseif (isset($_GET['logout'])) {
- logm('logout');
- Session::logout();
- MyTool::redirect();
+ # see you soon !
+ $poche->logout();
}
-elseif (isset($_GET['config'])) {
- if (isset($_POST['password']) && isset($_POST['password_repeat'])) {
- if ($_POST['password'] == $_POST['password_repeat'] && $_POST['password'] != "") {
- logm('password updated');
- if (!DEMO) {
- $store->updatePassword(encode_string($_POST['password'] . $_SESSION['login']));
- $msg->add('s', 'your password has been updated');
- }
- else {
- $msg->add('i', 'in demo mode, you can\'t update password');
- }
- }
- else
- $msg->add('e', 'your password can\'t be empty and you have to repeat it in the second field');
- }
+elseif (isset($_GET['config'])) {
+ # Update password
+ $poche->updatePassword();
+}
+elseif (isset($_GET['import'])) {
+ $import = $poche->import($_GET['from']);
+}
+elseif (isset($_GET['export'])) {
+ $poche->export();
}
-# Traitement des paramètres et déclenchement des actions
-$view = (isset ($_REQUEST['view'])) ? htmlentities($_REQUEST['view']) : 'index';
-$full_head = (isset ($_REQUEST['full_head'])) ? htmlentities($_REQUEST['full_head']) : 'yes';
-$action = (isset ($_REQUEST['action'])) ? htmlentities($_REQUEST['action']) : '';
-$_SESSION['sort'] = (isset ($_REQUEST['sort'])) ? htmlentities($_REQUEST['sort']) : 'id';
-$id = (isset ($_REQUEST['id'])) ? htmlspecialchars($_REQUEST['id']) : '';
-$url = (isset ($_GET['url'])) ? $_GET['url'] : '';
-
-$tpl->assign('isLogged', Session::isLogged());
-$tpl->assign('referer', $ref);
-$tpl->assign('view', $view);
-$tpl->assign('poche_url', myTool::getUrl());
-$tpl->assign('title', 'poche, a read it later open source system');
+# vars to send to templates
+$tpl_vars = array(
+ 'referer' => $referer,
+ 'view' => $view,
+ 'poche_url' => Tools::getPocheUrl(),
+ 'title' => _('poche, a read it later open source system'),
+ 'token' => Session::getToken(),
+);
if (Session::isLogged()) {
- action_to_do($action, $url, $id);
- display_view($view, $id, $full_head);
+ $poche->action($action, $url, $id);
+ $tpl_file = Tools::getTplFile($view);
+ $tpl_vars = array_merge($tpl_vars, $poche->displayView($view, $id));
}
else {
- $tpl->draw('login');
+ $tpl_file = 'login.twig';
}
+
+# because messages can be added in $poche->action(), we have to add this entry now (we can add it before)
+$messages = $poche->messages->display('all', FALSE);
+$tpl_vars = array_merge($tpl_vars, array('messages' => $messages));
+
+# display poche
+echo $poche->tpl->render($tpl_file, $tpl_vars);
\ No newline at end of file
--- /dev/null
+CREATE TABLE IF NOT EXISTS `config` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL,
+ `value` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `entries` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `title` varchar(255) NOT NULL,
+ `url` varchar(255) NOT NULL,
+ `is_read` tinyint(1) NOT NULL,
+ `is_fav` tinyint(1) NOT NULL,
+ `content` blob NOT NULL,
+ `user_id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `users` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `username` varchar(255) NOT NULL,
+ `password` varchar(255) NOT NULL,
+ `name` int(255) NOT NULL,
+ `email` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE IF NOT EXISTS `users_config` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `user_id` int(11) NOT NULL,
+ `name` varchar(255) NOT NULL,
+ `value` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
\ No newline at end of file
--- /dev/null
+CREATE TABLE config (
+ id bigserial primary key,
+ name varchar(255) NOT NULL,
+ value varchar(255) NOT NULL
+);
+
+CREATE TABLE entries (
+ id bigserial primary key,
+ title varchar(255) NOT NULL,
+ url varchar(255) NOT NULL,
+ is_read boolean DEFAULT false,
+ is_fav boolean DEFAULT false,
+ content TEXT,
+ user_id integer NOT NULL
+);
+
+CREATE TABLE users (
+ id bigserial primary key,
+ username varchar(255) NOT NULL,
+ password varchar(255) NOT NULL,
+ name varchar(255) NOT NULL,
+ email varchar(255) NOT NULL
+);
+
+CREATE TABLE users_config (
+ id bigserial primary key,
+ user_id integer NOT NULL,
+ name varchar(255) NOT NULL,
+ value varchar(255) NOT NULL
+);
\ No newline at end of file
--- /dev/null
+<?php
+# import script to upgrade from poche 0.3
+$db_path = 'sqlite:../db/poche.sqlite';
+$handle = new PDO($db_path);
+$handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+# Requêtes à exécuter pour mettre à jour poche.sqlite en 1.x
+
+# ajout d'un champ user_id sur la table entries
+$sql = 'ALTER TABLE entries RENAME TO tempEntries;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = 'CREATE TABLE entries (id INTEGER PRIMARY KEY, title TEXT, url TEXT, is_read NUMERIC DEFAULT 0, is_fav NUMERIC DEFAULT 0, content BLOB, user_id NUMERIC);';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = 'INSERT INTO entries (id, title, url, is_read, is_fav, content) SELECT id, title, url, is_read, is_fav, content FROM tempEntries;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+# Update tout pour mettre user_id = 1
+$sql = 'UPDATE entries SET user_id = 1;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+# Changement des flags pour les lus / favoris
+$sql = 'UPDATE entries SET is_read = 1 WHERE is_read = -1;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = 'UPDATE entries SET is_fav = 1 WHERE is_fav = -1;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+# Création de la table users
+$sql = 'CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, password TEXT, name TEXT, email TEXT);';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = 'INSERT INTO users (username) SELECT value FROM config WHERE name = "login";';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = "UPDATE users SET password = (SELECT value FROM config WHERE name = 'password')";
+$query = $handle->prepare($sql);
+$query->execute();
+
+# Création de la table users_config
+$sql = 'CREATE TABLE users_config (id INTEGER PRIMARY KEY, user_id NUMERIC, name TEXT, value TEXT);';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = 'INSERT INTO users_config (user_id, name, value) VALUES (1, "pager", "10");';
+$query = $handle->prepare($sql);
+$query->execute();
+
+$sql = 'INSERT INTO users_config (user_id, name, value) VALUES (1, "language", "en_EN.UTF8");';
+$query = $handle->prepare($sql);
+$query->execute();
+
+# Suppression de la table temporaire
+$sql = 'DROP TABLE tempEntries;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+# Vidage de la table de config
+$sql = 'DELETE FROM config;';
+$query = $handle->prepare($sql);
+$query->execute();
+
+echo 'welcome to poche 1.0 !';
\ No newline at end of file
+++ /dev/null
-/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
-//@ sourceMappingURL=jquery.min.map
-*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;
-return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l)
-}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===b.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);
\ No newline at end of file
+++ /dev/null
-/**
- * jQuery Masonry v2.1.08
- * A dynamic layout plugin for jQuery
- * The flip-side of CSS Floats
- * http://masonry.desandro.com
- *
- * Licensed under the MIT license.
- * Copyright 2012 David DeSandro
- */
-(function(e,t,n){"use strict";var r=t.event,i;r.special.smartresize={setup:function(){t(this).bind("resize",r.special.smartresize.handler)},teardown:function(){t(this).unbind("resize",r.special.smartresize.handler)},handler:function(e,t){var n=this,s=arguments;e.type="smartresize",i&&clearTimeout(i),i=setTimeout(function(){r.dispatch.apply(n,s)},t==="execAsap"?0:100)}},t.fn.smartresize=function(e){return e?this.bind("smartresize",e):this.trigger("smartresize",["execAsap"])},t.Mason=function(e,n){this.element=t(n),this._create(e),this._init()},t.Mason.settings={isResizable:!0,isAnimated:!1,animationOptions:{queue:!1,duration:500},gutterWidth:0,isRTL:!1,isFitWidth:!1,containerStyle:{position:"relative"}},t.Mason.prototype={_filterFindBricks:function(e){var t=this.options.itemSelector;return t?e.filter(t).add(e.find(t)):e},_getBricks:function(e){var t=this._filterFindBricks(e).css({position:"absolute"}).addClass("masonry-brick");return t},_create:function(n){this.options=t.extend(!0,{},t.Mason.settings,n),this.styleQueue=[];var r=this.element[0].style;this.originalStyle={height:r.height||""};var i=this.options.containerStyle;for(var s in i)this.originalStyle[s]=r[s]||"";this.element.css(i),this.horizontalDirection=this.options.isRTL?"right":"left";var o=this.element.css("padding-"+this.horizontalDirection),u=this.element.css("padding-top");this.offset={x:o?parseInt(o,10):0,y:u?parseInt(u,10):0},this.isFluid=this.options.columnWidth&&typeof this.options.columnWidth=="function";var a=this;setTimeout(function(){a.element.addClass("masonry")},0),this.options.isResizable&&t(e).bind("smartresize.masonry",function(){a.resize()}),this.reloadItems()},_init:function(e){this._getColumns(),this._reLayout(e)},option:function(e,n){t.isPlainObject(e)&&(this.options=t.extend(!0,this.options,e))},layout:function(e,t){for(var n=0,r=e.length;n<r;n++)this._placeBrick(e[n]);var i={};i.height=Math.max.apply(Math,this.colYs);if(this.options.isFitWidth){var s=0;n=this.cols;while(--n){if(this.colYs[n]!==0)break;s++}i.width=(this.cols-s)*this.columnWidth-this.options.gutterWidth}this.styleQueue.push({$el:this.element,style:i});var o=this.isLaidOut?this.options.isAnimated?"animate":"css":"css",u=this.options.animationOptions,a;for(n=0,r=this.styleQueue.length;n<r;n++)a=this.styleQueue[n],a.$el[o](a.style,u);this.styleQueue=[],t&&t.call(e),this.isLaidOut=!0},_getColumns:function(){var e=this.options.isFitWidth?this.element.parent():this.element,t=e.width();this.columnWidth=this.isFluid?this.options.columnWidth(t):this.options.columnWidth||this.$bricks.outerWidth(!0)||t,this.columnWidth+=this.options.gutterWidth,this.cols=Math.floor((t+this.options.gutterWidth)/this.columnWidth),this.cols=Math.max(this.cols,1)},_placeBrick:function(e){var n=t(e),r,i,s,o,u;r=Math.ceil(n.outerWidth(!0)/this.columnWidth),r=Math.min(r,this.cols);if(r===1)s=this.colYs;else{i=this.cols+1-r,s=[];for(u=0;u<i;u++)o=this.colYs.slice(u,u+r),s[u]=Math.max.apply(Math,o)}var a=Math.min.apply(Math,s),f=0;for(var l=0,c=s.length;l<c;l++)if(s[l]===a){f=l;break}var h={top:a+this.offset.y};h[this.horizontalDirection]=this.columnWidth*f+this.offset.x,this.styleQueue.push({$el:n,style:h});var p=a+n.outerHeight(!0),d=this.cols+1-c;for(l=0;l<d;l++)this.colYs[f+l]=p},resize:function(){var e=this.cols;this._getColumns(),(this.isFluid||this.cols!==e)&&this._reLayout()},_reLayout:function(e){var t=this.cols;this.colYs=[];while(t--)this.colYs.push(0);this.layout(this.$bricks,e)},reloadItems:function(){this.$bricks=this._getBricks(this.element.children())},reload:function(e){this.reloadItems(),this._init(e)},appended:function(e,t,n){if(t){this._filterFindBricks(e).css({top:this.element.height()});var r=this;setTimeout(function(){r._appended(e,n)},1)}else this._appended(e,n)},_appended:function(e,t){var n=this._getBricks(e);this.$bricks=this.$bricks.add(n),this.layout(n,t)},remove:function(e){this.$bricks=this.$bricks.not(e),e.remove()},destroy:function(){this.$bricks.removeClass("masonry-brick").each(function(){this.style.position="",this.style.top="",this.style.left=""});var n=this.element[0].style;for(var r in this.originalStyle)n[r]=this.originalStyle[r];this.element.unbind(".masonry").removeClass("masonry").removeData("masonry"),t(e).unbind(".masonry")}},t.fn.imagesLoaded=function(e){function u(){e.call(n,r)}function a(e){var n=e.target;n.src!==s&&t.inArray(n,o)===-1&&(o.push(n),--i<=0&&(setTimeout(u),r.unbind(".imagesLoaded",a)))}var n=this,r=n.find("img").add(n.filter("img")),i=r.length,s="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",o=[];return i||u(),r.bind("load.imagesLoaded error.imagesLoaded",a).each(function(){var e=this.src;this.src=s,this.src=e}),n};var s=function(t){e.console&&e.console.error(t)};t.fn.masonry=function(e){if(typeof e=="string"){var n=Array.prototype.slice.call(arguments,1);this.each(function(){var r=t.data(this,"masonry");if(!r){s("cannot call methods on masonry prior to initialization; attempted to call method '"+e+"'");return}if(!t.isFunction(r[e])||e.charAt(0)==="_"){s("no such method '"+e+"' for masonry instance");return}r[e].apply(r,n)})}else this.each(function(){var n=t.data(this,"masonry");n?(n.option(e||{}),n._init()):t.data(this,"masonry",new t.Mason(e,this))});return this}})(window,jQuery);
\ No newline at end of file
+++ /dev/null
-function toggle_favorite(element, id) {
- $(element).toggleClass('fav-off');
- $.ajax ({
- url: "index.php?action=toggle_fav",
- data:{id:id}
- });
-}
-
-function toggle_archive(element, id, view_article) {
- $(element).toggleClass('archive-off');
- $.ajax ({
- url: "index.php?action=toggle_archive",
- data:{id:id}
- });
- var obj = $('#entry-'+id);
-
- // on vient de la vue de l'article, donc pas de gestion de grille
- if (view_article != 1) {
- $('#content').masonry('remove',obj);
- $('#content').masonry('reloadItems');
- $('#content').masonry('reload');
- }
-}
-
-function sort_links(view, sort) {
- $.get('index.php', { view: view, sort: sort, full_head: 'no' }, function(data) {
- $('#content').html(data);
- });
-}
-
-
-// ---------- Swith light or dark view
-function setActiveStyleSheet(title) {
- var i, a, main;
- for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
- if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
- a.disabled = true;
- if(a.getAttribute("title") == title) a.disabled = false;
- }
- }
-}
-$('#themeswitch').click(function() {
- // we want the dark
- if ($('body').hasClass('light-style')) {
- setActiveStyleSheet('dark-style');
- $('body').addClass('dark-style');
- $('body').removeClass('light-style');
- $('#themeswitch').text('light');
- // we want the light
- } else if ($('body').hasClass('dark-style')) {
- setActiveStyleSheet('light-style');
- $('body').addClass('light-style');
- $('body').removeClass('dark-style');
- $('#themeswitch').text('dark');
- }
- return false;
-});
--- /dev/null
+msgid ""
+msgstr ""
+"Project-Id-Version: poche\n"
+"POT-Creation-Date: 2013-08-06 08:35+0100\n"
+"PO-Revision-Date: 2013-08-06 08:35+0100\n"
+"Last-Translator: Nicolas Lœuillet <nicolas.loeuillet@gmail.com>\n"
+"Language-Team: poche <support@inthepoche.com>\n"
+"Language: Français\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
+"X-Poedit-Basepath: /\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Poedit-SearchPath-0: /var/www/poche-i18n\n"
+
+#: /var/www/poche-i18n/index.php:43
+msgid "poche, a read it later open source system"
+msgstr "poche, a read it later open source system"
+
+#: /var/www/poche-i18n/inc/poche/Poche.class.php:101
+msgid "the link has been added successfully"
+msgstr "le lien a été ajouté avec succès"
+
+#: /var/www/poche-i18n/inc/poche/Poche.class.php:104
+msgid "error during insertion : the link wasn't added"
+msgstr "erreur durant l'insertion : le lien n'a pas été ajouté"
+
+#: /var/www/poche-i18n/inc/poche/Poche.class.php:109
+msgid "error during fetching content : the link wasn't added"
+msgstr "erreur durant la récupération du contenu : le lien n'a pas été ajouté"
+
+#: /var/www/poche-i18n/inc/poche/Poche.class.php:119
+msgid "the link has been deleted successfully"
+msgstr "le lien a été supprimé avec succès"
+
+#: /var/www/poche-i18n/inc/poche/Poche.class.php:123
+msgid "the link wasn't deleted"
+msgstr "le lien n'a pas été supprimé"
+
+#: /var/www/poche-i18n/inc/poche/Tools.class.php:18
+msgid "Oops, it seems you don't have PHP 5."
+msgstr "Oups, il semblerait que PHP 5 ne soit pas installé. "
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:32
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:70
+#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:50
+msgid "config"
+msgstr "config"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:46
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:31
+#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:26
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:34
+msgid "home"
+msgstr "accueil"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:54
+#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:34
+msgid "favorites"
+msgstr "favoris"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:62
+#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:42
+msgid "archive"
+msgstr "archives"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:74
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:76
+#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:54
+#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:56
+msgid "logout"
+msgstr "déconnexion"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:87
+msgid "Bookmarklet"
+msgstr "Bookmarklet"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:91
+msgid ""
+"Thanks to the bookmarklet, you will be able to easily add a link to your "
+"poche."
+msgstr ""
+"Grâce au bookmarklet, vous pouvez ajouter facilement un lien dans votre "
+"poche."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:93
+msgid "Have a look to this documentation:"
+msgstr "Jetez un œil à la documentation :"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:97
+msgid "Drag & drop this link to your bookmarks bar and have fun with poche."
+msgstr ""
+"Glissez / déposez ce lien dans votre barre de favoris de votre navigateur et "
+"prenez du bon temps avec poche."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:103
+msgid "poche it!"
+msgstr "poche-le !"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:108
+msgid "Updating poche"
+msgstr "Mettre à jour poche"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:113
+msgid "your version"
+msgstr "votre version"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:119
+msgid "latest stable version"
+msgstr "dernière version stable"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:125
+msgid "a more recent stable version is available."
+msgstr "une version stable plus récente est disponible."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:128
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:142
+msgid "you are up to date."
+msgstr "vous êtes à jour."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:133
+msgid "latest dev version"
+msgstr "dernière version de développement"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:139
+msgid "a more recent development version is available."
+msgstr "une version de développement plus récente est disponible."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:150
+msgid "Change your password"
+msgstr "Modifier votre mot de passe"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:157
+msgid "New password:"
+msgstr "Nouveau mot de passe :"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:161
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:171
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:60
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:68
+msgid "Password"
+msgstr "Mot de passe"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:167
+msgid "Repeat your new password:"
+msgstr "Répétez le nouveau mot de passe :"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:177
+msgid "Update"
+msgstr "Mettre à jour"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:193
+msgid "Import"
+msgstr "Import"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:197
+msgid "Please execute the import script locally, it can take a very long time."
+msgstr "Merci d'exécuter l'import en local, cela peut prendre du temps. "
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:201
+msgid "More infos in the official doc:"
+msgstr "Plus d'infos sur la documentation officielle :"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:206
+msgid "import from Pocket"
+msgstr "l'import depuis Pocket est terminé."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:210
+msgid "import from Readability"
+msgstr "l'import depuis Readability est terminé."
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:214
+msgid "import from Instapaper"
+msgstr "Import depuis Instapaper"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:220
+msgid "Export your poche datas"
+msgstr "Exporter vos données de poche"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:224
+msgid "Click here"
+msgstr "Cliquez-ici"
+
+#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:226
+msgid "to export your poche datas."
+msgstr "pour exporter vos données de poche."
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:46
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:139
+#: /var/www/poche-i18n/cache/30/97/b548692380c89d047a16cec7af79.php:22
+msgid "back to home"
+msgstr "retour à l'accueil"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:50
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:147
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:119
+msgid "toggle mark as read"
+msgstr "marquer comme lu"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:60
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:157
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:129
+msgid "toggle favorite"
+msgstr "favori"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:70
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:167
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:139
+msgid "delete"
+msgstr "supprimer"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:82
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:179
+msgid "tweet"
+msgstr "tweeter"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:93
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:190
+msgid "email"
+msgstr "envoyer par email"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:109
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:125
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:153
+msgid "original"
+msgstr "original"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:143
+msgid "back to top"
+msgstr "retour en haut de page"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:198
+msgid "this article appears wrong?"
+msgstr "cet article s'affiche mal ?"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:200
+msgid "create an issue"
+msgstr "créer un ticket"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:202
+msgid "or"
+msgstr "ou"
+
+#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:206
+msgid "contact us by mail"
+msgstr "contactez-nous par email"
+
+#: /var/www/poche-i18n/cache/88/8a/ee3b7080c13204391c14947a0c2c.php:22
+msgid "powered by"
+msgstr "propulsé par"
+
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:31
+msgid "installation"
+msgstr "installation"
+
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:42
+msgid "install your poche"
+msgstr "installez votre poche"
+
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:47
+msgid ""
+"poche is still not installed. Please fill the below form to install it. "
+"Don't hesitate to <a href='http://inthepoche.com/?pages/Documentation'>read "
+"the documentation on poche website</a>."
+msgstr ""
+"poche n'est pas encore installé. Merci de remplir les champs ci-dessous pour "
+"l'installer. N'hésitez pas à <a href='http://inthepoche.com/?pages/"
+"Documentation'>lire la documentation sur le site de poche</a>."
+
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:53
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:55
+msgid "Login"
+msgstr "Nom d'utilisateur"
+
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:67
+msgid "Repeat your password"
+msgstr "Répétez votre mot de passe"
+
+#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:74
+msgid "Install"
+msgstr "Installer"
+
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:31
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:42
+msgid "login to your poche"
+msgstr "Se connecter à votre poche"
+
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:48
+msgid "you are in demo mode, some features may be disabled."
+msgstr ""
+"vous êtes en mode démo, certaines fonctionnalités sont peut-être désactivées."
+
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:80
+msgid "Stay signed in"
+msgstr "rester connecté"
+
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:86
+msgid "(Do not check on public computers)"
+msgstr "(à ne pas cocher sur un ordinateur public)"
+
+#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:93
+msgid "Sign in"
+msgstr ""
+
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:55
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:57
+msgid "by date asc"
+msgstr "par date asc"
+
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:59
+msgid "by date"
+msgstr "par date"
+
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:65
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:67
+msgid "by date desc"
+msgstr "par date desc"
+
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:75
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:77
+msgid "by title asc"
+msgstr "par titre asc"
+
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:79
+msgid "by title"
+msgstr "par titre"
+
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:85
+#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:87
+msgid "by title desc"
+msgstr "par titre desc"
+
+#~ msgid "Please choose between Pocket & Readabilty :"
+#~ msgstr "Merci de choisir entre Pocket & Readability :"
+
+#~ msgid "Bye bye Pocket, let's go !"
+#~ msgstr "Bye bye Pocket, en route !"
+
+#~ msgid "Bye bye Readability, let's go !"
+#~ msgstr "Bye bye Readability, en route !"
+
+#~ msgid "Welcome to poche !"
+#~ msgstr "Bienvenue dans poche !"
+
+#~ msgid "Error with the import."
+#~ msgstr "Erreur durant l'import."
+
+#~ msgid "Wrong token."
+#~ msgstr "Mauvais jeton."
+
+#~ msgid "Login failed !"
+#~ msgstr "Connexion échouée."
+
+#~ msgid "your password has been updated"
+#~ msgstr "Votre mot de passe a été mis à jour. "
+
+#~ msgid "in demo mode, you can't update password"
+#~ msgstr "En mode démo, le mot de passe ne peut être modifié."
+
+#~ msgid ""
+#~ "your password can't be empty and you have to repeat it in the second field"
+#~ msgstr ""
+#~ "Votre mot de passe ne peut être vide et vous devez le répéter dans le "
+#~ "second champ."
+
+#~ msgid "error during url preparation : the link wasn't added"
+#~ msgstr "erreur durant l'insertion : le lien n'a pas été ajouté"
+
+#~ msgid "error during url preparation : the link is not valid"
+#~ msgstr "erreur durant la préparation de l'URL : le lien n'est pas valide"
+
+#~ msgid "TEST"
+#~ msgstr "NICOLAS"
--- /dev/null
+ <script type="text/javascript">
+ top["bookmarklet-url@inthepoche.com"]=""+"<!DOCTYPE html>"+"<html>"+"<head>"+"<title>poche it !</title>"+'<link rel="icon" href="{{poche_url}}tpl/img/favicon.ico" />'+"</head>"+"<body>"+"<script>"+"window.onload=function(){"+"window.setTimeout(function(){"+"history.back();"+"},250);"+"};"+"</scr"+"ipt>"+"</body>"+"</html>"
+ </script>
\ No newline at end of file
--- /dev/null
+ <footer class="w600p center mt3 smaller txtright">
+ <p>{% trans "powered by" %} <a href="http://inthepoche.com">poche</a></p>
+ {% if constant('DEBUG_POCHE') == 1 %}<p><strong>{% trans "debug mode is on so cache is off." %} {% trans "your poche version:" %}{{constant('POCHE_VERSION')}}. {% trans "storage:" %} {{constant('STORAGE')}}</strong></p>{% endif %}
+ </footer>
\ No newline at end of file
--- /dev/null
+ <link rel="shortcut icon" type="image/x-icon" href="./tpl/img/favicon.ico" />
+ <link rel="apple-touch-icon-precomposed" sizes="144x144" href="./tpl/img/apple-touch-icon-144x144-precomposed.png">
+ <link rel="apple-touch-icon-precomposed" sizes="72x72" href="./tpl/img/apple-touch-icon-72x72-precomposed.png">
+ <link rel="apple-touch-icon-precomposed" href="./tpl/img/apple-touch-icon-precomposed.png">
+ <link rel="stylesheet" href="./tpl/css/knacss.css" media="all">
+ <link rel="stylesheet" href="./tpl/css/style.css" media="all">
+ <link rel="stylesheet" href="./tpl/css/style-{{ constant('THEME') }}.css" media="all" title="{{ constant('THEME') }} theme">
+ <link rel="stylesheet" href="./tpl/css/messages.css" media="all">
+ <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
\ No newline at end of file
--- /dev/null
+ <ul id="links">
+ <li><a href="./" {% if view == 'home' %}class="current"{% endif %}>{% trans "home" %}</a></li>
+ <li><a href="./?view=fav" {% if view == 'fav' %}class="current"{% endif %}>{% trans "favorites" %}</a></li>
+ <li><a href="./?view=archive" {% if view == 'archive' %}class="current"{% endif %}>{% trans "archive" %}</a></li>
+ <li><a href="./?view=config" {% if view == 'config' %}class="current"{% endif %}>{% trans "config" %}</a></li>
+ <li><a href="./?logout" title="{% trans "logout" %}">{% trans "logout" %}</a></li>
+ </ul>
\ No newline at end of file
--- /dev/null
+ {{ messages | raw }}
\ No newline at end of file
--- /dev/null
+ <header class="w600p center mbm">
+ <h1><a href="./" title="{% trans "back to home" %}" ><img src="./tpl/img/logo.png" alt="logo poche" /></a></h1>
+ </header>
\ No newline at end of file
+++ /dev/null
- <div id="content">
- <h2>Bookmarklet</h2>
- <p>Thanks to the bookmarklet, you will be able to easily add a link to your poche. If you don't know how use a bookmarklet, <a href="http://support.mozilla.org/en-US/kb/bookmarklets-perform-common-web-page-tasks">have a look here</a>.</p>
- <p>Drag & drop this link to your bookmarks bar and have fun with poche.</p>
- <p><a style="cursor: move; border: 1px dashed grey; background: white;" title="i am a bookmarklet, use me !" href="javascript:(function(){var%20url%20=%20location.href%20||%20url;window.open('{$poche_url}?action=add&url='%20+%20encodeURIComponent(url),'_self');})();">poche it !</a></p>
-
- <h2>Password</h2>
- <form method="post" action="?config" name="loginform">
- <fieldset class="w500p">
- <div class="row">
- <label class="col w150p" for="password">New password</label>
- <input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2">
- </div>
- <div class="row">
- <label class="col w150p" for="password_repeat">Repeat your new password</label>
- <input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="Password" tabindex="3">
- </div>
- <div class="row mts txtcenter">
- <button class="bouton" type="submit" tabindex="4">Update</button>
- </div>
- </fieldset>
- <input type="hidden" name="returnurl" value="<?php echo htmlspecialchars($referer);?>">
- <input type="hidden" name="token" value="<?php echo Session::getToken(); ?>">
- </form>
- <h2>Export</h2>
- <p><a href="?view=export" target="_blank">Click here</a> to export your poche datas.</p>
- </div>
\ No newline at end of file
--- /dev/null
+{% extends "layout.twig" %}
+
+{% block title %}{% trans "config" %}{% endblock %}
+{% block menu %}
+ <ul id="links">
+ <li><a href="./" {% if view == 'home' %}class="current"{% endif %}>{% trans "home" %}</a></li>
+ <li><a href="./?view=fav" {% if view == 'fav' %}class="current"{% endif %}>{% trans "favorites" %}</a></li>
+ <li><a href="./?view=archive" {% if view == 'archive' %}class="current"{% endif %}>{% trans "archive" %}</a></li>
+ <li><a href="./?view=config" {% if view == 'config' %}class="current"{% endif %}>{% trans "config" %}</a></li>
+ <li><a href="./?logout" title="{% trans "logout" %}">{% trans "logout" %}</a></li>
+ </ul>
+{% endblock %}
+{% block content %}
+ <h2>{% trans "Bookmarklet" %}</h2>
+ <p>{% trans "Thanks to the bookmarklet, you will be able to easily add a link to your poche." %} {% trans "Have a look to this documentation:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a>.</p>
+ <p>{% trans "Drag & drop this link to your bookmarks bar and have fun with poche." %}</p>
+ <p class="txtcenter"><a ondragend="this.click();" style="cursor: move; border: 1px dashed grey; background: white; padding: 5px;" title="i am a bookmarklet, use me !" href="javascript:if(top['bookmarklet-url@inthepoche.com']){top['bookmarklet-url@inthepoche.com'];}else{(function(){var%20url%20=%20location.href%20||%20url;window.open('{{ poche_url }}?action=add&url='%20+%20btoa(url),'_self');})();void(0);}">{% trans "poche it!" %}</a></p>
+
+ <h2>{% trans "Updating poche" %}</h2>
+ <p><ul>
+ <li>{% trans "your version" %} : <strong>{{ constant('POCHE_VERSION') }}</strong></li>
+ <li>{% trans "latest stable version" %} : {{ prod }}. {% if compare_prod == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent stable version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>
+ <li>{% trans "latest dev version" %} : {{ dev }}. {% if compare_dev == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent development version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>
+ </ul>
+ </p>
+
+ <h2>{% trans "Change your password" %}</h2>
+ <form method="post" action="?config" name="loginform">
+ <fieldset class="w500p">
+ <div class="row">
+ <label class="col w150p" for="password">{% trans "New password:" %}</label>
+ <input class="col" type="password" id="password" name="password" placeholder="{% trans "Password" %}" tabindex="2">
+ </div>
+ <div class="row">
+ <label class="col w150p" for="password_repeat">{% trans "Repeat your new password:" %}</label>
+ <input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="{% trans "Password" %}" tabindex="3">
+ </div>
+ <div class="row mts txtcenter">
+ <button class="bouton" type="submit" tabindex="4">{% trans "Update" %}</button>
+ </div>
+ </fieldset>
+ <input type="hidden" name="returnurl" value="{{ referer }}">
+ <input type="hidden" name="token" value="{{ token }}">
+ </form>
+
+ <h2>{% trans "Import" %}</h2>
+ <p>{% trans "Please execute the import script locally, it can take a very long time." %}</p>
+ <p>{% trans "More infos in the official doc:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a></p>
+ <p><ul>
+ <li><a href="./?import&from=pocket">{% trans "import from Pocket" %}</a> (you must have a "ril_export.html" file on your server)</li>
+ <li><a href="./?import&from=readability">{% trans "import from Readability" %}</a> (you must have a "readability" file on your server)</li>
+ <li><a href="./?import&from=instapaper">{% trans "import from Instapaper" %}</a> (you must have a "instapaper-export.html" file on your server)</li>
+ </ul></p>
+
+ <h2>{% trans "Export your poche datas" %}</h2>
+ <p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your poche datas." %}</p>
+{% endblock %}
\ No newline at end of file
--- /dev/null
+.messages { width: 400px; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; }\r
+.messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; }\r
+/*.messages:hover a.closeMessage { visibility:visible; }*/\r
+.messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; }\r
+.messages.error { border: 1px solid #C42608; color: #c00 !important; background: #FFF0EF; }\r
+.messages.error p { background: url(../img/messages/cross.png ) no-repeat 0px 50%; color:#c00 !important; }\r
+.messages.success {background: #E0FBCC; border: 1px solid #6DC70C; } \r
+.messages.success p { background: url(../img/messages/tick.png) no-repeat 0px 50%; color: #2B6301 !important; }\r
+.messages.warning { background: #FFFCD3; border: 1px solid #EBCD41; color: #000; }\r
+.messages.warning p { background: url(../img/messages/warning.png ) no-repeat 0px 50%; color: #5F4E01; }\r
+.messages.information, .messages.info { background: #DFEBFB; border: 1px solid #82AEE7; }\r
+.messages.information p, .messages.info p { background: url(../img/messages/help.png ) no-repeat 0px 50%; color: #064393; }\r
+.messages.information a { text-decoration: underline; }
\ No newline at end of file
--- /dev/null
+
+a.back span {
+ background: url('../img/light/left.png') no-repeat;
+}
+
+a.top span {
+ background: url('../img/light/top.png') no-repeat;
+}
+
+
+a.fav span {
+ background: url('../img/light/star-on.png') no-repeat;
+}
+
+a.fav span:hover {
+ background: url('../img/light/star-off.png') no-repeat;
+}
+
+a.fav-off span {
+ background: url('../img/light/star-off.png') no-repeat;
+}
+
+a.fav-off span:hover {
+ background: url('../img/light/star-on.png') no-repeat;
+}
+
+a.archive span {
+ background: url('../img/light/checkmark-on.png') no-repeat;
+}
+
+a.archive span:hover {
+ background: url('../img/light/checkmark-off.png') no-repeat;
+}
+
+a.archive-off span {
+ background: url('../img/light/checkmark-off.png') no-repeat;
+}
+
+a.archive-off span:hover {
+ background: url('../img/light/checkmark-on.png') no-repeat;
+}
+
+a.twitter span {
+ background: url('../img/light/twitter.png') no-repeat;
+}
+
+a.email span {
+ background: url('../img/light/envelop.png') no-repeat;
+}
+
+a.delete span {
+ background: url('../img/light/remove.png') no-repeat;
+}
\ No newline at end of file
--- /dev/null
+body {
+ font-size: 16px;
+ font-family: 'Roboto', sans-serif;
+ margin: 10px;
+}
+
+header {
+ text-align: center;
+}
+
+header h1 {
+ font-size: 1.3em;
+}
+
+.bouton {
+ border-radius: 2px;
+}
+
+#main {
+ margin: 0 auto;
+}
+
+#main ul#links {
+ padding: 0;
+ list-style-type: none;
+ text-align: center;
+ font-size: 0.9em;
+}
+
+#main ul#links li {
+ display: inline;
+}
+
+#main ul#links li a.current {
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+}
+
+#main ul#sort {
+ padding: 0;
+ list-style-type: none;
+ text-align: center;
+ opacity: 0.5;
+}
+
+#main ul#sort li {
+ display: inline;
+ font-size: 0.9em;
+}
+
+#main ul#sort img:hover {
+ cursor: pointer;
+}
+
+
+#links a{
+ text-decoration: none;
+ padding: 5px 10px;
+}
+#links a:hover{
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+}
+
+/*** ***/
+/*** LINKS DISPLAY ***/
+
+#main a.tool {
+ text-decoration: none;
+ cursor: pointer;
+}
+
+#main #content {
+ margin-top: 20px;
+}
+
+#main #content h2 {
+ font-size: 1.3em;
+ text-decoration: none;
+}
+
+#main #content .entrie {
+ border-bottom: 1px dashed #222222;
+}
+
+#main .entrie ul.tools {
+ list-style-type: none;
+}
+
+#main .entrie ul.tools li {
+ /*display: inline;*/
+}
+
+.tools {
+ float: right;
+ text-align: right;
+ opacity: 0.5;
+}
+
+.tools p {
+ font-size: 0.8em;}
+
+/*
+.tools ul {
+ padding: 0; margin: 0;
+ list-style-type: none;
+}
+
+.tools ul li {
+ line-height: 20px;
+}
+
+.tools a.tool {
+ cursor: pointer;
+}*/
+
+#main .entrie .tools a.tool span, #article .tools a.tool span {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+}
+
+#main .entrie .url {
+ font-size: 13px;
+}
+
+
+/*** ***/
+/*** ARTICLE PAGE ***/
+
+#article {
+ margin: 0 auto;
+}
+#article header {
+ text-align: left;
+}
+
+#article header a {
+ text-decoration: none;
+}
+
+.vieworiginal a, .vieworiginal a:hover, .vieworiginal a:visited {
+ text-decoration: none;
+ color: #888888;
+}
+
+.backhome {
+ display: inline;
+}
+
+#article .tools {
+ position: relative;
+ display: inline;
+ top: 0px;
+ right: 0px;
+ width: 100%;
+}
+
+#article .tools ul li{
+ display: inline;
+}
+
+
+/*** GENERAL ***/
+body {
+ color: #000;
+}
+
+a, a:hover, a:visited {
+ color: #000;
+}
+
+.bouton {
+ background-color: #000;
+ color: #fff;
+ border: none;
+}
+.bouton:hover {
+ background-color: #222222;
+ color: #F1F1F1;
+}
+
+#main ul#links li a.current {
+ background-color: #000;
+ color: #fff;
+}
+
+#links a:hover{
+ background-color: #040707;
+ color: #F1F1F1;
+}
+
+
+/*** ***/
+/*** ARTICLE PAGE ***/
+
+#article header, #article article {
+ border-bottom: 1px solid #222222;
+}
+
+
+/* Pagination */
+.pagination {
+ clear: both;
+ padding-bottom: 20px;
+ padding-top: 10px;
+ text-align: right;
+}
+.pagination a {
+ border: 1px solid #D5D5D5;
+ color: #333;
+ font-size: 11px;
+ font-weight: bold;
+ height: 25px;
+ padding: 4px 8px;
+ text-decoration: none;
+ margin:2px;
+}
+.pagination a:hover, .pagination a:active {
+ background:#efefef;
+}
+.pagination span.current {
+ background-color: #ccc;
+ border: 1px solid #D5D5D5;
+ color: #000;
+ font-size: 11px;
+ font-weight: bold;
+ height: 25px;
+ padding: 4px 8px;
+ text-decoration: none;
+ margin:2px;
+}
+.pagination span.disabled {
+ border: 1px solid #EEEEEE;
+ color: #DDDDDD;
+ margin:2px;
+ padding: 4px 8px;
+ font-size: 11px;
+ font-weight: bold;
+}
+
+footer {
+ clear: both;
+}
\ No newline at end of file
+++ /dev/null
- <div id="content">
- {loop="entries"}
- <div id="entry-{$value.id}" class="entrie mb2">
- <span class="content">
- <h2 class="h6-like">
- <a href="index.php?&view=view&id={$value.id}">{$value.title}</a>
- </h2>
- <div class="tools">
- <ul>
- <li><a title="toggle mark as read" class="tool archive {if="$value.is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$value.id})"><span></span></a></li>
- <li><a title="toggle favorite" class="tool fav {if="$value.is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$value.id})"><span></span></a></li>
- <li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;"><input type="hidden" name="token" id="token" value="<?php echo Session::getToken(); ?>" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="view" name="view" value="{$view}" /><input type="hidden" id="id" name="id" value="{$value.id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
- </ul>
- </div>
- </span>
- </div>
- {/loop}
- </div>
\ No newline at end of file
+++ /dev/null
-export {$export}
\ No newline at end of file
--- /dev/null
+{{ export }}
\ No newline at end of file
+++ /dev/null
- </div>
- <footer class="mr2 mt3 smaller">
- <p>powered by <a href="http://inthepoche.com">poche</a><br />follow us on <a href="https://twitter.com/getpoche" title="follow us on twitter">twitter</a></p>
- </footer>
-
- </body>
-</html>
\ No newline at end of file
+++ /dev/null
-<!DOCTYPE html>
-<!--[if lte IE 6]> <html class="no-js ie6 ie67 ie678" lang="en"> <![endif]-->
-<!--[if lte IE 7]> <html class="no-js ie7 ie67 ie678" lang="en"> <![endif]-->
-<!--[if IE 8]> <html class="no-js ie8 ie678" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
-<html>
- <head>
- <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=10">
- <title>{$title}</title>
- <link rel="shortcut icon" type="image/x-icon" href="./img/favicon.ico" />
- <link rel="apple-touch-icon-precomposed" sizes="144x144" href="./img/apple-touch-icon-144x144-precomposed.png">
- <link rel="apple-touch-icon-precomposed" sizes="72x72" href="./img/apple-touch-icon-72x72-precomposed.png">
- <link rel="apple-touch-icon-precomposed" href="./img/apple-touch-icon-precomposed.png">
- <link rel="stylesheet" href="./css/knacss.css" media="all">
- <link rel="stylesheet" href="./css/style.css" media="all">
- <!-- Light Theme -->
- <link rel="stylesheet" href="./css/style-light.css" media="all" title="light-style">
- <!-- Dark Theme -->
- <link rel="alternate stylesheet" href="./css/style-dark.css" media="all" title="dark-style">
- </head>
\ No newline at end of file
+++ /dev/null
- <body class="light-style">
- <header>
- <h1><a href="index.php"><img src="./img/logo.png" alt="logo poche" /></a>poche</h1>
- </header>
- <div id="main">
- <ul id="links">
- <li><a href="index.php" {if="$view == 'index'"}class="current"{/if}>home</a></li>
- <li><a href="?view=fav" {if="$view == 'fav'"}class="current"{/if}>favorites</a></li>
- <li><a href="?view=archive" {if="$view == 'archive'"}class="current"{/if}>archive</a></li>
- <li><a href="?view=config" {if="$view == 'config'"}class="current"{/if}>config</a></li>
- <li><a href="?logout" title="Logout">logout</a></li>
- </ul>
- {if condition="isset($entries)"}
- <ul id="sort">
- <li><img src="img/up.png" onclick="sort_links('{$view}', 'ia');" title="by date asc" /> by date <img src="img/down.png" onclick="sort_links('{$view}', 'id');" title="by date desc" /></li>
- <li><img src="img/up.png" onclick="sort_links('{$view}', 'ta');" title="by title asc" /> by title <img src="img/down.png" onclick="sort_links('{$view}', 'td');" title="by title desc" /></li>
- </ul>
- {/if}
- {include="messages"}
\ No newline at end of file
--- /dev/null
+{% extends "layout.twig" %}
+{% block title %}{% trans "home" %}{% endblock %}
+{% block menu %}
+{% include '_menu.twig' %}
+{% endblock %}
+{% block precontent %}
+ <ul id="sort">
+ <li><a href="./?sort=ia&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/top.png" alt="{% trans "by date asc" %}" title="{% trans "by date asc" %}" /></a> {% trans "by date" %} <a href="./?sort=id&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/down.png" alt="{% trans "by date desc" %}" title="{% trans "by date desc" %}" /></a></li>
+ <li><a href="./?sort=ta&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/top.png" alt="{% trans "by title asc" %}" title="{% trans "by title asc" %}" /></a> {% trans "by title" %} <a href="./?sort=td&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/down.png" alt="{% trans "by title desc" %}" title="{% trans "by title desc" %}" /></a></li>
+ </ul>
+{% endblock %}
+{% block content %}
+ {{ page_links | raw }}
+ {% for entry in entries %}
+ <div id="entry-{{ entry.id|e }}" class="entrie">
+ <h2><a href="index.php?view=view&id={{ entry.id|e }}">{{ entry.title|e }}</a></h2>
+ <ul class="tools">
+ <li>
+ <a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
+ <li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
+ <li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
+ </li>
+ </ul>
+ <p>{{ entry.content|striptags|slice(0, 300) }}...</p>
+ <p class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></p>
+ </div>
+ {% endfor %}
+ {{ page_links | raw }}
+{% endblock %}
\ No newline at end of file
+++ /dev/null
-{include="head"}
- <body class="light-style">
- <header>
- <h1><a href="index.php"><img src="./img/logo.png" alt="logo poche" /></a>poche</h1>
- </header>
- <div id="main">
- <form method="post" action="?install" name="loginform">
- <fieldset class="w500p center">
- <h2 class="mbs txtcenter">install your poche</h2>
- <div class="row">
- <label class="col w150p" for="login">Login</label>
- <input class="col" type="text" id="login" name="login" placeholder="Login" tabindex="1" autofocus />
- </div>
- <div class="row">
- <label class="col w150p" for="password">Password</label>
- <input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2">
- </div>
- <div class="row">
- <label class="col w150p" for="password_repeat">Repeat your password</label>
- <input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="Password" tabindex="3">
- </div>
- <div class="row mts txtcenter">
- <button class="bouton" type="submit" tabindex="4">Install</button>
- </div>
- </fieldset>
- <input type="hidden" name="returnurl" value="<?php echo htmlspecialchars($referer);?>">
- <input type="hidden" name="token" value="<?php echo Session::getToken(); ?>">
- </form>
-
-{include="footer"}
--- /dev/null
+{% extends "layout.twig" %}
+{% block title %}{% trans "installation" %}{% endblock %}
+{% block content %}
+ <form method="post" action="?install" name="loginform">
+ <fieldset class="w500p center">
+ <h2 class="mbs txtcenter">{% trans "install your poche" %}</h2>
+ <p>
+ {% trans "poche is still not installed. Please fill the below form to install it. Don't hesitate to <a href='http://inthepoche.com/?pages/Documentation'>read the documentation on poche website</a>." %}
+ </p>
+ <div class="row">
+ <label class="col w150p" for="login">{% trans "Login" %}</label>
+ <input class="col" type="text" id="login" name="login" placeholder="Login" tabindex="1" autofocus />
+ </div>
+ <div class="row">
+ <label class="col w150p" for="password">{% trans "Password" %}</label>
+ <input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2">
+ </div>
+ <div class="row">
+ <label class="col w150p" for="password_repeat">{% trans "Repeat your password" %}</label>
+ <input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="Password" tabindex="3">
+ </div>
+ <div class="row mts txtcenter">
+ <button class="bouton" type="submit" tabindex="4">{% trans "Install" %}</button>
+ </div>
+ </fieldset>
+ <input type="hidden" name="token" value="{{ token }}">
+ </form>
+{% endblock %}
\ No newline at end of file
+++ /dev/null
- <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
- <script type="text/javascript" src="js/poche.js"></script>
-
- {if="$load_all_js == '1'"}
- <script type="text/javascript" src="js/jquery.masonry.min.js"></script>
- <script type="text/javascript">
- $( window ).load( function()
- {
- var columns = 3,
- setColumns = function() { columns = $( window ).width() > 640 ? 3 : $( window ).width() > 320 ? 2 : 1; };
-
- setColumns();
- $( window ).resize( setColumns );
-
- $( '#content' ).masonry(
- {
- itemSelector: '.entrie',
- columnWidth: function( containerWidth ) { return containerWidth / columns; }
- });
- });
- </script>
- {/if}
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html>
+<!--[if lte IE 6]> <html class="no-js ie6 ie67 ie678" lang="en"> <![endif]-->
+<!--[if lte IE 7]> <html class="no-js ie7 ie67 ie678" lang="en"> <![endif]-->
+<!--[if IE 8]> <html class="no-js ie8 ie678" lang="en"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=10">
+ <title>{% block title %}{% endblock %} - poche</title>
+ {% include '_head.twig' %}
+ {% include '_bookmarklet.twig' %}
+ </head>
+ <body>
+ {% include '_top.twig' %}
+ <div id="main">
+ {% block menu %}{% endblock %}
+ {% block precontent %}{% endblock %}
+ {% block messages %}
+ {% include '_messages.twig' %}
+ {% endblock %}
+ <div id="content" class="w600p center">
+ {% block content %}{% endblock %}
+ </div>
+ </div>
+ {% include '_footer.twig' %}
+ </body>
+</html>
\ No newline at end of file
+++ /dev/null
-{include="head"}
- <body class="light-style">
- <header>
- <h1><a href="index.php"><img src="./img/logo.png" alt="logo poche" /></a>poche</h1>
- </header>
- <div id="main">
- <form method="post" action="?login" name="loginform">
- <fieldset class="w500p center">
- <h2 class="mbs txtcenter">login to your poche</h2>
- <div class="row">
- <label class="col w150p" for="login">Login</label>
- <input class="col" type="text" id="login" name="login" placeholder="Login" tabindex="1" autofocus />
- </div>
- <div class="row">
- <label class="col w150p" for="password">Password</label>
- <input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2">
- </div>
- <div class="row">
- <label class="col w150p">Stay signed in</label>
- <div class="col">
- <input type="checkbox" name="longlastingsession" tabindex="3">
- <small class="inbl">(Do not check on public computers)</small>
- </div>
- </div>
- <div class="row mts txtcenter">
- <button class="bouton" type="submit" tabindex="4">Sign in</button>
- </div>
- </fieldset>
- <input type="hidden" name="returnurl" value="<?php echo htmlspecialchars($referer);?>">
- <input type="hidden" name="token" value="<?php echo Session::getToken(); ?>">
- </form>
-
-{include="footer"}
--- /dev/null
+{% extends "layout.twig" %}
+
+{% block title %}{% trans "login to your poche" %}{% endblock %}
+{% block content %}
+ <form method="post" action="?login" name="loginform">
+ <fieldset class="w500p center">
+ <h2 class="mbs txtcenter">{% trans "login to your poche" %}</h2>
+ {% if constant('MODE_DEMO') == 1 %}<p>{% trans "you are in demo mode, some features may be disabled." %}</p>{% endif %}
+ <div class="row">
+ <label class="col w150p" for="login">{% trans "Login" %}</label>
+ <input class="col" type="text" id="login" name="login" placeholder="Login" tabindex="1" autofocus {% if constant('MODE_DEMO') == 1 %}value="poche"{% endif %} />
+ </div>
+
+ <div class="row">
+ <label class="col w150p" for="password">{% trans "Password" %}</label>
+ <input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2" {% if constant('MODE_DEMO') == 1 %}value="poche"{% endif %} />
+ </div>
+ <div class="row">
+ <label class="col w150p" for="longlastingsession">{% trans "Stay signed in" %}</label>
+ <div class="col">
+ <input type="checkbox" id="longlastingsession" name="longlastingsession" tabindex="3">
+ <small class="inbl">{% trans "(Do not check on public computers)" %}</small>
+ </div>
+ </div>
+ <div class="row mts txtcenter">
+ <button class="bouton" type="submit" tabindex="4">{% trans "Login" %}</button>
+ </div>
+ </fieldset>
+ <input type="hidden" name="returnurl" value="{{ referer }}">
+ <input type="hidden" name="token" value="{{ token }}">
+ </form>
+{% endblock %}
\ No newline at end of file
+++ /dev/null
-<div id="messages"><?php echo $msg->display(); ?></div>
\ No newline at end of file
+++ /dev/null
-<!DOCTYPE html>
-<!--[if lte IE 6]> <html class="no-js ie6 ie67 ie678" lang="en"> <![endif]-->
-<!--[if lte IE 7]> <html class="no-js ie7 ie67 ie678" lang="en"> <![endif]-->
-<!--[if IE 8]> <html class="no-js ie8 ie678" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
-<html>
- <head>
- <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=10">
- <title>{$title}</title>
- <link rel="shortcut icon" type="image/x-icon" href="./img/favicon.ico" />
- <link rel="apple-touch-icon-precomposed" sizes="144x144" href="./img/apple-touch-icon-144x144-precomposed.png">
- <link rel="apple-touch-icon-precomposed" sizes="72x72" href="./img/apple-touch-icon-72x72-precomposed.png">
- <link rel="apple-touch-icon-precomposed" href="./img/apple-touch-icon-precomposed.png">
- <link rel="stylesheet" href="./css/knacss.css" media="all">
- <link rel="stylesheet" href="./css/style.css" media="all">
- <!-- Light Theme -->
- <link rel="stylesheet" href="./css/style-light.css" media="all" title="light-style">
- <!-- Dark Theme -->
- <link rel="alternate stylesheet" href="./css/style-dark.css" media="all" title="dark-style">
- </head>
- <body class="article light-style">
- <div id="article" class="w600p">
- <div class="backhome">
- <a href="index.php" title="back to home">←</a>
- </div>
- <div class="tools">
- <ul>
- <li><a title="toggle mark as read" class="tool archive {if="$is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$id})"><span></span></a></li>
- <li><a href="#" id="themeswitch">dark</a></li>
- <li><a title="toggle favorite" class="tool fav {if="$is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$id})"><span></span></a></li>
- <li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;" action="index.php"><input type="hidden" name="token" id="token" value="<?php echo Session::getToken(); ?>" /><input type="hidden" id="view" name="view" value="index" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="id" name="id" value="{$id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
- <li><a href="?logout" title="Logout">logout</a></li>
- </ul>
- </div>
- <header class="mbm">
- <h1><a href="{$url}">{$title}</a></h1>
- <div class="vieworiginal txtright small"><a href="{$url}" target="_blank" title="original : {$title}">view original</a></div>
- </header>
- {include="messages"}
- <article>
- <div id="readityourselfcontent">
- {$content}
- </div>
- </article>
- <div class="vieworiginal txtright small"><a href="{$url}" target="_blank" title="original : {$title}">view original</a></div>
- <div class="backhome">
- <a href="index.php" title="back to home">←</a>
- </div>
-
- {include="js"}
- {include="footer"}
\ No newline at end of file
--- /dev/null
+{% extends "layout.twig" %}
+{% block title %}{% trans "home" %}{% endblock %}
+{% block content %}
+ <div id="article">
+ <div class="tools">
+ <ul class="tools">
+ <li>
+ <li><a href="{{ referer }}" title="{% trans "back to home" %}" class="tool back"><span></span></a></li>
+ <a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
+ <li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
+ <li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
+ {% if constant('SHARE_TWITTER') == 1 %}<li><a href="https://twitter.com/home?status={{entry.title}}%20{{ entry.url|e }}%20via%20@getpoche" target="_blank" class="tool twitter" title="{% trans "tweet" %}"><span></span></a></li>{% endif %}
+ {% if constant('SHARE_MAIL') == 1 %}<li><a href="mailto:?subject={{ entry.title|e }}&body={{ entry.url|e }} via @getpoche" class="tool email" title="{% trans "email" %}"><span></span></a></li>{% endif %}
+ </li>
+ </ul>
+ </div>
+ <header class="mbm">
+ <h1>{{ entry.title|e }}</h1>
+ <div class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></div>
+ </header>
+ <article>
+ {{ content | raw }}
+ <div class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></div>
+ </article>
+ <div class="tools">
+ <ul class="tools">
+ <li>
+ <li><a href="{{ referer }}" title="{% trans "back to home" %}" class="tool back"><span></span></a></li>
+ <li><a href="#" title="{% trans "back to top" %}" class="tool top"><span></span></a></li>
+ <a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
+ <li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
+ <li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
+ {% if constant('SHARE_TWITTER') == 1 %}<li><a href="https://twitter.com/home?status={{entry.title}}%20{{ entry.url|e }}%20via%20@getpoche" target="_blank" class="tool twitter" title="{% trans "tweet" %}"><span></span></a></li>{% endif %}
+ {% if constant('SHARE_MAIL') == 1 %}<li><a href="mailto:?subject={{ entry.title|e }}&body={{ entry.url|e }} via @getpoche" class="tool email" title="{% trans "email" %}"><span></span></a></li>{% endif %}
+ </li>
+ </ul>
+ <p>{% trans "this article appears wrong?" %} <a href="https://github.com/inthepoche/poche/issues/new">{% trans "create an issue" %}</a> {% trans "or" %} <a href="mailto:support@inthepoche.com?subject=Wrong display in poche&body={{ entry.url|e }}">{% trans "contact us by mail" %}</a></p>
+ </div>
+ </div>
+{% endblock %}
\ No newline at end of file