summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2010-11-20 02:52:28 +0100
committerÉtienne Loks <etienne.loks@peacefrogs.net>2010-11-20 02:52:28 +0100
commit63afe4e84cd3be5284a7126264c06ce87d191bc0 (patch)
tree1ba8afc27b5aee7cdfb1d4abcde142b260c635b0
parentf65df4be0383b60b6a500f76f6405a6c5621df23 (diff)
parent00697996e885044314cc297b72aaa86d69d2a219 (diff)
downloadChimère-63afe4e84cd3be5284a7126264c06ce87d191bc0.tar.bz2
Chimère-63afe4e84cd3be5284a7126264c06ce87d191bc0.zip
Merge branch 'master' into carte-ouverte
Conflicts: .gitignore chimere/main/actions.py chimere/urls.py
-rw-r--r--.gitmodules3
-rw-r--r--chimere/initial_data.json4
-rw-r--r--chimere/locale/fr/LC_MESSAGES/django.po273
-rw-r--r--chimere/main/actions.py14
-rw-r--r--chimere/main/admin.py18
-rw-r--r--chimere/main/forms.py50
-rw-r--r--chimere/main/models.py121
-rw-r--r--chimere/main/views.py47
-rw-r--r--chimere/main/widgets.py45
-rw-r--r--chimere/rss/__init__.py1
-rw-r--r--chimere/rss/feeds.py234
-rw-r--r--chimere/rss/templates/rss.html73
-rw-r--r--chimere/rss/templates/rss_descr.html7
-rw-r--r--chimere/rss/templates/rss_title.html2
-rw-r--r--chimere/rss/urls.py42
-rw-r--r--chimere/rss/views.py140
-rwxr-xr-xchimere/scripts/upgrade.py112
-rw-r--r--chimere/settings.py.example32
m---------chimere/static/jquery/bsmSelect0
-rw-r--r--chimere/static/jquery/css/jquery.bsmselect.custom.css45
-rw-r--r--chimere/static/jquery/jquery-1.4.4.min.js167
-rw-r--r--chimere/static/styles.css1
-rw-r--r--chimere/templates/404.html5
-rw-r--r--chimere/templates/500.html5
-rw-r--r--chimere/templates/detail.html7
-rw-r--r--chimere/templates/edit.html36
-rw-r--r--chimere/templates/edit_route.html36
-rw-r--r--chimere/urls.py52
-rw-r--r--docs/en/INSTALL.t2t4
-rw-r--r--docs/en/UPGRADE.t2t2
30 files changed, 1361 insertions, 217 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..8905b55
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "chimere/static/jquery/bsmSelect"]
+ path = chimere/static/jquery/bsmSelect
+ url = git://github.com/vicb/bsmSelect.git
diff --git a/chimere/initial_data.json b/chimere/initial_data.json
index b88b17b..f181244 100644
--- a/chimere/initial_data.json
+++ b/chimere/initial_data.json
@@ -49,5 +49,5 @@
{"pk": 22, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 8}},
{"pk": 23, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 8}},
{"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 8}},
- {"pk": 1, "model": "auth.group", "fields": {"name": "Moderator", "permissions": [37, 40, 38, 41, 39, 42]}},
- {"pk": 2, "model": "auth.group", "fields": {"name": "Application administrator", "permissions": [43, 28, 31, 37, 25, 40, 34, 44, 29, 32, 38, 26, 41, 35, 45, 30, 33, 39, 27, 42, 36]}}]
+ {"pk": 1, "model": "auth.group", "fields": {"name": "Moderator", "permissions": [37, 40, 38, 41, 39, 42, 49, 50, 51]}},
+ {"pk": 2, "model": "auth.group", "fields": {"name": "Application administrator", "permissions": [49, 50, 51, 43, 28, 31, 37, 25, 40, 34, 44, 29, 32, 38, 26, 41, 35, 45, 30, 33, 39, 27, 42, 36]}}]
diff --git a/chimere/locale/fr/LC_MESSAGES/django.po b/chimere/locale/fr/LC_MESSAGES/django.po
index b6eace0..8563abf 100644
--- a/chimere/locale/fr/LC_MESSAGES/django.po
+++ b/chimere/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-04-06 01:19+0200\n"
+"POT-Creation-Date: 2010-11-20 02:16+0100\n"
"PO-Revision-Date: 2010-03-20 20:00+0100\n"
"Last-Translator: Étienne Loks <etienne.loks@peacefrogs.net>\n"
"MIME-Version: 1.0\n"
@@ -26,183 +26,225 @@ msgstr "Participer"
msgid "Add a new point of interest"
msgstr "Ajout d'un point remarquable"
-#: main/actions.py:35 templates/edit_route.html:8
+#: main/actions.py:35 templates/edit_route.html:15
msgid "Add a new route"
msgstr "Ajout d'un nouveau trajet"
-#: main/actions.py:37
+#: main/actions.py:39
+msgid "RSS feeds"
+msgstr "Flux RSS"
+
+#: main/actions.py:42
msgid "Contact us"
msgstr "Nous contacter"
-#: main/forms.py:53
+#: main/forms.py:72
msgid "New submission for"
msgstr "Nouvelle proposition pour"
-#: main/forms.py:54
+#: main/forms.py:73
#, python-format
msgid "The new item \"%s\" has been submited in the category: "
msgstr "Le nouvel élément « %s » a été proposé dans la catégorie : "
-#: main/forms.py:56
+#: main/forms.py:75
msgid "To valid, precise or unvalid this item: "
msgstr "Pour valider, préciser ou rejeter cet élément : "
-#: main/forms.py:65
+#: main/forms.py:84
msgid "Email (optional)"
msgstr "Courriel (optionnel) "
-#: main/forms.py:66
+#: main/forms.py:85
msgid "Object"
msgstr "Objet"
-#: main/forms.py:226 main/models.py:407
+#: main/forms.py:143
+msgid "End date has been set with no start date"
+msgstr "Une date de fin a été donnée sans date de début"
+
+#: main/forms.py:268 main/models.py:449
msgid "Area"
msgstr "Zone"
-#: main/models.py:36 main/models.py:88 main/models.py:109 main/models.py:122
-#: main/models.py:134 main/models.py:182 main/models.py:250 main/models.py:388
-#: main/models.py:433
+#: main/models.py:37 main/models.py:90 main/models.py:111 main/models.py:124
+#: main/models.py:138 main/models.py:188 main/models.py:272 main/models.py:433
+#: main/models.py:475
msgid "Name"
msgstr "Nom"
-#: main/models.py:37 main/models.py:110 main/models.py:135 main/models.py:188
-#: main/models.py:256 main/models.py:395 main/models.py:435
+#: main/models.py:38 main/models.py:112 main/models.py:139 main/models.py:196
+#: main/models.py:280 main/models.py:437 main/models.py:477
msgid "Available"
msgstr "Disponible"
-#: main/models.py:38
+#: main/models.py:39
msgid "Date"
msgstr "Date"
-#: main/models.py:44
+#: main/models.py:45 main/models.py:46
msgid "News"
msgstr "Nouvelle"
-#: main/models.py:49
+#: main/models.py:51
msgid "Parameters"
-msgstr ""
+msgstr "Paramètres"
-#: main/models.py:53
+#: main/models.py:55
msgid "TinyUrl"
-msgstr ""
+msgstr "Mini-url"
-#: main/models.py:92 main/models.py:99 main/models.py:139
+#: main/models.py:94 main/models.py:101 main/models.py:142
msgid "Color theme"
msgstr "Thème de couleur"
-#: main/models.py:97
+#: main/models.py:99
msgid "Code"
msgstr "Code"
-#: main/models.py:98 main/models.py:111 main/models.py:141 main/models.py:394
-#: main/models.py:434
+#: main/models.py:100 main/models.py:113 main/models.py:144 main/models.py:436
+#: main/models.py:476
msgid "Order"
msgstr "Ordre"
-#: main/models.py:104
+#: main/models.py:106
msgid "Color"
msgstr "Couleur"
-#: main/models.py:117 main/models.py:133 templates/edit.html:18
-#: templates/edit_route.html:17
+#: main/models.py:119 main/models.py:137
msgid "Category"
msgstr "Catégorie"
-#: main/models.py:123 main/models.py:185 main/models.py:253
-#: templates/edit.html:37 templates/edit_route.html:37
+#: main/models.py:125 main/models.py:191 main/models.py:275
+#: templates/edit.html:35 templates/edit_route.html:35
msgid "Image"
msgstr "Image"
-#: main/models.py:128 main/models.py:138
+#: main/models.py:127 main/models.py:193 main/models.py:277
+msgid "Height"
+msgstr "Hauteur"
+
+#: main/models.py:128 main/models.py:194 main/models.py:278
+msgid "Width"
+msgstr "Largeur"
+
+#: main/models.py:132 main/models.py:141
msgid "Icon"
msgstr "Icône"
-#: main/models.py:142
+#: main/models.py:145
msgid "Marker"
msgstr "Point d'intérêt"
-#: main/models.py:143 main/models.py:252 main/models.py:269
-#: templates/edit_route.html:31
+#: main/models.py:146 main/models.py:274 main/models.py:300
+#: templates/edit_route.html:29
msgid "Route"
msgstr "Trajet"
-#: main/models.py:144
+#: main/models.py:147
msgid "Both"
msgstr "Mixte"
-#: main/models.py:145
+#: main/models.py:148
msgid "Item type"
msgstr "Type d'élément"
-#: main/models.py:150 main/models.py:183 main/models.py:251
+#: main/models.py:153
msgid "Subcategory"
msgstr "Sous-catégorie"
-#: main/models.py:184
+#: main/models.py:190
msgid "Localisation"
msgstr "Localisation"
-#: main/models.py:187 main/models.py:255
+#: main/models.py:195 main/models.py:279
msgid "Submited"
msgstr "Soumis"
-#: main/models.py:189 main/models.py:257
+#: main/models.py:197 main/models.py:281
msgid "Disabled"
msgstr "Désactivé"
-#: main/models.py:193 main/models.py:261
+#: main/models.py:201 main/models.py:292
msgid "Status"
msgstr "État"
-#: main/models.py:201 main/models.py:457
+#: main/models.py:203 main/models.py:286 templates/edit.html:41
+#: templates/edit_route.html:41
+msgid "Start date"
+msgstr "Date de début"
+
+#: main/models.py:204 main/models.py:287
+msgid "Not mandatory. Set it for dated item such as event. Format YYYY-MM-DD"
+msgstr ""
+"Optionnel. Précisez ce champ pour les éléments datés comme un événement. "
+"Format du champ : AAAA-MM-JJ"
+
+#: main/models.py:206 main/models.py:289 templates/edit.html:47
+#: templates/edit_route.html:47
+msgid "End date"
+msgstr "Date de fin"
+
+#: main/models.py:207 main/models.py:290
+msgid ""
+"Not mandatory. Set it only if you have a multi-day event. Format YYYY-MM-DD"
+msgstr ""
+"Optionnel. Précisez ce champ seulement pour des événements durant plusieurs "
+"jours. Format du champ : AAAA-MM-JJ"
+
+#: main/models.py:210
+msgid "Available Date"
+msgstr "Date de mise en disponibilité"
+
+#: main/models.py:219 main/models.py:499
msgid "Point of interest"
msgstr "Point d'intérêt"
-#: main/models.py:389
+#: main/models.py:434
msgid "Area urn"
msgstr "Urn de la zone"
-#: main/models.py:396
+#: main/models.py:438
msgid "Upper left corner"
msgstr "Coin en haut à gauche"
-#: main/models.py:398
+#: main/models.py:440
msgid "Lower right corner"
msgstr "Coin en bas à droite"
-#: main/models.py:436
+#: main/models.py:478
msgid "Text"
msgstr "Texte"
-#: main/models.py:437
+#: main/models.py:479
msgid "Long text"
msgstr "Texte long"
-#: main/models.py:438
+#: main/models.py:480
msgid "Password"
msgstr "Mot de passe"
-#: main/models.py:442
+#: main/models.py:484
msgid "Type"
msgstr "Type"
-#: main/models.py:447 main/models.py:459
+#: main/models.py:489 main/models.py:501
msgid "Property model"
msgstr "Modèle de propriété"
-#: main/models.py:460
+#: main/models.py:502
msgid "Value"
msgstr "Valeur"
-#: main/models.py:464
+#: main/models.py:506
msgid "Property"
msgstr "Propriété"
-#: main/views.py:217
+#: main/views.py:221
msgid "Comments/request on the map"
msgstr "Commentaires/requètes sur la carte"
-#: main/views.py:220
+#: main/views.py:224
msgid ""
"Thank you for your contribution. It will be taken into account. If you have "
"left your email you may be contacted soon for more details."
@@ -211,45 +253,45 @@ msgstr ""
"laissé votre courriel vous serez peut-être contacté bientôt pour plus de "
"détails."
-#: main/views.py:224
+#: main/views.py:228
msgid "Temporary error. Renew your message later."
msgstr "Erreur temporaire. Réenvoyez votre message plus tard."
-#: main/views.py:307
+#: main/views.py:337
msgid "No category available in this area."
msgstr "Pas de catégorie disponible sur cette zone."
-#: main/widgets.py:117
+#: main/widgets.py:112
msgid "Latitude"
msgstr "Latitude"
-#: main/widgets.py:117
+#: main/widgets.py:112
msgid "Longitude"
msgstr "Longitude"
-#: main/widgets.py:141
+#: main/widgets.py:136
msgid "Invalid point"
msgstr "Point invalide"
-#: main/widgets.py:167
+#: main/widgets.py:162
msgid "Creation mode"
msgstr "Mode création"
-#: main/widgets.py:168
+#: main/widgets.py:163
msgid ""
"To start drawing the route click on the toggle button : \"Start drawing\"."
msgstr ""
"Pour commencer le dessin cliquez sur le bouton : « Commencer le tracé » "
-#: main/widgets.py:169
+#: main/widgets.py:164
msgid "Then click on the map to begin the drawing."
msgstr "Puis cliquez sur la carte pour commencer le dessin."
-#: main/widgets.py:170
+#: main/widgets.py:165
msgid "You can add points by clicking again."
msgstr "Vous pouvez ajouter des points en cliquant de nouveau."
-#: main/widgets.py:171
+#: main/widgets.py:166
msgid ""
"To finish the drawing double click. When the drawing is finished you can "
"edit it."
@@ -257,7 +299,7 @@ msgstr ""
"Pour finir le tracé double-cliquez. Quand le tracé est fini vous pouvez "
"toujours l'éditer."
-#: main/widgets.py:173
+#: main/widgets.py:168
msgid ""
"While creating to undo a drawing click again on the toggle button \"Stop "
"drawing\"."
@@ -265,24 +307,24 @@ msgstr ""
"En mode création vous pouvez annuler un tracé en appuyant sur le bouton « "
"Arrêter le tracé »"
-#: main/widgets.py:178
+#: main/widgets.py:173
msgid "Modification mode"
msgstr "Mode modification"
-#: main/widgets.py:179
+#: main/widgets.py:174
msgid "To move a point click on it and drag it to the desired position."
msgstr ""
"Pour bouger un point, cliquez dessus, maintenez le click pour le déposer à "
"la position désirée."
-#: main/widgets.py:180
+#: main/widgets.py:175
msgid ""
"To delete a point move the mouse cursor over it and press the \"d\" key."
msgstr ""
"Pour supprimer un point, mettez le curseur de la souris sur celui-ci et "
"appuyez sur le touche « d »"
-#: main/widgets.py:181
+#: main/widgets.py:176
msgid ""
"To add a point click in the middle of a segment and drag the new point to "
"the desired position"
@@ -291,14 +333,78 @@ msgstr ""
"maintenez le bouton appuyé et déplacez le nouveau point à la position "
"désirée."
-#: main/widgets.py:190
+#: main/widgets.py:185
msgid "Start drawing"
msgstr "Commencer le tracé"
-#: main/widgets.py:190
+#: main/widgets.py:185
msgid "Stop drawing"
msgstr "Arrêter le tracé"
+#: main/widgets.py:323
+msgid "Select..."
+msgstr "Sélectionner..."
+
+#: rss/feeds.py:132 rss/feeds.py:222
+msgid "Last points of interest"
+msgstr "Derniers points d'intérêt"
+
+#: rss/feeds.py:138
+msgid "Latest points of interest from "
+msgstr "Nouveaux points d'intérêt de "
+
+#: rss/feeds.py:184
+msgid "Last points of interest by area"
+msgstr "Nouveaux points d'intérêt par zone"
+
+#: rss/views.py:73
+msgid "Incorrect choice in the list"
+msgstr "Choix incorrect dans la liste"
+
+#: rss/templates/rss.html:10
+msgid "Subscribe to RSS feed"
+msgstr "Souscrire à un flux RSS"
+
+#: rss/templates/rss.html:17
+msgid "Type of RSS feed"
+msgstr "Type de flux RSS"
+
+#: rss/templates/rss.html:20
+msgid "All new points of interest"
+msgstr "Tous les nouveaux points d'intérêt"
+
+#: rss/templates/rss.html:21 rss/templates/rss.html.py:28
+msgid "New points of interest by category"
+msgstr "Les nouveaux points d'intérêt par catégorie"
+
+#: rss/templates/rss.html:22 rss/templates/rss.html.py:44
+msgid "New points of interest by area"
+msgstr "Les nouveaux points d'intérêt par zone"
+
+#: rss/templates/rss.html:30
+msgid "Choose a category"
+msgstr "Choisir une catégorie"
+
+#: rss/templates/rss.html:47
+msgid "Choose a pre-defined areas"
+msgstr "Choisir une zone pré-définie"
+
+#: rss/templates/rss.html:61
+msgid "Or select the area by zooming and panning this map"
+msgstr "Ou sélectionner une zone en zoomant et en se déplaçant sur cette carte"
+
+#: rss/templates/rss.html:66
+msgid "Validate"
+msgstr "Valider"
+
+#: templates/404.html:4
+msgid "Page not found"
+msgstr "Page non trouvée"
+
+#: templates/500.html:4
+msgid "Internal server error"
+msgstr "Erreur interne du serveur"
+
#: templates/base.html:39
msgid "This site uses Chimère"
msgstr "Ce site utilise Chimère"
@@ -332,35 +438,43 @@ msgstr ""
msgid "Submit"
msgstr "Proposer"
-#: templates/detail.html:8
+#: templates/detail.html:7
+msgid "Date:"
+msgstr "Date :"
+
+#: templates/detail.html:13
msgid "Share on"
msgstr "Partager sur"
-#: templates/detail.html:11
+#: templates/detail.html:16
msgid "Share"
msgstr "Partager"
-#: templates/edit.html:9
+#: templates/edit.html:16
msgid "Add a new site"
msgstr "Ajouter un nouveau site"
-#: templates/edit.html:10 templates/edit_route.html:9
+#: templates/edit.html:17 templates/edit_route.html:16
msgid "indicates a mandatory field"
msgstr "indique un champ obligatoire"
-#: templates/edit.html:13 templates/edit_route.html:12
+#: templates/edit.html:20 templates/edit_route.html:19
msgid "Site name"
msgstr "Nom du site"
-#: templates/edit.html:32
+#: templates/edit.html:25 templates/edit_route.html:24
+msgid "Categories"
+msgstr "Catégories"
+
+#: templates/edit.html:30
msgid "Point"
msgstr "Point"
-#: templates/edit.html:33 templates/edit_route.html:32
+#: templates/edit.html:31 templates/edit_route.html:30
msgid "Select a location for this new site"
msgstr "Choisissez une localisation pour ce nouveau site"
-#: templates/edit.html:48 templates/edit_route.html:48
+#: templates/edit.html:60 templates/edit_route.html:60
msgid "Propose"
msgstr "Proposez"
@@ -406,6 +520,3 @@ msgstr ""
"fichier welcome.html dans le dossier de patrons de Chimère. En dessous de ce "
"message toutes les nouvelles vont être affichées. Vous pouvez les ajouter "
"dans les pages d'administration."
-
-#~ msgid "Description"
-#~ msgstr "Description"
diff --git a/chimere/main/actions.py b/chimere/main/actions.py
index aa817c1..3711234 100644
--- a/chimere/main/actions.py
+++ b/chimere/main/actions.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2008-2010 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
@@ -23,7 +23,7 @@ Actions available in the main interface
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth import models
-from chimere.settings import EXTRA_URL, EMAIL_HOST
+from chimere.settings import EXTRA_URL, EMAIL_HOST, INSTALLED_APPS
class Action:
def __init__(self, id, path, label):
@@ -33,7 +33,13 @@ actions = [(Action('view', '', _('View')), []),
(Action('contribute', 'edit', _('Contribute')),
(Action('edit', 'edit', _('Add a new point of interest')),
Action('edit_route', 'edit_route', _('Add a new route'))),
- ),
- (Action('charte', 'charte', _('Charte')), []),]
+ ),]
+
+if 'chimere.rss' in INSTALLED_APPS:
+ actions.append((Action('rss', 'rss', _('RSS feeds')), []))
+
+actions.append((Action('charte', 'charte', _('Charte')), []))
+
if EMAIL_HOST:
actions.append((Action('contact', 'contact', _('Contact us')), []),)
+
diff --git a/chimere/main/admin.py b/chimere/main/admin.py
index f63daa1..ea79f7a 100644
--- a/chimere/main/admin.py
+++ b/chimere/main/admin.py
@@ -21,6 +21,7 @@
Settings for administration pages
"""
+from chimere import settings
from chimere.main.models import Category, Icon, SubCategory, Marker, \
PropertyModel, News, Route, Area, ColorTheme, Color
from chimere.main.forms import MarkerAdminForm, RouteAdminForm, AreaAdminForm,\
@@ -47,8 +48,11 @@ class MarkerAdmin(admin.ModelAdmin):
Specialized the Point field.
"""
search_fields = ("name",)
- list_display = ('name', 'subcategory', 'status')
- list_filter = ('status', 'subcategory')
+ list_display = ('name', 'status')
+ list_filter = ('status', 'categories')
+ exclude = ['height', 'width']
+ if 'chimere.rss' in settings.INSTALLED_APPS:
+ exclude.append('available_date')
form = MarkerAdminForm
def queryset(self, request):
@@ -68,8 +72,9 @@ class RouteAdmin(admin.ModelAdmin):
Specialized the Route field.
"""
search_fields = ("name",)
- list_display = ('name', 'subcategory', 'status')
- list_filter = ('status', 'subcategory')
+ list_display = ('name', 'status')
+ list_filter = ('status', 'categories')
+ exclude = ['height', 'width']
form = RouteAdminForm
def queryset(self, request):
@@ -118,10 +123,13 @@ class ColorInline(admin.TabularInline):
class ColorThemeAdmin(admin.ModelAdmin):
inlines = [ColorInline,]
+class IconAdmin(admin.ModelAdmin):
+ exclude = ['height', 'width']
+
# register of differents database fields
admin.site.register(News, NewsAdmin)
admin.site.register(Category, CategoryAdmin)
-admin.site.register(Icon)
+admin.site.register(Icon, IconAdmin)
admin.site.register(SubCategory, SubCategoryAdmin)
admin.site.register(Marker, MarkerAdmin)
admin.site.register(Route, RouteAdmin)
diff --git a/chimere/main/forms.py b/chimere/main/forms.py
index f2490da..11b1d99 100644
--- a/chimere/main/forms.py
+++ b/chimere/main/forms.py
@@ -24,6 +24,7 @@ from django import forms
from django.contrib.gis.db import models
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User, Permission, ContentType
+from django.contrib.admin.widgets import AdminDateWidget
from django.core.mail import EmailMessage, BadHeaderError
from chimere import settings
@@ -32,6 +33,22 @@ from chimere.main.models import Marker, Route, PropertyModel, Property, Area,\
News, Category, SubCategory
from chimere.main.widgets import AreaField, PointField, TextareaWidget
+from datetime import timedelta, datetime, tzinfo
+
+ZERO = timedelta(0)
+
+class UTC(tzinfo):
+ """UTC time zone"""
+
+ def utcoffset(self, dt):
+ return ZERO
+
+ def tzname(self, dt):
+ return settings.TIME_ZONE
+
+ def dst(self, dt):
+ return ZERO
+
def notifyStaff(subject, body, sender=None):
if not settings.EMAIL_HOST:
return
@@ -51,7 +68,7 @@ def notifyStaff(subject, body, sender=None):
return True
def notifySubmission(geo_object):
- category = unicode(geo_object.subcategory)
+ category = u" - ".join([unicode(cat) for cat in geo_object.categories.all()])
subject = u'%s %s' % (_(u"New submission for"), category)
message = _(u'The new item "%s" has been submited in the category: ') % \
geo_object.name + category
@@ -111,6 +128,22 @@ required=False)' % (property.order, property.id, property.name,
else:
keys['initial'] = property_dct
super(MarkerAdminForm, self).__init__(*args, **keys)
+ if settings.DAYS_BEFORE_EVENT:
+ self.fields['start_date'].widget = AdminDateWidget()
+ self.fields['end_date'].widget = AdminDateWidget()
+
+ def clean(self):
+ '''
+ Verify that a start date is provided when an end date is set
+ '''
+ if not settings.DAYS_BEFORE_EVENT:
+ return self.cleaned_data
+ if self.cleaned_data['end_date'] and \
+ not self.cleaned_data['start_date']:
+ msg = _(u"End date has been set with no start date")
+ self._errors["end_date"] = self.error_class([msg])
+ del self.cleaned_data['end_date']
+ return self.cleaned_data
def save(self, *args, **keys):
"""
@@ -119,6 +152,10 @@ required=False)' % (property.order, property.id, property.name,
new_marker = super(MarkerAdminForm, self).save(*args, **keys)
if 'status' not in self.cleaned_data:
new_marker.status = 'S'
+ if new_marker.status == 'A':
+ tz = UTC()
+ new_marker.available_date = datetime.replace(datetime.utcnow(),
+ tzinfo=tz)
new_marker.save()
# save each property
for propertymodel in PropertyModel.objects.filter(available=True):
@@ -180,6 +217,9 @@ required=False)' % (property.order, property.id, property.name,
else:
keys['initial'] = property_dct
super(RouteAdminForm, self).__init__(*args, **keys)
+ if settings.DAYS_BEFORE_EVENT:
+ self.fields['start_date'].widget = AdminDateWidget()
+ self.fields['end_date'].widget = AdminDateWidget()
def save(self, *args, **keys):
"""
@@ -268,3 +308,11 @@ class AreaAdminForm(forms.ModelForm):
if perm:
perm[0].delete()
return new_area
+
+class AreaForm(AreaAdminForm):
+ """
+ Form for the edit page
+ """
+ class Meta:
+ model = Area
+
diff --git a/chimere/main/models.py b/chimere/main/models.py
index f633b3f..093918b 100644
--- a/chimere/main/models.py
+++ b/chimere/main/models.py
@@ -20,6 +20,8 @@
"""
Models description
"""
+from datetime import datetime, timedelta
+
from django.utils.translation import ugettext_lazy as _
from django.contrib.gis.db import models
@@ -27,8 +29,7 @@ from django.contrib.gis.gdal import SpatialReference
from django.contrib import admin
from chimere import settings
-from chimere.main.widgets import PointField, RouteField, \
- ManyToManyField_NoSyncdb
+from chimere.main.widgets import PointField, RouteField, SelectMultipleField
class News(models.Model):
"""News of the site
@@ -42,6 +43,7 @@ class News(models.Model):
return self.title
class Meta:
verbose_name = _("News")
+ verbose_name_plural = _("News")
class TinyUrl(models.Model):
"""Tinyfied version of permalink parameters
@@ -122,6 +124,8 @@ class Icon(models.Model):
name = models.CharField(_("Name"), max_length=150)
image = models.ImageField(_("Image"), upload_to='icons',
height_field='height', width_field='width')
+ height = models.IntegerField(_("Height"))
+ width = models.IntegerField(_("Width"))
def __unicode__(self):
return self.name
class Meta:
@@ -133,8 +137,7 @@ class SubCategory(models.Model):
category = models.ForeignKey(Category, verbose_name=_("Category"))
name = models.CharField(_("Name"), max_length=150)
available = models.BooleanField(_("Available"))
- areas = models.ManyToManyField('Area', related_name='areas',
- blank=True, null=True)
+ areas = SelectMultipleField('Area', related_name='areas', blank=True)
icon = models.ForeignKey(Icon, verbose_name=_("Icon"))
color_theme = models.ForeignKey(ColorTheme, verbose_name=_("Color theme"),
blank=True, null=True)
@@ -163,8 +166,8 @@ class SubCategory(models.Model):
if area_name:
area = Area.objects.get(urn=area_name)
# if there some restrictions with categories limit them
- if area.subcategories.count():
- sub_ids = [sub.id for sub in area.subcategories.all()]
+ if area.subcategory_set.count():
+ sub_ids = [sub.id for sub in area.subcategory_set.all()]
# if no area is defined for a category don't filter it
sub_ids += [sub.id for sub in subcategories
if not sub.areas.count()]
@@ -183,10 +186,12 @@ class Marker(models.Model):
'''Marker for a POI
'''
name = models.CharField(_("Name"), max_length=150)
- subcategory = models.ForeignKey(SubCategory, verbose_name=_("Subcategory"))
- point = PointField(_("Localisation"))
+ categories = SelectMultipleField(SubCategory)
+ point = PointField(_("Localisation"), srid=settings.EPSG_DISPLAY_PROJECTION)
picture = models.ImageField(_("Image"), upload_to='upload', blank=True,
- height_field='height', width_field='width')
+ null=True, height_field='height', width_field='width')
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
STATUS = (('S', _('Submited')),
('A', _('Available')),
('D', _('Disabled')),)
@@ -194,13 +199,23 @@ class Marker(models.Model):
for key, label in STATUS:
STATUS_DCT[key] = label
status = models.CharField(_("Status"), max_length=1, choices=STATUS)
+ if settings.DAYS_BEFORE_EVENT:
+ start_date = models.DateField(_("Start date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it for dated item such as event. \
+Format YYYY-MM-DD"))
+ end_date = models.DateField(_("End date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it only if you have a multi-day event. \
+Format YYYY-MM-DD"))
+ if 'chimere.rss' in settings.INSTALLED_APPS:
+ available_date = models.DateTimeField(_("Available Date"), blank=True,
+ null=True)
objects = models.GeoManager()
def __unicode__(self):
return self.name
class Meta:
- ordering = ('subcategory__category', 'subcategory', 'status', 'name')
+ ordering = ('status', 'name')
verbose_name = _("Point of interest")
def getLatitude(self):
@@ -236,31 +251,44 @@ class Marker(models.Model):
properties.append(property)
return properties
- def getGeoJSON(self):
+ def getGeoJSON(self, categories_id=[]):
'''Return a GeoJSON string
'''
- return """{"type":"Feature", "geometry":%(geometry)s, \
+ jsons = []
+ for cat in self.categories.all():
+ if categories_id and cat.id not in categories_id:
+ continue
+ jsons.append("""{"type":"Feature", "geometry":%(geometry)s, \
"properties":{"pk": %(id)d, "name": "%(name)s", \
"icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, \
"icon_height":%(icon_height)d}}""" % {'id':self.id, 'name':self.name,
-'icon_path':self.subcategory.icon.image, 'geometry':self.point.geojson,
-'icon_width':self.subcategory.icon.image.width,
-'icon_height':self.subcategory.icon.image.height,}
+'icon_path':cat.icon.image, 'geometry':self.point.geojson,
+'icon_width':cat.icon.image.width, 'icon_height':cat.icon.image.height,})
+ return ",".join(jsons)
class Route(models.Model):
'''Route on the map
'''
name = models.CharField(_("Name"), max_length=150)
- subcategory = models.ForeignKey(SubCategory, verbose_name=_("Subcategory"))
- route = RouteField(_("Route"))
+ categories = SelectMultipleField(SubCategory)
+ route = RouteField(_("Route"), srid=settings.EPSG_DISPLAY_PROJECTION)
picture = models.ImageField(_("Image"), upload_to='upload', blank=True,
- height_field='height', width_field='width')
+ null=True, height_field='height', width_field='width')
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
STATUS = (('S', _('Submited')),
('A', _('Available')),
('D', _('Disabled')),)
STATUS_DCT = {}
for key, label in STATUS:
STATUS_DCT[key] = label
+ if settings.DAYS_BEFORE_EVENT:
+ start_date = models.DateField(_("Start date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it for dated item such as event. \
+Format YYYY-MM-DD"))
+ end_date = models.DateField(_("End date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it only if you have a multi-day event. \
+Format YYYY-MM-DD"))
status = models.CharField(_("Status"), max_length=1, choices=STATUS)
objects = models.GeoManager()
@@ -268,7 +296,7 @@ class Route(models.Model):
return self.name
class Meta:
- ordering = ('subcategory__category', 'subcategory', 'status', 'name')
+ ordering = ('status', 'name')
verbose_name = _("Route")
def getProperty(self, propertymodel, safe=None):
@@ -304,6 +332,22 @@ class Route(models.Model):
"color":"%(color)s"}}""" % {'id':self.id, 'name':self.name,
'color':color, 'geometry':self.route.geojson,}
+def getDateCondition():
+ '''
+ Return an SQL condition for apparition of dates
+ '''
+ if not settings.DAYS_BEFORE_EVENT:
+ return ""
+ now = datetime.now().strftime('%Y-%m-%d')
+ after = (datetime.now() + timedelta(settings.DAYS_BEFORE_EVENT)
+ ).strftime('%Y-%m-%d')
+ date_condition = " and %(alias)s.start_date is null or "
+ date_condition += "(%(alias)s.start_date >= '" + now + "' and "
+ date_condition += "%(alias)s.start_date <='" + after + "')"
+ date_condition += " or (%(alias)s.start_date <='" + now + "' and "
+ date_condition += "%(alias)s.end_date >='" + now + "') "
+ return date_condition
+
class SimplePoint:
"""
Point in the map (not in the database)
@@ -352,39 +396,35 @@ class SimpleArea:
self.upper_left_corner.x, self.upper_left_corner.y,
settings.EPSG_DISPLAY_PROJECTION
)
+ date_condition = getDateCondition()
sql_main = '''select subcat.id as id, subcat.category_id as category_id,
subcat.name as name, subcat.available as available, subcat.icon_id as icon_id,
subcat.color_theme_id as color_theme_id, subcat.order as order,
subcat.item_type as item_type from main_subcategory subcat
inner join main_category cat on cat.id=subcat.category_id'''
sql = sql_main + '''
-inner join main_marker mark on mark.subcategory_id=subcat.id
- and ST_Contains(%s, mark.point)''' % area
+inner join main_marker mark on ST_Contains(%s, mark.point)''' % area
if equal_status:
sql += ' and mark.status' + equal_status
+ sql += date_condition % {'alias':'mark'}
+ sql += '''
+inner join main_marker_categories mc on mc.subcategory_id=subcat.id and
+mc.marker_id=mark.id'''
if filter_available:
sql += ' where subcat.available = TRUE and cat.available = TRUE'
- print sql
- # django > 1.1
- #subcats = SubCategory.objects.raw(sql)
- from django.db import connection, transaction
- cursor = connection.cursor()
- cursor.execute(sql, [])
- subcats = set()
- for r in cursor.fetchall():
- subcats.add(SubCategory.objects.get(id=r[0]))
+ subcats = set(SubCategory.objects.raw(sql))
sql = sql_main + '''
-inner join main_route rt on rt.subcategory_id=subcat.id
-and (ST_Intersects(%s, rt.route) or ST_Contains(%s, rt.route))''' % (area, area)
+inner join main_route rt on (ST_Intersects(%s, rt.route) or
+ST_Contains(%s, rt.route))''' % (area, area)
if equal_status:
sql += ' and rt.status' + equal_status
+ sql += date_condition % {'alias':'rt'}
+ sql += '''
+inner join main_route_categories rc on rc.subcategory_id=subcat.id and
+rc.route_id=rt.id'''
if filter_available:
sql += ' where subcat.available = TRUE and cat.available = TRUE'
- # django > 1.1
- #subcats += SubCategory.objects.raw(sql)
- cursor.execute(sql, [])
- for r in cursor.fetchall():
- subcats.add(SubCategory.objects.get(id=r[0]))
+ subcats.union(SubCategory.objects.raw(sql))
return subcats
class Area(models.Model, SimpleArea):
@@ -393,15 +433,12 @@ class Area(models.Model, SimpleArea):
name = models.CharField(_("Name"), max_length=150)
urn = models.SlugField(_("Area urn"), max_length=50, blank=True,
unique=True)
- subcategories = ManyToManyField_NoSyncdb(SubCategory,
- related_name='subcategories', blank=True, null=True,
- db_table=u'subcategory_areas')
order = models.IntegerField(_("Order"))
available = models.BooleanField(_("Available"))
upper_left_corner = models.PointField(_("Upper left corner"),
- default='POINT(0 0)')
+ default='POINT(0 0)', srid=settings.EPSG_DISPLAY_PROJECTION)
lower_right_corner = models.PointField(_("Lower right corner"),
- default='POINT(0 0)')
+ default='POINT(0 0)', srid=settings.EPSG_DISPLAY_PROJECTION)
objects = models.GeoManager()
def __unicode__(self):
diff --git a/chimere/main/views.py b/chimere/main/views.py
index cf8b1b7..91f398d 100644
--- a/chimere/main/views.py
+++ b/chimere/main/views.py
@@ -30,6 +30,7 @@ from django.template import loader
from django.http import HttpResponseRedirect, HttpResponse
from django.core import serializers
from django.utils.http import urlquote
+from django.db.models import Q
from chimere import settings
from chimere.main.actions import actions
@@ -136,6 +137,7 @@ def edit(request, area_name=""):
'error_message':'',
'map_layer':settings.MAP_LAYER,
'form':form,
+ 'dated':settings.DAYS_BEFORE_EVENT,
'extra_head':form.media,
'sub_categories':SubCategory.getAvailable(['M', 'B'],
area_name),
@@ -176,6 +178,7 @@ def editRoute(request, area_name=""):
'error_message':'',
'map_layer':settings.MAP_LAYER,
'form':form,
+ 'dated':settings.DAYS_BEFORE_EVENT,
'extra_head':form.media,
'sub_categories':SubCategory.getAvailable(['R', 'B'],
area_name),
@@ -252,12 +255,14 @@ def getDetail(request, area_name, marker_id):
if 'simple' in request.GET and request.GET['simple']:
response_dct['simple'] = True
parameters = u'current_feature=%s' % marker_id
- parameters += u"&checked_categories=%d" % marker.subcategory.id
+ parameters += u"&checked_categories=%s" % "_".join([str(m.id) \
+ for m in marker.categories.all()])
net_dct = getTinyfiedUrl(parameters, area_name)
share_networks = []
for network in settings.SHARE_NETWORKS:
share_networks.append((network[0], network[1] % net_dct, network[2]))
response_dct['share_networks'] = share_networks
+ response_dct['dated'] = settings.DAYS_BEFORE_EVENT and marker.start_date
return render_to_response('detail.html', response_dct)
def getDescriptionDetail(request, area_name, category_id):
@@ -272,6 +277,21 @@ def getDescriptionDetail(request, area_name, category_id):
response_dct['category'] = category
return render_to_response('category_detail.html', response_dct)
+def checkDate(q):
+ """
+ Filter a queryset to manage dates
+ """
+ if not settings.DAYS_BEFORE_EVENT:
+ return q
+ today = datetime.date.today()
+ after = today + datetime.timedelta(settings.DAYS_BEFORE_EVENT)
+
+ q = q & ( Q(start_date__isnull=True)
+ | Q(start_date__gte=today, start_date__lte=after)
+ | Q(start_date__lte=today, end_date__gte=today)
+ )
+ return q
+
def getGeoObjects(request, area_name, category_ids, status):
'''
Get the JSON for markers and routes
@@ -279,35 +299,38 @@ def getGeoObjects(request, area_name, category_ids, status):
if not status:
status = 'A'
status = status.split('_')
+ category_ids = category_ids.split('_')
try:
- query = Route.objects.filter(status__in=status,
- subcategory__in=category_ids.split('_'))
+ q = checkDate(Q(status__in=status, categories__in=category_ids))
+ query = Route.objects.filter(q)
except:
return HttpResponse('no results')
- query.order_by('subcategory')
+ query.order_by('categories')
routes = list(query)
jsons = []
current_cat, colors, idx = None, None, 0
for route in routes:
- if not current_cat or current_cat != route.subcategory:
+ c_cat = route.categories.all()[0]
+ if not current_cat or current_cat != c_cat:
idx = 0
- current_cat = route.subcategory
- colors = list(Color.objects.filter(color_theme=\
- route.subcategory.color_theme))
+ current_cat = c_cat
+ colors = list(Color.objects.filter(color_theme = c_cat.color_theme))
jsons.append(route.getGeoJSON(color=colors[idx % len(colors)].code))
idx += 1
try:
- query = Marker.objects.filter(status__in=status,
- subcategory__in=category_ids.split('_'))
+ q = checkDate(Q(status__in=status, categories__in=category_ids))
+ query = Marker.objects.filter(q)
except:
return HttpResponse('no results')
- jsons += [geo_object.getGeoJSON() for geo_object in list(query)]
+ category_ids = [int(cat_id) for cat_id in category_ids]
+ jsons += [geo_object.getGeoJSON(category_ids) for geo_object in list(query)]
if not jsons:
return HttpResponse('no results')
data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons)
return HttpResponse(data)
-def getAvailableCategories(request, area_name=None, area=None, status='A', force=None):
+def getAvailableCategories(request, area_name=None, area=None, status='A',
+ force=None):
'''
Get categories for a designed area
'''
diff --git a/chimere/main/widgets.py b/chimere/main/widgets.py
index 4ad6475..9c53a6d 100644
--- a/chimere/main/widgets.py
+++ b/chimere/main/widgets.py
@@ -33,11 +33,6 @@ URL_OSM_CSS = ["http://www.openlayers.org/api/theme/default/style.css"]
URL_OSM_JS = ["http://www.openlayers.org/api/OpenLayers.js",
"http://www.openstreetmap.org/openlayers/OpenStreetMap.js"]
-class ManyToManyField_NoSyncdb(models.ManyToManyField):
- def __init__(self, *args, **kwargs):
- super(ManyToManyField_NoSyncdb, self).__init__(*args, **kwargs)
- self.creates_table = False
-
def getMapJS(area_name=''):
'''Variable initialization for drawing the map
'''
@@ -136,7 +131,7 @@ class PointField(models.PointField):
keys.update(defaults)
return super(PointField, self).formfield(**keys)
- def clean(self, value):
+ def clean(self, value, instance=None):
if len(value) != 2 and self.required:
raise ValidationError(_("Invalid point"))
return value
@@ -299,3 +294,41 @@ class AreaField(forms.MultiValueField):
if not data_list:
return None
return data_list
+
+class MultiSelectWidget(forms.SelectMultiple):
+ class Media:
+ css = {'all': (
+ settings.MEDIA_URL + 'jquery/bsmSelect/css/jquery.bsmselect.css',
+ settings.MEDIA_URL + 'jquery/css/jquery.bsmselect.custom.css',
+ )
+ }
+ js = (
+ settings.MEDIA_URL + 'jquery/jquery-1.4.4.min.js',
+ settings.MEDIA_URL + 'jquery/bsmSelect/js/jquery.bsmselect.js',
+ settings.MEDIA_URL + 'jquery/bsmSelect/js/jquery.bsmselect.compatibility.js',
+ )
+
+ def render(self, name, value, attrs=None):
+ rendered = super(MultiSelectWidget, self).render(name, value, attrs)
+ return mark_safe(rendered + u'''<hr class='spacer'/><script type="text/javascript">
+$.bsmSelect.conf['title'] = "%(title)s";
+$("#id_%(name)s").bsmSelect({
+ removeLabel: '<strong>X</strong>',
+ containerClass: 'bsmContainer',
+ listClass: 'bsmList-custom',
+ listItemClass: 'bsmListItem-custom',
+ listItemLabelClass: 'bsmListItemLabel-custom',
+ removeClass: 'bsmListItemRemove-custom'
+});
+</script>''' % {'name':name, 'title':_("Select...")})
+
+class SelectMultipleField(models.ManyToManyField):
+ '''
+ Set the widget for the category field
+ '''
+ def formfield(self, **keys):
+ self.help_text = ""
+ defaults = {'widget': MultiSelectWidget}
+ keys.update(defaults)
+ return super(SelectMultipleField, self).formfield(**keys)
+
diff --git a/chimere/rss/__init__.py b/chimere/rss/__init__.py
new file mode 100644
index 0000000..792d600
--- /dev/null
+++ b/chimere/rss/__init__.py
@@ -0,0 +1 @@
+#
diff --git a/chimere/rss/feeds.py b/chimere/rss/feeds.py
new file mode 100644
index 0000000..1bb1a76
--- /dev/null
+++ b/chimere/rss/feeds.py
@@ -0,0 +1,234 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010 Pierre Clarenc <pierre.crc_AT_gmailDOTcom>,
+# Samuel Renard <renard.samuel_AT_gmailDOTcom>,
+# Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# See the file COPYING for details.
+
+from django.utils.translation import ugettext as _
+from django.contrib.syndication.feeds import Feed
+from django.contrib.syndication.feeds import FeedDoesNotExist
+from chimere.main.models import Category, SubCategory, Marker, Area
+from django.core.exceptions import ObjectDoesNotExist
+from django.contrib.gis.geos import *
+
+from chimere import settings
+
+class BaseFeed(Feed):
+ """
+ Base feed for Chimere objects
+ """
+ def item_link(self, item):
+ ''' Return POI permalink '''
+ coord = item.point
+ return settings.BASE_URL + '?zoom=16&lat=%d&lon=%d&current_feature=%d&\
+checked_categories=%d' % (coord.y, coord.x, item.id,
+ item.categories.all()[0].id)
+
+ def item_pubdate(self, item):
+ """
+ Date of the Marker when it has been available
+ """
+ return item.available_date
+
+ def description(self, obj):
+ return ""
+
+class LatestPOIsByCategory(BaseFeed):
+ '''
+ Last Points of interests by category in Feeds
+ '''
+ title_template = "rss_title.html"
+ description_template = "rss_descr.html"
+
+ def get_object(self, bits):
+ """
+ Get extra url, after rss/category/ id of category
+ """
+ if len(bits) != 1:
+ raise ObjectDoesNotExist
+ return Category.objects.get(id__exact=bits[0])
+
+ def title(self, obj):
+ """
+ Define the title of the feed
+ """
+ return u"%s - %s" % (settings.PROJECT_NAME, obj.name)
+
+ def link(self, obj):
+ """
+ Define the link of the feed.
+ """
+ if not obj:
+ raise FeedDoesNotExist
+ return settings.BASE_URL + 'rss/category/' + str(obj.id)
+
+ def description(self, obj):
+ """
+ Description of the feed
+ """
+ return obj.description
+
+ def items(self, obj):
+ """
+ Requests to marker where its category match the category is requested
+ and its status is available
+ This returns a list of the 15 last markers/POIs ordering by date
+ """
+ q = Marker.objects.filter(status__exact='A',
+ categories__subcategory__category__id__exact=obj.id,
+ available_date__isnull=False).order_by('-available_date')[:15]
+ return q
+
+class LatestPOIsBySubCategory(BaseFeed):
+ '''
+ Last Points of interests by SubCategory in Feeds
+ '''
+ title_template = "rss_title.html"
+ description_template = "rss_descr.html"
+
+ def get_object(self, bits):
+ if len(bits) != 1:
+ raise ObjectDoesNotExist
+ return SubCategory.objects.get(id__exact=bits[0])
+
+ def title(self, obj):
+ return u"%s - %s - %s" % (settings.PROJECT_NAME, obj.category.name,
+ obj.name)
+
+ def link(self, obj):
+ if not obj:
+ raise FeedDoesNotExist
+ return settings.BASE_URL + 'rss/subcategory/' + str(obj.id)
+
+ def items(self, obj):
+ q = Marker.objects.filter(categories__id__exact=obj.id,
+ available_date__isnull=False, status__exact='A').order_by(
+ '-available_date')[:15]
+ return q
+
+class LatestPOIs(BaseFeed):
+ '''
+ Last Points of interests
+ '''
+ title_template = "rss_title.html"
+ description_template = "rss_descr.html"
+
+ def title(self):
+ return settings.PROJECT_NAME + u" - " + _(u"Last points of interest")
+
+ def link(self):
+ return settings.BASE_URL + 'rss/categories/'
+
+ def description(self):
+ return _("Latest points of interest from ") + settings.PROJECT_NAME
+
+ def items(self):
+ q = Marker.objects.filter(status__exact='A',
+ available_date__isnull=False).order_by('-available_date')[:15]
+ return q
+
+class LatestPOIsByZone(BaseFeed):
+ '''
+ Last Points of interests by zone by coordinates
+ '''
+ title_template = "rss_title.html"
+ description_template = "rss_descr.html"
+ upper_left_lat = 0
+ upper_left_lon = 0
+ lower_right_lat = 0
+ lower_right_lon = 0
+
+ def get_object(self, bits):
+ """
+ Get the extra url. Parameters are the coordinates of the zone (the
+ upper left and lower right points)
+ """
+ if len(bits) != 1:
+ raise ObjectDoesNotExist
+ # Then define the upper right and lower left points
+ coordinates = str(bits[0]).split('_')
+ upper_left_lat = float(coordinates[0])
+ upper_left_lon = float(coordinates[1])
+ lower_right_lat = float(coordinates[2])
+ lower_right_lon = float(coordinates[3])
+ upper_right_lat = upper_left_lat
+ upper_right_lon = lower_right_lon
+ lower_left_lat = lower_right_lat
+ lower_left_lon = upper_left_lon
+ # Define a Polygon with the 4 points of the zone.
+ areaBox = Polygon(((upper_left_lon, upper_left_lat),
+ (upper_right_lon, upper_right_lat),
+ (lower_right_lon, lower_right_lat),
+ (lower_left_lon, lower_left_lat),
+ (upper_left_lon, upper_left_lat)),
+ srid=settings.EPSG_DISPLAY_PROJECTION)
+ return areaBox
+
+ def title(self, obj):
+ return settings.PROJECT_NAME + u" - " +\
+ _(u"Last points of interest by area")
+
+ def link(self, obj):
+ """
+ Define the link of the feed. It's the same url as we get in the method
+ get_object
+ """
+ if not obj:
+ raise FeedDoesNotExist
+ return settings.BASE_URL + 'rss/area/' \
+ + str(self.upper_left_lat) + '_' + str(self.upper_left_lon) + \
+ '_' + str(self.lower_right_lat) + '_' + str(self.lower_right_lon)
+
+ def items(self, obj):
+ """
+ Request to return Markers WHERE there points are containes in the zone
+ which is requested.
+ This returns a list of the 15 last markers/POIs ordering by date
+ """
+ q = Marker.objects.filter(point__contained=obj, status__exact='A',
+ available_date__isnull=False).order_by('-available_date')[:15]
+ return q
+
+class LatestPOIsByZoneID(BaseFeed):
+ '''
+ Last Points of interests by zone by id
+ '''
+ title_template = "rss_title.html"
+ description_template = "rss_descr.html"
+
+ def get_object(self, bits):
+ if len(bits) != 1:
+ raise ObjectDoesNotExist
+ return Area.objects.get(id__exact=bits[0])
+
+ def title(self, obj):
+ return settings.PROJECT_NAME + u" - " + \
+ _(u"Last points of interest") + u" - " + obj.name
+
+ def link(self, obj):
+ if not obj:
+ raise FeedDoesNotExist
+ return settings.BASE_URL + 'rss/areaid/' + str(obj.id)
+
+ def items(self, obj):
+ sql = 'select * from "main_marker" where ' + obj.getIncludeSql()
+ sql += ' and "main_marker".available_date is not null'
+ sql += ' and "main_marker".status=\'A\''
+ sql += ' order by "main_marker".available_date desc limit 15'
+ q = Marker.objects.raw(sql)
+ return q
diff --git a/chimere/rss/templates/rss.html b/chimere/rss/templates/rss.html
new file mode 100644
index 0000000..0c895ed
--- /dev/null
+++ b/chimere/rss/templates/rss.html
@@ -0,0 +1,73 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block sidebar %}
+{% endblock %}
+
+{% block content %}
+<div id='content'>
+<fieldset class='edit'>
+<legend>{% trans "Subscribe to RSS feed" %}</legend>
+
+<p><font color='red'> {{ error_message }} </font></p>
+
+<form method='post' id='rss_form' name='rss_form' action=''>
+{%if not category_rss_feed %}
+<div class="fieldWrapper">
+ <label for="rss_category">{% trans "Type of RSS feed" %}</label>
+ <select name='rss_category' id='rss_category' onchange='document.forms["rss_form"].submit();'>
+ <option value=""> ---- </option>
+ <option value="global">{% trans "All new points of interest" %}</option>
+ <option value="poi">{% trans "New points of interest by category" %}</option>
+ <option value="area">{% trans "New points of interest by area" %}</option>
+ </select>
+</div>
+{% endif %}
+
+{%ifequal category_rss_feed "category" %}
+<h3>{% trans "New points of interest by category" %}</h3>
+<div class="fieldWrapper">
+ <label for="id_subcategory">{% trans "Choose a category" %}</label>
+ <select name='subcategory' id='subcategory' onchange='document.forms["rss_form"].submit();'>
+ {% for cat_subcat in sub_categories %}
+ <option value ="cat_{{cat_subcat.0.id}}"> ---- {{cat_subcat.0.name}} ----
+ {% for sub_category in cat_subcat.1 %}
+ <option value='{{sub_category.id}}'{% ifequal sub_category.id current_category %} selected='selected'{% endifequal %}>
+ {% trans sub_category.name %}
+ </option>{% endfor %}
+ </option>{% endfor %}
+ </select>
+</div>
+{% endifequal %}
+
+{%ifequal category_rss_feed "area" %}
+<h3>{% trans "New points of interest by area" %}</h3>
+{% if area_id %}
+<div class="fieldWrapper">
+ <label for="id_area">{% trans "Choose a pre-defined areas" %}</label>
+ <select name='id_area' id='id_area' onchange='document.forms["rss_form"].submit();'>
+ <option value="" selected="selected"> ---- </option>
+ {% for areaID in area_id %}
+ <option value ={{areaID.id}}>{{areaID.name}}</option>
+ {% endfor %}
+ </select>
+</div>
+
+</form>
+
+<form method='post' action=''>
+{% endif %}
+<div class='fieldWrapper'>
+<label>{% trans "Or select the area by zooming and panning this map" %}</label>
+<div class="map">
+ {{form.area}}
+</div>
+</div>
+<p><input type="submit" value="{% trans "Validate" %}" /></p>
+{% endifequal %}
+
+</form>
+
+</fieldset>
+</div>
+{% endblock %}
diff --git a/chimere/rss/templates/rss_descr.html b/chimere/rss/templates/rss_descr.html
new file mode 100644
index 0000000..f94b061
--- /dev/null
+++ b/chimere/rss/templates/rss_descr.html
@@ -0,0 +1,7 @@
+{% load i18n %}
+<div id='detail_content'>
+{% if obj.picture %}<img src='{{media_path}}{{obj.picture}}' alt='{{obj.name}}'/>{%endif%}
+<div>{% for property in obj.getProperties %}
+<p id='{{property.propertymodel.getNamedId}}'>{{ property.value|safe }}</p>
+{% endfor %}</div>
+</div>
diff --git a/chimere/rss/templates/rss_title.html b/chimere/rss/templates/rss_title.html
new file mode 100644
index 0000000..5b379e7
--- /dev/null
+++ b/chimere/rss/templates/rss_title.html
@@ -0,0 +1,2 @@
+{% load i18n %}
+{{ obj.name }}
diff --git a/chimere/rss/urls.py b/chimere/rss/urls.py
new file mode 100644
index 0000000..e5e9a24
--- /dev/null
+++ b/chimere/rss/urls.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010 Pierre Clarenc <pierre.crc_AT_gmailDOTcom>,
+# Samuel Renard <renard.samuel_AT_gmailDOTcom>,
+# Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# See the file COPYING for details.
+
+
+from django.conf.urls.defaults import *
+
+from chimere.rss.feeds import LatestPOIsByCategory, LatestPOIsBySubCategory, \
+ LatestPOIs, LatestPOIsByZone, LatestPOIsByZoneID
+from chimere.urls import EXTRA_NO_AREA as EXTRA
+
+feeds = {
+ 'category': LatestPOIsByCategory,
+ 'subcategory': LatestPOIsBySubCategory,
+ 'global': LatestPOIs,
+ 'area': LatestPOIsByZone,
+ 'areaid': LatestPOIsByZoneID
+}
+
+urlpatterns = patterns('',
+ (EXTRA + r'rss/$', 'chimere.rss.views.rss'),
+ (EXTRA + r'rss/(?P<url>.*)/$',
+ 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),
+)
+
diff --git a/chimere/rss/views.py b/chimere/rss/views.py
new file mode 100644
index 0000000..04d69dc
--- /dev/null
+++ b/chimere/rss/views.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010 Pierre Clarenc <pierre.crc_AT_gmailDOTcom>,
+# Samuel Renard <renard.samuel_AT_gmailDOTcom>,
+# Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# See the file COPYING for details.
+
+"""
+Views of the project
+"""
+
+from django.shortcuts import render_to_response
+from django.http import HttpResponseRedirect
+
+from chimere import settings
+from chimere.main.views import get_base_response
+from chimere.main.actions import actions
+from chimere.main.models import SubCategory,Area
+from chimere.main.forms import AreaForm
+from chimere.main.widgets import AreaWidget
+
+def rss(request, area_name=''):
+ '''
+ Redirect to RSS subscription page
+ '''
+ response_dct = get_base_response()
+ response_dct.update({'actions':actions, 'action_selected':('rss',),
+ 'category_rss_feed':'',})
+ # If the form has been submited
+ if request.method == "POST":
+ # User has defined the kind of POI he is interested in : POI in a area
+ # (GET method is used for the link with RSS icon in the browser)
+ if 'rss_category' in request.POST:
+ #User wants to follow all the new POI
+ if request.POST['rss_category'] == 'global':
+ feeds_link = '/' + settings.EXTRA_URL + 'rss/global/'
+ return HttpResponseRedirect(feeds_link)
+ # User wants to follow all the new POI by category or subcategory
+ elif request.POST['rss_category'] == 'poi':
+ response_dct['category_rss_feed'] = 'category'
+ response_dct['sub_categories'] = SubCategory.getAvailable(['M',
+ 'B'])
+ return render_to_response('rss.html', response_dct)
+ # User wants to follow all the new POI situated in a defined area
+ elif request.POST['rss_category'] == 'area':
+ # An unbound form
+ form = AreaForm()
+ area_widget = AreaWidget().render('area', None)
+ response_dct.update({'map_layer':settings.MAP_LAYER,
+ 'extra_head':form.media,
+ 'form':form,
+ 'category_rss_feed':'area',
+ 'area_id':Area.getAvailable(),
+ 'area_widget':area_widget
+ })
+ return render_to_response('rss.html', response_dct)
+ # Error when submitting the form
+ else:
+ error = _("Incorrect choice in the list")
+ response_dct.update({'error_message':error,
+ 'category_rss_feed':'category',
+ 'sub_categories':SubCategory.getAvailable(['M', 'B'])})
+ return render_to_response('rss.html', response_dct)
+
+ # User has specified the category or subcategory he wants to follow =>
+ # we redirect him towards the related rss feed
+ if 'subcategory' in request.POST and request.POST['subcategory'] != '':
+ idCat = request.POST['subcategory']
+ if idCat.find("cat_") != -1 :
+ list_Cat = idCat.split('_')
+ feeds_link = '/' + settings.EXTRA_URL + 'rss/category/'
+ feeds_link += list_Cat[1]
+ return HttpResponseRedirect(feeds_link)
+
+ else:
+ feeds_link = '/' + settings.EXTRA_URL + 'rss/subcategory/' + \
+ idCat
+ return HttpResponseRedirect(feeds_link)
+
+ # User has specified the ID of the area he wants to follow
+ if 'id_area' in request.POST and request.POST['id_area'] != '':
+ feeds_link = '/' + settings.EXTRA_URL + 'rss/areaid/' \
+ + request.POST['id_area']
+ return HttpResponseRedirect(feeds_link)
+
+ # User has specified the area he wants to follow => we redirect him
+ # towards the related rss feed (using upper left and lower right
+ # coordinates)
+ elif 'upper_left_lat' in request.POST and \
+ request.POST['upper_left_lat'] != '' and \
+ 'upper_left_lon' in request.POST and \
+ request.POST['upper_left_lon'] != '' and \
+ 'lower_right_lon' in request.POST and \
+ request.POST['lower_right_lon'] != '' and \
+ 'lower_right_lat' in request.POST and \
+ request.POST['lower_right_lat'] != '' :
+ feeds_link = '/' + settings.EXTRA_URL + 'rss/area/' + \
+request.POST['upper_left_lat'] + '_' + request.POST['upper_left_lon'] + '_' + \
+request.POST['lower_right_lat'] + '_' + request.POST['lower_right_lon']
+ return HttpResponseRedirect(feeds_link)
+
+
+ # GET method is used for linking with the RSS icon in the browser when user
+ # wants to choose a category to follow
+ elif request.method == "GET" and 'rss_category' in request.GET:
+ if request.GET['rss_category'] == 'global':
+ feeds_link = '/' + settings.EXTRA_URL + 'rss/global/'
+ return HttpResponseRedirect(feeds_link)
+ if request.GET['rss_category'] == 'poi':
+ response_dct['category_rss_feed'] = 'category'
+ response_dct['sub_categories'] = SubCategory.getAvailable(['M','B'])
+ return render_to_response('rss.html', response_dct)
+ if request.GET['rss_category'] == 'area':
+ # An unbound form
+ form = AreaForm()
+ response_dct.update({'map_layer':settings.MAP_LAYER,
+ 'extra_head':form.media,
+ 'form':form,
+ 'category_rss_feed':'area',
+ 'area_id':Area.getAvailable(),
+ 'area_widget':AreaWidget().render('area', None)})
+ return render_to_response('rss.html', response_dct)
+
+ # User access to the RSS tab
+ else:
+ return render_to_response('rss.html', response_dct)
diff --git a/chimere/scripts/upgrade.py b/chimere/scripts/upgrade.py
index f260a07..46b3548 100755
--- a/chimere/scripts/upgrade.py
+++ b/chimere/scripts/upgrade.py
@@ -13,7 +13,7 @@ from django.db import connection, transaction
cursor = connection.cursor()
-from main.models import Area, Route
+from main.models import Area, Marker, Route, Icon, SubCategory
from django.contrib.gis.geos import LineString
# early versions before 0.1: urn field doesn't exist for area
@@ -32,12 +32,14 @@ def slugfy(text, separator):
ret = re.sub(" +", separator, ret)
return ret.strip()
+QUERY_CHECK_FIELD = """SELECT a.attname AS field FROM pg_class c, pg_attribute a
+ WHERE c.relname = '%s' AND a.attnum > 0 AND a.attrelid = c.oid
+ AND a.attname='%s';"""
QUERY_CHECK_TABLE = """SELECT c.relname FROM pg_class c
WHERE c.relname = '%s';"""
-query = """SELECT a.attname AS field FROM pg_class c, pg_attribute a
- WHERE c.relname = 'main_area' AND a.attnum > 0 AND a.attrelid = c.oid
- AND a.attname='urn';"""
+
+query = QUERY_CHECK_FIELD % ('main_area', 'urn')
cursor.execute(query)
transaction.commit_unless_managed()
@@ -93,7 +95,8 @@ if not row:
row = cursor.fetchone()
if row:
- query_rename = """ALTER TABLE subcategory_areas RENAME TO main_subcategory_areas;"""
+ query_rename = "ALTER TABLE subcategory_areas RENAME TO \
+main_subcategory_areas;"
cursor.execute(query_rename)
transaction.commit_unless_managed()
print " * subcategory_areas renamed to main_subcategory_areas"
@@ -159,6 +162,104 @@ for area in areas:
if changed:
print " * projections of areas corrected"
+# changement from version 1.0 to 1.1: version of django 1.2
+# create specific height and width for image fields
+
+for cls, attr in ((Icon, "image"), (Marker, "picture"),
+ (Route, "picture")):
+ table = cls._meta.db_table
+ query = QUERY_CHECK_FIELD % (table, 'width')
+ cursor.execute(query)
+ transaction.commit_unless_managed()
+
+ row = cursor.fetchone()
+ if not row:
+ query_update = "ALTER TABLE "+table+" ADD COLUMN width integer"
+ cursor.execute(query_update)
+ transaction.commit_unless_managed()
+ query_update = "ALTER TABLE "+table+" ADD COLUMN height integer"
+ cursor.execute(query_update)
+ transaction.commit_unless_managed()
+ for obj in cls.objects.all():
+ image = getattr(obj, attr)
+ if not image:
+ continue
+ obj.width = image.width
+ obj.height = image.height
+ obj.save()
+ print " * height and width of " + table + " corrected"
+
+# changement from version 1.0 to 1.1: add dated fields to markers and routes
+if settings.DAYS_BEFORE_EVENT:
+ for cls in (Marker, Route):
+ table = cls._meta.db_table
+ query = QUERY_CHECK_FIELD % (table, 'start_date')
+ cursor.execute(query)
+ transaction.commit_unless_managed()
+
+ row = cursor.fetchone()
+ if not row:
+ query_update = "ALTER TABLE "+table+" ADD COLUMN start_date date"
+ cursor.execute(query_update)
+ transaction.commit_unless_managed()
+ query_update = "ALTER TABLE "+table+" ADD COLUMN end_date date"
+ cursor.execute(query_update)
+ transaction.commit_unless_managed()
+ print " * start_date and end_date added to table " + table + "."
+
+# changement from version 1.0 to 1.1: add available_date field to marker
+if 'chimere.rss' in settings.INSTALLED_APPS:
+ for cls in (Marker,):
+ table = cls._meta.db_table
+ query = QUERY_CHECK_FIELD % (table, 'available_date')
+ cursor.execute(query)
+ transaction.commit_unless_managed()
+
+ row = cursor.fetchone()
+ if not row:
+ query_update = "ALTER TABLE " + table + " ADD COLUMN \
+available_date timestamp with time zone"
+ cursor.execute(query_update)
+ transaction.commit_unless_managed()
+ print " * available_date added to table " + table + "."
+
+
+# changement from version 1.0 to 1.1: multiple selection of categories
+
+for cls in (Marker, Route):
+ table = cls._meta.db_table[len("main_"):]
+ query = QUERY_CHECK_TABLE % ('main_' + table + '_categories')
+ cursor.execute(query)
+ transaction.commit_unless_managed()
+
+ row = cursor.fetchone()
+ if row:
+ continue
+ query_create = """
+CREATE TABLE "main_%s_categories" (
+ "id" serial NOT NULL PRIMARY KEY,
+ "%s_id" integer NOT NULL REFERENCES "main_%s" ("id") DEFERRABLE INITIALLY DEFERRED,
+ "subcategory_id" integer NOT NULL REFERENCES "main_subcategory" ("id") DEFERRABLE INITIALLY DEFERRED,
+ UNIQUE ("%s_id", "subcategory_id"));
+""" % (table, table, table, table)
+ cursor.execute(query_create)
+ transaction.commit_unless_managed()
+ for obj in cls.objects.all():
+ query = "select subcategory_id from main_%s where id=%d" % (table,
+ obj.id)
+ cursor.execute(query)
+ transaction.commit_unless_managed()
+
+ row = cursor.fetchone()
+ if row:
+ obj.categories.add(SubCategory.objects.get(id=row[0]))
+ obj.save()
+ query = "ALTER TABLE main_%s DROP COLUMN subcategory_id;" % table
+ cursor.execute(query)
+ transaction.commit_unless_managed()
+ print " * main_%s_categories created" % table
+
+
# early versions before 0.1: save route with wrong SRID
# only errors with default SRID is managed adapt the script for your SRID
@@ -177,3 +278,4 @@ for route in routes:
route.save()
if changed:
print " * projections of routes corrected"
+
diff --git a/chimere/settings.py.example b/chimere/settings.py.example
index c0f6cb6..48785d5 100644
--- a/chimere/settings.py.example
+++ b/chimere/settings.py.example
@@ -31,6 +31,12 @@ DYNAMIC_CATEGORIES = False
DISPLAY_AREAS = True
# specific css for areas
CSS_AREAS = True
+# number of day before an event to display
+# if equal to 0: disable event management
+# if you change this value from 0 to a value in a production environnement
+# don't forget to run the upgrade.py script to create appropriate fields in
+# the database
+DAYS_BEFORE_EVENT = 30
# default id category to check on the map
DEFAULT_CATEGORIES = [1]
@@ -49,12 +55,16 @@ ADMINS = (
MANAGERS = ADMINS
-DATABASE_ENGINE = 'postgresql_psycopg2' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
-DATABASE_NAME = 'ratatouille' # Or path to database file if using sqlite3.
-DATABASE_USER = 'ratatouille' # Not used with sqlite3.
-DATABASE_PASSWORD = 'wiki' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
+DATABASES = {
+ 'default': {
+ 'NAME': 'ratatouille',
+ 'ENGINE': 'django.contrib.gis.db.backends.postgis',
+ 'HOST': 'localhost',
+ 'PORT': '5432',
+ 'USER': 'ratatouille',
+ 'PASSWORD': 'wiki',
+ },
+}
# Local time zone for this installation. Choices can be found here:
# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
@@ -118,12 +128,12 @@ MIDDLEWARE_CLASSES = (
ROOT_URLCONF = 'chimere.urls'
-TEMPLATE_DIRS = (
+TEMPLATE_DIRS = [
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
ROOT_PATH + 'templates',
-)
+]
INSTALLED_APPS = (
'django.contrib.auth',
@@ -132,5 +142,11 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.sites',
'chimere.main',
+ # activate it if you want to use migration scripts
'chimere.scripts',
+ # activate it if you want to use RSS feeds
+ 'chimere.rss'
)
+
+if 'chimere.rss' in INSTALLED_APPS:
+ TEMPLATE_DIRS.append(ROOT_PATH + 'rss/templates')
diff --git a/chimere/static/jquery/bsmSelect b/chimere/static/jquery/bsmSelect
new file mode 160000
+Subproject 69ff6a5a052de9e577909e310ccba8a0be67096
diff --git a/chimere/static/jquery/css/jquery.bsmselect.custom.css b/chimere/static/jquery/css/jquery.bsmselect.custom.css
new file mode 100644
index 0000000..8c48aeb
--- /dev/null
+++ b/chimere/static/jquery/css/jquery.bsmselect.custom.css
@@ -0,0 +1,45 @@
+.bsmListSortableCustom li {
+ cursor: move;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ margin: 2px 0;
+}
+
+.bsmList-custom {
+ /* html list that contains selected items */
+ margin: 0.25em 0 0.25em 0;
+ display: block;
+ padding-left: 0;
+ list-style: none;
+}
+
+.bsmListItem-custom {
+ /* li item from the html list above */
+ margin: 0 5px 5px 0;
+ padding: 4px;
+ list-style: none;
+ background: #ddd;
+ border: 1px solid #bbb;
+ line-height: 1em;
+ float: left;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+
+.bsmListItem-custom:hover {
+ background-color: #e5e5e5;
+ box-shadow: 0 0 3px #aaa;
+ -webkit-box-shadow: 0 0 3px #aaa;
+ -moz-box-shadow: 0 0 3px #aaa;
+}
+
+.bsmListItemLabel-custom {
+ padding-right: 5px;
+}
+
+.bsmListItemRemove-custom {
+ text-decoration: none;
+}
+
diff --git a/chimere/static/jquery/jquery-1.4.4.min.js b/chimere/static/jquery/jquery-1.4.4.min.js
new file mode 100644
index 0000000..8f3ca2e
--- /dev/null
+++ b/chimere/static/jquery/jquery-1.4.4.min.js
@@ -0,0 +1,167 @@
+/*!
+ * jQuery JavaScript Library v1.4.4
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu Nov 11 19:04:53 2010 -0500
+ */
+(function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h=
+h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;k<J.length;k++){h=J[k];h.origType.replace(X,"")===a.type?f.push(h.selector):J.splice(k--,1)}f=c(a.target).closest(f,a.currentTarget);o=0;for(x=f.length;o<x;o++){r=f[o];for(k=0;k<J.length;k++){h=J[k];if(r.selector===h.selector&&(!A||A.test(h.namespace))){l=r.elem;e=null;if(h.preType==="mouseenter"||
+h.preType==="mouseleave"){a.type=h.preType;e=c(a.relatedTarget).closest(h.selector)[0]}if(!e||e!==l)C.push({elem:l,handleObj:h,level:r.level})}}}o=0;for(x=C.length;o<x;o++){f=C[o];if(d&&f.level>d)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La,
+"`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this,
+e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a,
+"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+
+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j,
+s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this,
+j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length},
+toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j===
+-1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false;
+if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K<Q;K++)if((j=arguments[K])!=null)for(s in j){v=G[s];z=j[s];if(G!==z)if(ga&&z&&(b.isPlainObject(z)||(H=b.isArray(z)))){if(H){H=false;v=v&&b.isArray(v)?v:[]}else v=v&&b.isPlainObject(v)?v:{};G[s]=b.extend(ga,v,z)}else if(z!==B)G[s]=z}return G};b.extend({noConflict:function(j){E.$=e;if(j)E.jQuery=d;return b},isReady:false,readyWait:1,ready:function(j){j===true&&b.readyWait--;
+if(!b.readyWait||j!==true&&!b.isReady){if(!t.body)return setTimeout(b.ready,1);b.isReady=true;if(!(j!==true&&--b.readyWait>0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload",
+b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&&
+!F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&&
+l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H<G;){if(s.apply(j[H++],v)===false)break}else if(K)for(z in j){if(s.call(j[z],
+z,j[z])===false)break}else for(v=j[0];H<G&&s.call(v,H,v)!==false;v=j[++H]);return j},trim:O?function(j){return j==null?"":O.call(j)}:function(j){return j==null?"":j.toString().replace(k,"").replace(o,"")},makeArray:function(j,s){var v=s||[];if(j!=null){var z=b.type(j);j.length==null||z==="string"||z==="function"||z==="regexp"||b.isWindow(j)?M.call(v,j):b.merge(v,j)}return v},inArray:function(j,s){if(s.indexOf)return s.indexOf(j);for(var v=0,z=s.length;v<z;v++)if(s[v]===j)return v;return-1},merge:function(j,
+s){var v=j.length,z=0;if(typeof s.length==="number")for(var H=s.length;z<H;z++)j[v++]=s[z];else for(;s[z]!==B;)j[v++]=s[z++];j.length=v;return j},grep:function(j,s,v){var z=[],H;v=!!v;for(var G=0,K=j.length;G<K;G++){H=!!s(j[G],G);v!==H&&z.push(j[G])}return z},map:function(j,s,v){for(var z=[],H,G=0,K=j.length;G<K;G++){H=s(j[G],G,v);if(H!=null)z[z.length]=H}return z.concat.apply([],z)},guid:1,proxy:function(j,s,v){if(arguments.length===2)if(typeof s==="string"){v=j;j=v[s];s=B}else if(s&&!b.isFunction(s)){v=
+s;s=B}if(!s&&j)s=function(){return j.apply(v||this,arguments)};if(j)s.guid=j.guid=j.guid||s.guid||b.guid++;return s},access:function(j,s,v,z,H,G){var K=j.length;if(typeof s==="object"){for(var Q in s)b.access(j,Q,s[Q],z,H,v);return j}if(v!==B){z=!G&&z&&b.isFunction(v);for(Q=0;Q<K;Q++)H(j[Q],s,z?v.call(j[Q],Q,H(j[Q],s)):v,G);return j}return K?H(j[0],s):B},now:function(){return(new Date).getTime()},uaMatch:function(j){j=j.toLowerCase();j=L.exec(j)||g.exec(j)||i.exec(j)||j.indexOf("compatible")<0&&n.exec(j)||
+[];return{browser:j[1]||"",version:j[2]||"0"}},browser:{}});b.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(j,s){R["[object "+s+"]"]=s.toLowerCase()});m=b.uaMatch(m);if(m.browser){b.browser[m.browser]=true;b.browser.version=m.version}if(b.browser.webkit)b.browser.safari=true;if(D)b.inArray=function(j,s){return D.call(s,j)};if(!/\s/.test("\u00a0")){k=/^[\s\xA0]+/;o=/[\s\xA0]+$/}f=b(t);if(t.addEventListener)u=function(){t.removeEventListener("DOMContentLoaded",u,
+false);b.ready()};else if(t.attachEvent)u=function(){if(t.readyState==="complete"){t.detachEvent("onreadystatechange",u);b.ready()}};return E.jQuery=E.$=b}();(function(){c.support={};var a=t.documentElement,b=t.createElement("script"),d=t.createElement("div"),e="script"+c.now();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"),
+k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false,
+scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom=
+1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="<div style='width:4px;'></div>";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display=
+"none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h=
+c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando);
+else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h<l;h++){f=e[h].name;if(f.indexOf("data-")===0){f=f.substr(5);ka(this[0],f,d[f])}}}return d}else if(typeof a==="object")return this.each(function(){c.data(this,
+a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(b===B){d=this.triggerHandler("getData"+k[1]+"!",[k[0]]);if(d===B&&this.length){d=c.data(this[0],a);d=ka(this[0],a,d)}return d===B&&k[1]?this.data(k[0]):d}else return this.each(function(){var o=c(this),x=[k[0],b];o.triggerHandler("setData"+k[1]+"!",x);c.data(this,a,b);o.triggerHandler("changeData"+k[1]+"!",x)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e=
+c.data(a,b);if(!d)return e||[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===B)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,
+a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var sa=/[\n\t]/g,ha=/\s+/,Sa=/\r/g,Ta=/^(?:href|src|style)$/,Ua=/^(?:button|input)$/i,Va=/^(?:button|input|object|select|textarea)$/i,Wa=/^a(?:rea)?$/i,ta=/^(?:radio|checkbox)$/i;c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",
+colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(x){var r=c(this);r.addClass(a.call(this,x,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===
+1)if(f.className){for(var h=" "+f.className+" ",l=f.className,k=0,o=b.length;k<o;k++)if(h.indexOf(" "+b[k]+" ")<0)l+=" "+b[k];f.className=c.trim(l)}else f.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var x=c(this);x.removeClass(a.call(this,o,x.attr("class")))});if(a&&typeof a==="string"||a===B)for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1&&f.className)if(a){for(var h=(" "+f.className+" ").replace(sa," "),
+l=0,k=b.length;l<k;l++)h=h.replace(" "+b[l]+" "," ");f.className=c.trim(h)}else f.className=""}return this},toggleClass:function(a,b){var d=typeof a,e=typeof b==="boolean";if(c.isFunction(a))return this.each(function(f){var h=c(this);h.toggleClass(a.call(this,f,h.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var f,h=0,l=c(this),k=b,o=a.split(ha);f=o[h++];){k=e?k:!l.hasClass(f);l[k?"addClass":"removeClass"](f)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,
+"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(sa," ").indexOf(a)>-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one";
+if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h<e;h++){var l=f[h];if(l.selected&&(c.support.optDisabled?!l.disabled:l.getAttribute("disabled")===null)&&(!l.parentNode.disabled||!c.nodeName(l.parentNode,"optgroup"))){a=c(l).val();if(b)return a;d.push(a)}}return d}if(ta.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Sa,"")}return B}var k=c.isFunction(a);return this.each(function(o){var x=c(this),r=a;if(this.nodeType===1){if(k)r=
+a.call(this,o,x.val());if(r==null)r="";else if(typeof r==="number")r+="";else if(c.isArray(r))r=c.map(r,function(C){return C==null?"":C+""});if(c.isArray(r)&&ta.test(this.type))this.checked=c.inArray(x.val(),r)>=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},
+attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&
+b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0};
+c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,
+arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid=
+d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+
+c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h<A.length;h++){C=A[h];if(d.guid===C.guid){if(k||x.test(C.namespace)){e==null&&A.splice(h--,1);r.remove&&r.remove.call(a,C)}if(e!=null)break}}if(A.length===0||e!=null&&A.length===1){if(!r.teardown||r.teardown.call(a,o)===false)c.removeEvent(a,f,w.handle);delete I[f]}}else for(h=0;h<A.length;h++){C=A[h];if(k||x.test(C.namespace)){c.event.remove(a,r,C.handler,h);A.splice(h--,1)}}}if(c.isEmptyObject(I)){if(b=
+w.handle)b.elem=null;delete w.events;delete w.handle;if(typeof w==="function")c.removeData(a,J);else c.isEmptyObject(w)&&c.removeData(a)}}}}},trigger:function(a,b,d,e){var f=a.type||a;if(!e){a=typeof a==="object"?a[c.expando]?a:c.extend(c.Event(f),a):c.Event(f);if(f.indexOf("!")>=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
+8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k===
+"click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+
+d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f<l;f++){var k=d[f];if(b||e.test(k.namespace)){a.handler=k.handler;a.data=k.data;a.handleObj=k;k=k.handler.apply(this,h);if(k!==B){a.result=k;if(k===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[c.expando])return a;var b=a;a=c.Event(b);for(var d=this.props.length,e;d;){e=this.props[--d];a[e]=b[e]}if(!a.target)a.target=a.srcElement||t;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=t.documentElement;d=t.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(a.which==null&&(a.charCode!=null||a.keyCode!=null))a.which=a.charCode!=null?a.charCode:a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==B)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,Y(a.origType,a.selector),c.extend({},a,{handler:Ka,guid:a.handler.guid}))},remove:function(a){c.event.remove(this,
+Y(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,d){if(c.isWindow(this))this.onbeforeunload=d},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.removeEvent=t.removeEventListener?function(a,b,d){a.removeEventListener&&a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent&&a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=
+c.now();this[c.expando]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ca;var a=this.originalEvent;if(a)if(a.preventDefault)a.preventDefault();else a.returnValue=false},stopPropagation:function(){this.isPropagationStopped=ca;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ca;this.stopPropagation()},isDefaultPrevented:U,isPropagationStopped:U,isImmediatePropagationStopped:U};
+var va=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},wa=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?wa:va,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?wa:va)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(){if(this.nodeName.toLowerCase()!==
+"form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length){a.liveFired=B;return la("submit",this,arguments)}});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13){a.liveFired=B;return la("submit",this,arguments)}})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};if(!c.support.changeBubbles){var V,
+xa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired=
+B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type===
+"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]===
+0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h<k;h++)c.event.add(this[h],d,l,e)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var d in a)this.unbind(d,
+a[d]);else{d=0;for(var e=this.length;d<e;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,e){return this.live(b,d,e,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var d=c.Event(a);d.preventDefault();d.stopPropagation();c.event.trigger(d,b,this[0]);return d.result}},toggle:function(a){for(var b=arguments,d=
+1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(e){var f=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,f+1);e.preventDefault();return b[f].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var ya={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,e,f,h){var l,k=0,o,x,r=h||this.selector;h=h?this:c(this.context);if(typeof d===
+"object"&&!d.preventDefault){for(l in d)h[b](l,e,d[l],r);return this}if(c.isFunction(e)){f=e;e=B}for(d=(d||"").split(" ");(l=d[k++])!=null;){o=X.exec(l);x="";if(o){x=o[0];l=l.replace(X,"")}if(l==="hover")d.push("mouseenter"+x,"mouseleave"+x);else{o=l;if(l==="focus"||l==="blur"){d.push(ya[l]+x);l+=x}else l=(ya[l]||l)+x;if(b==="live"){x=0;for(var A=h.length;x<A;x++)c.event.add(h[x],"live."+Y(l,r),{data:e,selector:r,handler:f,origType:l,origHandler:f,preType:o})}else h.unbind("live."+Y(l,r),f)}}return this}});
+c.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".split(" "),function(a,b){c.fn[b]=function(d,e){if(e==null){e=d;d=null}return arguments.length>0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
+(function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1&&!q){y.sizcache=n;y.sizset=p}if(y.nodeName.toLowerCase()===i){F=y;break}y=y[g]}m[p]=F}}}function b(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1){if(!q){y.sizcache=n;y.sizset=p}if(typeof i!=="string"){if(y===i){F=true;break}}else if(k.filter(i,
+[y]).length>0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3];
+break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr,
+q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h=
+l;g.sort(w);if(h)for(var i=1;i<g.length;i++)g[i]===g[i-1]&&g.splice(i--,1)}return g};k.matches=function(g,i){return k(g,null,null,i)};k.matchesSelector=function(g,i){return k(i,null,null,[g]).length>0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p<q;p++){var u,y=o.order[p];if(u=o.leftMatch[y].exec(g)){var F=u[1];u.splice(1,1);if(F.substr(F.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");m=o.find[y](u,i,n);if(m!=null){g=g.replace(o.match[y],"");break}}}}m||(m=i.getElementsByTagName("*"));
+return{set:m,expr:g}};k.filter=function(g,i,n,m){for(var p,q,u=g,y=[],F=i,M=i&&i[0]&&k.isXML(i[0]);g&&i.length;){for(var N in o.filter)if((p=o.leftMatch[N].exec(g))!=null&&p[2]){var O,D,R=o.filter[N];D=p[1];q=false;p.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(F===y)y=[];if(o.preFilter[N])if(p=o.preFilter[N](p,F,n,y,m,M)){if(p===true)continue}else q=O=true;if(p)for(var j=0;(D=F[j])!=null;j++)if(D){O=R(D,p,j,F);var s=m^!!O;if(n&&O!=null)if(s)q=true;else F[j]=false;else if(s){y.push(D);q=true}}if(O!==
+B){n||(F=y);g=g.replace(o.match[N],"");if(!q)return[];break}}}if(g===u)if(q==null)k.error(g);else break;u=g}return F};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var o=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
+POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,i){var n=typeof i==="string",m=n&&!/\W/.test(i);n=n&&!m;if(m)i=i.toLowerCase();m=0;for(var p=g.length,q;m<p;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=n||q&&q.nodeName.toLowerCase()===
+i?q||false:q===i}n&&k.filter(i,g,true)},">":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p<q;p++){if(n=g[p]){n=n.parentNode;g[p]=n.nodeName.toLowerCase()===i?n:false}}else{for(;p<q;p++)if(n=g[p])g[p]=m?n.parentNode:n.parentNode===i;m&&k.filter(i,g,true)}},"":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=i=i.toLowerCase();q=a}q("parentNode",i,p,g,m,n)},"~":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=
+i=i.toLowerCase();q=a}q("previousSibling",i,p,g,m,n)}},find:{ID:function(g,i,n){if(typeof i.getElementById!=="undefined"&&!n)return(g=i.getElementById(g[1]))&&g.parentNode?[g]:[]},NAME:function(g,i){if(typeof i.getElementsByName!=="undefined"){for(var n=[],m=i.getElementsByName(g[1]),p=0,q=m.length;p<q;p++)m[p].getAttribute("name")===g[1]&&n.push(m[p]);return n.length===0?null:n}},TAG:function(g,i){return i.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,i,n,m,p,q){g=" "+g[1].replace(/\\/g,
+"")+" ";if(q)return g;q=0;for(var u;(u=i[q])!=null;q++)if(u)if(p^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n,
+m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===
+true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===
+g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return i<n[3]-0},gt:function(g,i,n){return i>n[3]-0},nth:function(g,i,n){return n[3]-
+0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n<m;n++)if(i[n]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+p)},CHILD:function(g,i){var n=i[1],m=g;switch(n){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(n===
+"first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":n=i[2];var p=i[3];if(n===1&&p===0)return true;var q=i[0],u=g.parentNode;if(u&&(u.sizcache!==q||!g.nodeIndex)){var y=0;for(m=u.firstChild;m;m=m.nextSibling)if(m.nodeType===1)m.nodeIndex=++y;u.sizcache=q}m=g.nodeIndex-p;return n===0?m===0:m%n===0&&m/n>=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===
+i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]];
+if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m,
+g);else if(typeof g.length==="number")for(var p=g.length;n<p;n++)m.push(g[n]);else for(;g[n];n++)m.push(g[n]);return m}}var w,I;if(t.documentElement.compareDocumentPosition)w=function(g,i){if(g===i){h=true;return 0}if(!g.compareDocumentPosition||!i.compareDocumentPosition)return g.compareDocumentPosition?-1:1;return g.compareDocumentPosition(i)&4?-1:1};else{w=function(g,i){var n,m,p=[],q=[];n=g.parentNode;m=i.parentNode;var u=n;if(g===i){h=true;return 0}else if(n===m)return I(g,i);else if(n){if(!m)return 1}else return-1;
+for(;u;){p.unshift(u);u=u.parentNode}for(u=m;u;){q.unshift(u);u=u.parentNode}n=p.length;m=q.length;for(u=0;u<n&&u<m;u++)if(p[u]!==q[u])return I(p[u],q[u]);return u===n?I(g,q[u],-1):I(p[u],i,1)};I=function(g,i,n){if(g===i)return n;for(g=g.nextSibling;g;){if(g===i)return-1;g=g.nextSibling}return 1}}k.getText=function(g){for(var i="",n,m=0;g[m];m++){n=g[m];if(n.nodeType===3||n.nodeType===4)i+=n.nodeValue;else if(n.nodeType!==8)i+=k.getText(n.childNodes)}return i};(function(){var g=t.createElement("div"),
+i="script"+(new Date).getTime(),n=t.documentElement;g.innerHTML="<a name='"+i+"'/>";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g);
+n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&&
+function(){var g=k,i=t.createElement("div");i.innerHTML="<p class='TEST'></p>";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F||
+p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g=
+t.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition?
+function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n<u;n++)k(g,q[n],m);return k.filter(p,m)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=k.getText;c.isXMLDoc=k.isXML;
+c.contains=k.contains})();var Za=/Until$/,$a=/^(?:parents|prevUntil|prevAll)/,ab=/,/,Na=/^.[^:#\[\.,]*$/,bb=Array.prototype.slice,cb=c.expr.match.POS;c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,e=0,f=this.length;e<f;e++){d=b.length;c.find(a,this[e],b);if(e>0)for(var h=d;h<b.length;h++)for(var l=0;l<d;l++)if(b[l]===b[h]){b.splice(h--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,e=b.length;d<e;d++)if(c.contains(this,b[d]))return true})},
+not:function(a){return this.pushStack(ma(this,a,false),"not",a)},filter:function(a){return this.pushStack(ma(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e<f;e++){l=a[e];k[l]||(k[l]=c.expr.match.POS.test(l)?c(l,b||this.context):l)}for(;h&&h.ownerDocument&&h!==b;){for(l in k){e=k[l];if(e.jquery?e.index(h)>-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h=
+h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e<f;e++)for(h=this[e];h;)if(l?l.index(h)>-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):
+c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,
+2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,
+b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&
+e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/<tbody/i,eb=/<|&#?\w+;/,Ca=/<(?:script|object|embed|option|style)/i,Da=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/\=([^="'>\s]+\/)>/g,P={option:[1,
+"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null;
+else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1></$2>");try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(e){this.empty().append(a)}}else c.isFunction(a)?this.each(function(f){var h=c(this);h.html(a.call(this,f,h.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=
+c(this),e=d.html();d.replaceWith(a.call(this,b,e))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){var e,f,h,l=a[0],k=[];if(!c.support.checkClone&&arguments.length===3&&typeof l==="string"&&Da.test(l))return this.each(function(){c(this).domManip(a,
+b,d,true)});if(c.isFunction(l))return this.each(function(x){var r=c(this);a[0]=l.call(this,x,b?r.html():B);r.domManip(a,b,d)});if(this[0]){e=l&&l.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:c.buildFragment(a,this,k);h=e.fragment;if(f=h.childNodes.length===1?h=h.firstChild:h.firstChild){b=b&&c.nodeName(f,"tr");f=0;for(var o=this.length;f<o;f++)d.call(b?c.nodeName(this[f],"table")?this[f].getElementsByTagName("tbody")[0]||this[f].appendChild(this[f].ownerDocument.createElement("tbody")):
+this[f]:this[f],f>0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",
+prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f<h;f++){var l=(f>0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument||
+b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1></$2>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]==="<table>"&&!x?r.childNodes:[];for(o=k.length-
+1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));
+d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i,
+jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,
+zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),
+h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b);
+if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=
+d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left;
+e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b===
+"object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("<div>").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&
+!this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})},
+getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html",
+script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data||
+!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache=
+false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset;
+A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type",
+b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&&
+c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d||
+c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]=
+encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess",
+[b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),
+e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}});
+if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show",
+3),a,b,d);else{d=0;for(var e=this.length;d<e;d++){a=this[d];b=a.style.display;if(!c.data(a,"olddisplay")&&b==="none")b=a.style.display="";b===""&&c.css(a,"display")==="none"&&c.data(a,"olddisplay",qa(a.nodeName))}for(d=0;d<e;d++){a=this[d];b=a.style.display;if(b===""||b==="none")a.style.display=c.data(a,"olddisplay")||""}return this}},hide:function(a,b,d){if(a||a===0)return this.animate(S("hide",3),a,b,d);else{a=0;for(b=this.length;a<b;a++){d=c.css(this[a],"display");d!=="none"&&c.data(this[a],"olddisplay",
+d)}for(a=0;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b,d){var e=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||e?this.each(function(){var f=e?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(S("toggle",3),a,b,d);return this},fadeTo:function(a,b,d,e){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d,e)},animate:function(a,b,d,e){var f=c.speed(b,
+d,e);if(c.isEmptyObject(a))return this.each(f.complete);return this[f.queue===false?"each":"queue"](function(){var h=c.extend({},f),l,k=this.nodeType===1,o=k&&c(this).is(":hidden"),x=this;for(l in a){var r=c.camelCase(l);if(l!==r){a[r]=a[l];delete a[l];l=r}if(a[l]==="hide"&&o||a[l]==="show"&&!o)return h.complete.call(this);if(k&&(l==="height"||l==="width")){h.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(c.css(this,"display")==="inline"&&c.css(this,"float")==="none")if(c.support.inlineBlockNeedsLayout)if(qa(this.nodeName)===
+"inline")this.style.display="inline-block";else{this.style.display="inline";this.style.zoom=1}else this.style.display="inline-block"}if(c.isArray(a[l])){(h.specialEasing=h.specialEasing||{})[l]=a[l][1];a[l]=a[l][0]}}if(h.overflow!=null)this.style.overflow="hidden";h.curAnim=c.extend({},a);c.each(a,function(A,C){var J=new c.fx(x,h,A);if(vb.test(C))J[C==="toggle"?o?"show":"hide":C](a);else{var w=wb.exec(C),I=J.cur()||0;if(w){var L=parseFloat(w[2]),g=w[3]||"px";if(g!=="px"){c.style(x,A,(L||1)+g);I=(L||
+1)/J.cur()*I;c.style(x,A,I+g)}if(w[1])L=(w[1]==="-="?-1:1)*L+I;J.custom(I,L,g)}else J.custom(I,C,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var e=d.length-1;e>=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b,
+d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a*
+Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)}
+var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;
+this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide||
+this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=
+c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},interval:13,stop:function(){clearInterval(ba);ba=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===
+b.elem}).length};var xb=/^t(?:able|d|h)$/i,Ia=/^(?:body|html)$/i;c.fn.offset="getBoundingClientRect"in t.documentElement?function(a){var b=this[0],d;if(a)return this.each(function(l){c.offset.setOffset(this,a,l)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);try{d=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,h=f.documentElement;if(!d||!c.contains(h,b))return d||{top:0,left:0};b=f.body;f=fa(f);return{top:d.top+(f.pageYOffset||c.support.boxModel&&
+h.scrollTop||b.scrollTop)-(h.clientTop||b.clientTop||0),left:d.left+(f.pageXOffset||c.support.boxModel&&h.scrollLeft||b.scrollLeft)-(h.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(x){c.offset.setOffset(this,a,x)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d,e=b.offsetParent,f=b.ownerDocument,h=f.documentElement,l=f.body;d=(f=f.defaultView)?f.getComputedStyle(b,null):b.currentStyle;
+for(var k=b.offsetTop,o=b.offsetLeft;(b=b.parentNode)&&b!==l&&b!==h;){if(c.offset.supportsFixedPosition&&d.position==="fixed")break;d=f?f.getComputedStyle(b,null):b.currentStyle;k-=b.scrollTop;o-=b.scrollLeft;if(b===e){k+=b.offsetTop;o+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&xb.test(b.nodeName))){k+=parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}e=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"){k+=
+parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}d=d}if(d.position==="relative"||d.position==="static"){k+=l.offsetTop;o+=l.offsetLeft}if(c.offset.supportsFixedPosition&&d.position==="fixed"){k+=Math.max(h.scrollTop,l.scrollTop);o+=Math.max(h.scrollLeft,l.scrollLeft)}return{top:k,left:o}};c.offset={initialize:function(){var a=t.body,b=t.createElement("div"),d,e,f,h=parseFloat(c.css(a,"marginTop"))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",
+height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);d=b.firstChild;e=d.firstChild;f=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=e.offsetTop!==5;this.doesAddBorderForTableAndCells=
+f.offsetTop===5;e.style.position="fixed";e.style.top="20px";this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15;e.style.position=e.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==h;a.removeChild(b);c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.css(a,
+"marginTop"))||0;d+=parseFloat(c.css(a,"marginLeft"))||0}return{top:b,left:d}},setOffset:function(a,b,d){var e=c.css(a,"position");if(e==="static")a.style.position="relative";var f=c(a),h=f.offset(),l=c.css(a,"top"),k=c.css(a,"left"),o=e==="absolute"&&c.inArray("auto",[l,k])>-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a,
+e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&&
+c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();
+c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+
+b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window);
diff --git a/chimere/static/styles.css b/chimere/static/styles.css
index 893062d..21fbb2e 100644
--- a/chimere/static/styles.css
+++ b/chimere/static/styles.css
@@ -569,4 +569,3 @@ padding:0;
background-color:transparent;
color:#b488ff;
.simple .cloud img{display:None;}
-
diff --git a/chimere/templates/404.html b/chimere/templates/404.html
new file mode 100644
index 0000000..d7d0de0
--- /dev/null
+++ b/chimere/templates/404.html
@@ -0,0 +1,5 @@
+{% load i18n %}
+{% extends "base.html" %}
+{% block content %}
+<h2>{% trans "Page not found" %}</h2>
+{% endblock %}
diff --git a/chimere/templates/500.html b/chimere/templates/500.html
new file mode 100644
index 0000000..a230d92
--- /dev/null
+++ b/chimere/templates/500.html
@@ -0,0 +1,5 @@
+{% load i18n %}
+{% extends "base.html" %}
+{% block content %}
+<h2>{% trans "Internal server error"%}</h2>
+{% endblock %}
diff --git a/chimere/templates/detail.html b/chimere/templates/detail.html
index 94f8eae..d7084db 100644
--- a/chimere/templates/detail.html
+++ b/chimere/templates/detail.html
@@ -2,7 +2,12 @@
<h2>{{ marker.name }}</h2>
<div id='detail_content'>
{% if marker.picture %}<img src='{{media_path}}{{marker.picture}}' alt='{{marker.name}}'/>{%endif%}
-<div>{% for property in marker.getProperties %}
+<div>
+{% if dated %}
+<p id='detail_start_date'><label>{% trans "Date:" %}</label> <span>{{marker.start_date|date:"D d M Y"}}
+{% if marker.end_date %} - {{marker.end_date|date:"D d M Y"}}</p>{% endif %}</span>
+{% endif %}
+{% for property in marker.getProperties %}
<p id='{{property.propertymodel.getNamedId}}'>{{ property.value|safe }}</p>
{% endfor %}</div>{% if share_networks %}
{% if simple %}{% trans "Share on"%}{% for share_network in share_networks %}
diff --git a/chimere/templates/edit.html b/chimere/templates/edit.html
index 0e1f6d7..4a02fe4 100644
--- a/chimere/templates/edit.html
+++ b/chimere/templates/edit.html
@@ -1,5 +1,12 @@
{% extends "base_user.html" %}
{% load i18n %}
+{% block extra_head %}
+{% if dated %}<script type="text/javascript" src="{{extra_url}}admin/jsi18n"></script>
+<script type="text/javascript" src="{{extra_url}}media/js/core.js"></script>
+<link rel="stylesheet" type="text/css" href="{{extra_url}}media/css/base.css"/>
+<link rel="stylesheet" type="text/css" href="{{extra_url}}media/css/widgets.css"/>
+{% endif %}{{ block.super }}
+{% endblock %}
{% block message_map %}{% endblock %}
{% block message_edit%}<div id='content'>{{block.super}}{% endblock %}
@@ -15,18 +22,9 @@
{{ form.name }}
</div>
<div class="fieldWrapper">
- <label for="id_subcategory">{% trans "Category" %} *</label>
- {{ form.subcategory.errors }}
- <select name='subcategory' id='subcategory'>
- <option value="">---------</option>
- {% for cat_subcat in sub_categories %}
- <optgroup label="{{cat_subcat.0.name}}">
- {% for sub_category in cat_subcat.1 %}
- <option value='{{sub_category.id}}'{% ifequal sub_category.id current_category %} selected='selected'{% endifequal %}>
- {% trans sub_category.name %}
- </option>{% endfor %}
- </optgroup>{% endfor %}
- </select>
+ <label for="id_subcategory">{% trans "Categories" %} *</label>
+ {{ form.categories.errors }}
+ {{ form.categories }}
</div>
<div class="fieldWrapper">
<label for="id_point">{% trans "Point"%} *</label>
@@ -38,6 +36,20 @@
{{ form.picture.errors }}
{{ form.picture }}
</div>
+{% if dated %}
+<div class="fieldWrapper">
+ <label for="id_start_date">{% trans "Start date" %}</label>
+ {{ form.start_date.errors }}
+ {{ form.start_date }}
+ <p class="help">{{ form.start_date.help_text }}</p>
+</div>
+<div class="fieldWrapper">
+ <label for="id_end_date">{% trans "End date" %}</label>
+ {{ form.end_date.errors }}
+ {{ form.end_date }}
+ <p class="help">{{ form.end_date.help_text }}</p>
+</div>
+{% endif %}
{%for field in form%}{%for property in properties%}{%ifequal field.name property%}
<div class="fieldWrapper">
<label for="id_{{field.name}}">{% trans field.label %}</label>
diff --git a/chimere/templates/edit_route.html b/chimere/templates/edit_route.html
index 5168001..5152ba5 100644
--- a/chimere/templates/edit_route.html
+++ b/chimere/templates/edit_route.html
@@ -1,5 +1,12 @@
{% extends "base_user.html" %}
{% load i18n %}
+{% block extra_head %}
+{% if dated %}<script type="text/javascript" src="{{extra_url}}admin/jsi18n"></script>
+<script type="text/javascript" src="{{extra_url}}media/js/core.js"></script>
+<link rel="stylesheet" type="text/css" href="{{extra_url}}media/css/base.css"/>
+<link rel="stylesheet" type="text/css" href="{{extra_url}}media/css/widgets.css"/>
+{% endif %}{{ block.super }}
+{% endblock %}
{% block message_map %}{% endblock %}
{% block message_edit%}<div id='content'>{{block.super}}{% endblock %}
{% block content %}{{ block.super }}
@@ -14,18 +21,9 @@
{{ form.name }}
</div>
<div class="fieldWrapper">
- <label for="id_subcategory">{% trans "Category" %} *</label>
- {{ form.subcategory.errors }}
- <select name='subcategory' id='subcategory'>
- <option value="">---------</option>
- {% for cat_subcat in sub_categories %}
- <optgroup label="{{cat_subcat.0.name}}">
- {% for sub_category in cat_subcat.1 %}
- <option value='{{sub_category.id}}'{% ifequal sub_category.id current_category %} selected='selected'{% endifequal %}>
- {% trans sub_category.name %}
- </option>{% endfor %}
- </optgroup>{% endfor %}
- </select>
+ <label for="id_subcategory">{% trans "Categories" %} *</label>
+ {{ form.categories.errors }}
+ {{ form.categories }}
</div>
<div class="fieldWrapper">
<label for="id_route">{% trans "Route"%} *</label>
@@ -38,6 +36,20 @@
{{ form.picture.errors }}
{{ form.picture }}
</div>-->
+{% if dated %}
+<div class="fieldWrapper">
+ <label for="id_start_date">{% trans "Start date" %}</label>
+ {{ form.start_date.errors }}
+ {{ form.start_date }}
+ <p class="help">{{ form.start_date.help_text }}</p>
+</div>
+<div class="fieldWrapper">
+ <label for="id_end_date">{% trans "End date" %}</label>
+ {{ form.end_date.errors }}
+ {{ form.end_date }}
+ <p class="help">{{ form.end_date.help_text }}</p>
+</div>
+{% endif %}
{%for field in form%}{%for property in properties%}{%ifequal field.name property%}
<div class="fieldWrapper">
<label for="id_{{field.name}}">{% trans field.label %}</label>
diff --git a/chimere/urls.py b/chimere/urls.py
index 407deff..331dbbe 100644
--- a/chimere/urls.py
+++ b/chimere/urls.py
@@ -23,7 +23,7 @@ from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
-from settings import ROOT_PATH, EXTRA_URL
+from settings import ROOT_PATH, EXTRA_URL, INSTALLED_APPS
from main.models import Area
@@ -31,48 +31,54 @@ js_info_dict = {
'packages': 'chimere',
}
-base = '^' + EXTRA_URL
+BASE = '^' + EXTRA_URL
urlpatterns = patterns('',
- (base + r'admin/(.*)', admin.site.root),
- (base + r'static/(?P<path>.*)$', 'django.views.static.serve',
+ (BASE + r'admin/(.*)', admin.site.root),
+ (BASE + r'static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': ROOT_PATH + 'static/'}),
- (base + r'media/(?P<path>.*)$', 'django.views.static.serve',
+ (BASE + r'media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': ROOT_PATH + 'media/'}),
- (base + r'jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
- (base + r'charte/$', 'chimere.main.views.charte'),
+ (BASE + r'jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
+ (BASE + r'charte/$', 'chimere.main.views.charte'),
)
urlpatterns += patterns('chimere.main.views',
)
url_areas = Area.objects.filter(urn__isnull=False)
-urlpatterns += patterns('chimere.main.views', (base + r'$', 'index'),
- (base + r'simple/?$', 'index', {'simple':True}) )
+urlpatterns += patterns('chimere.main.views', (BASE + r'$', 'index'),
+ (BASE + r'simple/?$', 'index', {'simple':True}) )
for area in url_areas:
urlpatterns += patterns('chimere.main.views',
- (base + '(' + area.urn + ')/?$', 'index', {'default_area':area}),
- (base + '(' + area.urn + ')/simple/?$', 'index', {'default_area':area,
+ (BASE + '(' + area.urn + ')/?$', 'index', {'default_area':area}),
+ (BASE + '(' + area.urn + ')/simple/?$', 'index', {'default_area':area,
'simple':True}),)
-extra = "|".join([area.urn for area in url_areas])
+EXTRA = "|".join([area.urn for area in url_areas])
default_dct = {}
-if extra:
- extra = "(?P<area_name>%s)?/?" % extra
+EXTRA_NO_AREA = EXTRA
+if EXTRA:
+ EXTRA_NO_AREA = "(%s)?/?" % EXTRA
+ EXTRA = "(?P<area_name>%s)?/?" % EXTRA
else:
default_dct = {'area_name':''}
urlpatterns += patterns('chimere.main.views',
-(base + extra + r'contact/$', 'contactus', default_dct),
-(base + extra + r'edit/$', 'edit', default_dct),
-(base + extra + r'edit_route/$', 'editRoute', default_dct),
-(base + extra + r'submited/(?P<action>\w+)/$', 'submited', default_dct),
-(base + extra + r'getDetail/(?P<marker_id>\d+)/$', 'getDetail', default_dct),
-(base + extra + r'getDescriptionDetail/(?P<category_id>\d+)/$',
+(BASE + EXTRA + r'contact/$', 'contactus', default_dct),
+(BASE + EXTRA + r'edit/$', 'edit', default_dct),
+(BASE + EXTRA + r'edit_route/$', 'editRoute', default_dct),
+(BASE + EXTRA + r'submited/(?P<action>\w+)/$', 'submited', default_dct),
+(BASE + EXTRA + r'getDetail/(?P<marker_id>\d+)/$', 'getDetail', default_dct),
+(BASE + EXTRA + r'getDescriptionDetail/(?P<category_id>\d+)/$',
'getDescriptionDetail', default_dct),
-(base + extra + r'getGeoObjects/(?P<category_ids>\w+)(/(?P<status>\w+))?$',
+(BASE + EXTRA + r'getGeoObjects/(?P<category_ids>\w+)(/(?P<status>\w+))?$',
'getGeoObjects', default_dct),
-(base + extra + r'getAvailableCategories/((?P<area>\w+))?(/(?P<status>\w+))?(/(?P<force>\w+))?$',
+(BASE + EXTRA + r'getAvailableCategories/((?P<area>\w+))?(/(?P<status>\w+))?(/(?P<force>\w+))?$',
'getAvailableCategories', default_dct),
-(base + extra + r'ty/(?P<tiny_urn>\w+)$', 'redirectFromTinyURN', default_dct),
+(BASE + EXTRA + r'ty/(?P<tiny_urn>\w+)$', 'redirectFromTinyURN', default_dct),
)
+
+if 'chimere.rss' in INSTALLED_APPS:
+ urlpatterns += patterns('',
+ (r'^' + EXTRA_URL, include('chimere.rss.urls')),)
diff --git a/docs/en/INSTALL.t2t b/docs/en/INSTALL.t2t
index 01ddd9a..9cfdd25 100644
--- a/docs/en/INSTALL.t2t
+++ b/docs/en/INSTALL.t2t
@@ -30,7 +30,7 @@ Optionaly (but recommanded):
- [tinymce http://tinymce.moxiecode.com/]
-The simpliest way to obtain these packages is to get them from your favorite Linux distribution repositories (for instance python, python-django, tinymce, apache2, libapache2-mod-python, libgeos-3.0.0, proj, gdal-bin, python-psycopg2, python-imaging, postgresql-8.3 and postgresql-8.3-postgis packages for Debian Lenny). If these packages do not exist in your distribution's repository, please refer to the applications' websites.
+The simpliest way to obtain these packages is to get them from your favorite Linux distribution repositories (for instance python, python-django, tinymce, apache2, libapache2-mod-python, libgeos-3.2.0, proj, gdal-bin, python-psycopg2, python-imaging, postgresql-8.4 and postgresql-8.4-postgis packages for Debian Squeeze). If these packages do not exist in your distribution's repository, please refer to the applications' websites.
+++ Database configuration +++
@@ -57,6 +57,8 @@ Another solution is to get the last git version:
```
git clone git://www.peacefrogs.net/git/chimere
+git tag -l # list tagged versions
+git checkout v1.0.0 # checkout the desired version
```
+++ Install the sources +++
diff --git a/docs/en/UPGRADE.t2t b/docs/en/UPGRADE.t2t
index 1e874fe..0f5a068 100644
--- a/docs/en/UPGRADE.t2t
+++ b/docs/en/UPGRADE.t2t
@@ -119,7 +119,7 @@ In "settings.py" verify that "chimere.scripts" is in the INSTALLED_APPS.
After that in the chimere directory just execute the script:
```
-python ./scripts/upgrade
+$ python ./scripts/upgrade
```
+ Point to the new installation +