You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/02/27 13:50:34 UTC

[01/26] allura git commit: Docs for outgoing mail setup for development.

Repository: allura
Updated Branches:
  refs/heads/ib/7830 e37f9437e -> 7c2bef4e5 (forced update)


Docs for outgoing mail setup for development.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/aa14b0d8
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/aa14b0d8
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/aa14b0d8

Branch: refs/heads/ib/7830
Commit: aa14b0d8f56b4cbb4e2c9c9ae095d1851ae4f719
Parents: a3620b4
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Sat Feb 14 18:39:25 2015 -0500
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Feb 19 15:54:48 2015 +0000

----------------------------------------------------------------------
 Allura/development.ini             | 12 ++++++++++++
 Allura/docs/conf.py                |  1 -
 Allura/docs/contributing.rst       |  6 +++---
 Allura/docs/faq.rst                |  8 ++++----
 Allura/docs/guides/email.rst       |  6 +++---
 Allura/docs/guides/message_bus.rst | 10 +++++-----
 Allura/docs/guides/permissions.rst | 10 +++++-----
 Allura/docs/guides/scm.rst         | 12 ++++++------
 Allura/docs/index.rst              | 16 ++++++++--------
 Allura/docs/installation.rst       | 21 +++++++++++++++++----
 Allura/docs/intro.rst              |  4 ++--
 Allura/docs/online.rst             | 10 +++++-----
 Allura/docs/platform.rst           | 10 +++++-----
 Allura/docs/platform_tour.rst      | 14 +++++++-------
 Allura/docs/scm_host.rst           | 12 ++++++------
 Allura/docs/scm_host_ssh.rst       | 12 ++++++------
 INSTALL.markdown                   | 11 +++++++----
 17 files changed, 101 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 68b6267..993c4a5 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -27,8 +27,20 @@
 debug = true
 # Uncomment and replace with the address which should receive any error reports
 #email_to = you@yourdomain.com
+
+# Smtp settings
+;smtp_tls = False
+;smtp_ssl = True
+;smtp_user = some_user
+;smtp_password = some_password
+;smtp_timeout = 10
 smtp_server = localhost
 smtp_port = 8826
+
+# Spam filtering service: mollom or akismet
+;spam.method = akismet
+;spam.key =
+
 error_email_from = paste@localhost
 ; Used to uniquify references to static resources, can be a timestamp or any unique value
 ; This should be updated each time you deploy (or make significant changes, like new tools, new css)

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/conf.py
----------------------------------------------------------------------
diff --git a/Allura/docs/conf.py b/Allura/docs/conf.py
index 14651da..03ad27f 100644
--- a/Allura/docs/conf.py
+++ b/Allura/docs/conf.py
@@ -102,7 +102,6 @@ pygments_style = 'sphinx'
 # A list of ignored prefixes for module index sorting.
 #modindex_common_prefix = []
 
-
 # -- Options for HTML output ---------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  Major themes that come with

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/contributing.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/contributing.rst b/Allura/docs/contributing.rst
index 1635424..e899d05 100644
--- a/Allura/docs/contributing.rst
+++ b/Allura/docs/contributing.rst
@@ -59,9 +59,9 @@ Allura services:
 
 Logging
 -------
-The logs for Allura services can be found in ``/var/log/`` (Vagrant setup) or
-``~/logs/`` (manual setup). The most important of these is ``allura.log``, as
-it will contain log messages for all Allura application code.
+The logs for Allura services can be found in ``/var/log/allura/``.
+The most important of these is ``allura.log``, as it will contain log messages
+for all Allura application code.
 
 Technology Stack
 ----------------

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/faq.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/faq.rst b/Allura/docs/faq.rst
index 95795a2..0c26b43 100644
--- a/Allura/docs/faq.rst
+++ b/Allura/docs/faq.rst
@@ -16,7 +16,7 @@
        under the License.
 
 Why not improve existing tools like Trac, Redmine or Bugzilla?
----------------------------------------------------------------------
+--------------------------------------------------------------
 
 One word.  Scalability.
 
@@ -34,7 +34,7 @@ so we did take a long look at Roundup, which is a very well designed
 system build from the ground up around the idea of e-mail integration.
 
 If you were so inspired by Roundup, why not just use it?
----------------------------------------------------------------------
+--------------------------------------------------------
 
 We liked the flexible schema system provided by Roundup's HyperTable layer,
 but thought that native MongoDB bindings were both cleaner, faster, and
@@ -45,7 +45,7 @@ backend, but our main goal is to make usable, high performance system,
 not to maximize the number of backend storages systems supported.
 
 Why create all the apps as plugins?
----------------------------------------------------------------------
+-----------------------------------
 
 We know that some projects are going to want more locked down
 access controls in their bug trackers, or more workflow based
@@ -58,7 +58,7 @@ integration points makes it possible to serve everybody in one
 way or another.
 
 Why not just allow web-based extensions?
----------------------------------------------------------------------
+----------------------------------------
 
 We talked about this quite a bit, and decided that we could write local
 native tools more quickly and easily, and that we could build a

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/guides/email.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/guides/email.rst b/Allura/docs/guides/email.rst
index d238321..d88105e 100644
--- a/Allura/docs/guides/email.rst
+++ b/Allura/docs/guides/email.rst
@@ -16,10 +16,10 @@
        under the License.
 
 Guide to email integration in the Allura
-=====================================================================
+========================================
 
 Email routing
----------------------------------------------------------------------
+-------------
 
 routing mechanism will be a dotted path from the project to
 the application/tool to the specific artifact within that app that is
@@ -49,7 +49,7 @@ messages, to go into amqp with the same routing information, and turn into
 "messages" just like e-mail.
 
 Email Content Handling
----------------------------------------------------------------------
+----------------------
 
 On Allura message bodies should be composed as markdown.
 Multi-part mime encoded messages should be sent include plain text

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/guides/message_bus.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/guides/message_bus.rst b/Allura/docs/guides/message_bus.rst
index 11067c9..cef23a0 100644
--- a/Allura/docs/guides/message_bus.rst
+++ b/Allura/docs/guides/message_bus.rst
@@ -16,13 +16,13 @@
        under the License.
 
 Guide to the Allura task and event system
-====================================================================
+=========================================
 
 Our event system is driven by a MongoDB-based queuing system, most of which you
 can ignore, because we've simplified it down to two ideas: *tasks* and *event handlers*.
 
 Glossary
-----------------------------------
+--------
 
 Before we get into the details perhaps a few definitions are in order:
 
@@ -33,7 +33,7 @@ Before we get into the details perhaps a few definitions are in order:
   fan out to multiple callables.
 
 Tasks
--------------------------------------------------------------
+-----
 
 The `MonQTask` class is central to the Allura asynchronous processing system.
 Simply put, a `MonQTask` is a document in MongoDB that contains a context
@@ -64,7 +64,7 @@ well::
 .. _events:
 
 Events
--------------------
+------
 
 Events provide fanout capability for messages, letting several functions get
 called in response to the same 'event.'  To note a function as an event handler,
@@ -87,7 +87,7 @@ the topic name (above, this would be 'project_updated') is always the first
 parameter passed to the event handler.
 
 Running the Task Daemon
-----------------------------------------------------------------
+-----------------------
 
 In order to actually run the asynchronous tasks, we have written a paster command
 `taskd`.  This creates a configurable number of worker processes that watch for

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/guides/permissions.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/guides/permissions.rst b/Allura/docs/guides/permissions.rst
index d214f0d..713b08c 100644
--- a/Allura/docs/guides/permissions.rst
+++ b/Allura/docs/guides/permissions.rst
@@ -16,10 +16,10 @@
        under the License.
 
 Guide to Users, Groups and Permissions in Allura
-=====================================================================
+================================================
 
 User/Group model
----------------------------------------------------------------------
+----------------
 
 In the allura system `users` can be assigned to various `groups` or
 roles on a per-project basis.
@@ -30,7 +30,7 @@ be assigned a list of `permissions` like `edit`,
 set of permissions, for their artifacts.
 
 Individual artifacts and ACL's
----------------------------------------------------------------------
+------------------------------
 
 You may want to assign a permission
 to particular people or roles for a specific `Artifact` such as
@@ -39,7 +39,7 @@ an additive ACL field on every `Artifact` instance.  It is not exposed
 via the UI currently.
 
 Permission hierarchy
---------------------------------------------------------------------
+--------------------
 
 Projects and subprojects can define user groups, but for any particular
 subproject the set of groups the user belongs to is additive.  This follows
@@ -48,7 +48,7 @@ can *allow* additional access, but can't *restrict* it beyond
 what permissions are allowed by a higher level project.
 
 Permission predicates
----------------------------------------------------------------------
+---------------------
 
 Predicates are simple functions, several of which are defined in Allura
 itself, and which can be added by any tool, which return true if

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/guides/scm.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/guides/scm.rst b/Allura/docs/guides/scm.rst
index f4bc229..9d8e987 100644
--- a/Allura/docs/guides/scm.rst
+++ b/Allura/docs/guides/scm.rst
@@ -16,10 +16,10 @@
        under the License.
 
 Guide to SCM tools in Allura
-=====================================================================
+============================
 
 Overview
----------------------------------------------------------------------
+--------
 
 The interface API and most of the controller and view structure of
 code repository type apps is defined in the base classes in the
@@ -33,7 +33,7 @@ packages:
 
 
 Application and Implementation
----------------------------------------------------------------------
+------------------------------
 
 The `Application` structure for SCM apps follows the normal pattern for
 Allura applications, though they should inherit from
@@ -52,7 +52,7 @@ thin wrappers around the underlying SCM tool (see `Indexless`_, below).
 
 
 Controller / View Dispatch
----------------------------------------------------------------------
+--------------------------
 
 All of the SCM apps use the base controllers in `allura.controllers.repository`
 with only minimal customization through subclassing (primarily to
@@ -99,7 +99,7 @@ commit that touched each file or directory within the given directory.
 
 
 Last Commit Logic
----------------------------------------------------------------------
+-----------------
 
 Determining which commit was the last to touch a given set of files or
 directories can be complicated, depending on the specific SCM tool.
@@ -133,7 +133,7 @@ The overall logic for generating this data for Git and Mercurial is as follows:
 
 
 Indexless
----------------------------------------------------------------------
+---------
 
 Currently, there are model classes which encapsulate SCM metadata
 (such as commits, file system structure, etc) in a generic (agnostic to

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/index.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/index.rst b/Allura/docs/index.rst
index d58b7aa..7cb4686 100644
--- a/Allura/docs/index.rst
+++ b/Allura/docs/index.rst
@@ -21,7 +21,7 @@
    contain the root `toctree` directive.
 
 Introduction
-=====================================================================
+============
 
 .. toctree::
    :maxdepth: 2
@@ -29,7 +29,7 @@ Introduction
    intro
 
 Running Allura
-=====================================================================
+==============
 
 .. toctree::
    :maxdepth: 2
@@ -39,7 +39,7 @@ Running Allura
    scm_host
 
 Using Allura
-=====================================================================
+============
 
 .. toctree::
    :maxdepth: 2
@@ -47,7 +47,7 @@ Using Allura
    using
 
 Extending Allura
-=====================================================================
+================
 
 .. toctree::
    :maxdepth: 3
@@ -62,7 +62,7 @@ Extending Allura
     * `Adding Custom CSS <https://sourceforge.net/u/vansteenburgh/allura-plugin-development/2013/12/part-5-adding-custom-css/>`_
 
 Developing Allura
-=====================================================================
+=================
 
 .. toctree::
    :maxdepth: 3
@@ -78,7 +78,7 @@ Developing Allura
 
 
 API Documentation
-==================
+=================
 
 .. toctree::
    :maxdepth: 2
@@ -87,7 +87,7 @@ API Documentation
    api/*
 
 Background Info
-=====================================================================
+===============
 .. toctree::
    :maxdepth: 1
 
@@ -95,7 +95,7 @@ Background Info
    online
 
 Indices and tables
-=====================================================================
+==================
 
 * :ref:`genindex`
 * :ref:`modindex`

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/installation.rst b/Allura/docs/installation.rst
index 558f9b8..ce26d06 100644
--- a/Allura/docs/installation.rst
+++ b/Allura/docs/installation.rst
@@ -16,7 +16,7 @@
        under the License.
 
 Installation
-=================
+============
 
 Install
 -------
@@ -43,12 +43,25 @@ emails sent to that address will be added as comments on the ticket.  To set up
 
 .. code-block:: shell-session
 
-    (env-allura)~/src/forge/Allura$ nohup paster smtp_server development.ini > ~/logs/smtp.log &
+    (env-allura)~/src/forge/Allura$ nohup paster smtp_server development.ini > /var/log/allura/smtp.log &
 
 By default this uses port 8825.  Depending on your mail routing, you may need to change that port number.
 And if the port is in use, this command will fail.  You can check the log file for any errors.
 To change the port number, edit `development.ini` and change `forgemail.port` to the appropriate port number for your environment.
 
+SMTP in development
+^^^^^^^^^^^^^^^^^^^
+
+The following command can be used for quick and easy monitoring of smtp during development.
+Just be sure the port matches the `smtp_port` from your `development.ini` (8826 by default).
+
+.. code-block:: shell-session
+
+    (env-allura)~/src/forge/Allura$ python -m smtpd -n -c DebuggingServer localhost:8826
+
+This will create a new debugging server that discards messages and prints them to stdout.
+
+
 Using LDAP
 ^^^^^^^^^^
 
@@ -72,7 +85,7 @@ Note: if you want users to register new accounts into your LDAP system via Allur
 off :samp:`autoregister` and turn on :samp:`allow_user_registration`
 
 Enabling RabbitMQ
-^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^
 
 For faster notification of background jobs, you can use RabbitMQ.  Assuming a base setup from the INSTALL, run these commands
 to install rabbitmq and set it up:
@@ -92,4 +105,4 @@ If your `paster taskd` process is still running, restart it:
 .. code-block:: shell-session
 
     (env-allura)~/src/forge/Allura$ pkill -f taskd
-    (env-allura)~/src/forge/Allura$ nohup paster taskd development.ini > ~/logs/taskd.log &
+    (env-allura)~/src/forge/Allura$ nohup paster taskd development.ini > /var/log/allura/taskd.log &
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/intro.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/intro.rst b/Allura/docs/intro.rst
index a3252b7..341ec25 100644
--- a/Allura/docs/intro.rst
+++ b/Allura/docs/intro.rst
@@ -18,7 +18,7 @@
 Rather than build yet another forge, we decided to do something new.   We wanted to build a new kind of extensible forge, and a new set of highly integrated forge tools. 
 
 Allura is an **open** platform for **open** processes
-----------------------------------------------------------------------
+-----------------------------------------------------
 
 It's easy to get frustrated with existing development tools.   Too often they are overbearing, complex, and make assumptions that get in your way.  And even if they are open source, it's often difficult to get them to work the way you need them too. 
 
@@ -35,7 +35,7 @@ It's open in bunch of ways:
 We looked at existing forges, but to achieve all those goals, we decided we needed to build something new.
 
 Allura is designed to support an **ecosystem**
-------------------------------------------------------------------------
+----------------------------------------------
 
 Allura is at once a **set of tools** to help people collaboratively develop software, and an **open platform** on which innovative new tools be built. 
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/online.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/online.rst b/Allura/docs/online.rst
index 8f6518b..e68dd44 100644
--- a/Allura/docs/online.rst
+++ b/Allura/docs/online.rst
@@ -16,7 +16,7 @@
        under the License.
 
 Online References
-======================
+=================
 
 Generated API docs, useful for browsing through the code, viewing inheritance, etc:
 
@@ -28,7 +28,7 @@ Our project page, including tickets, discussion forums, etc.:
 
 
 Much of the current forge was inspired by Roundup
----------------------------------------------------------------------
+-------------------------------------------------
 
 http://roundup.sourceforge.net/index.html
 
@@ -37,18 +37,18 @@ After we told ESR about roundup, he posted some interesting ideas about how to "
 http://esr.ibiblio.org/?p=1359
 
 Message based system needed
----------------------------------------------------------------------
+---------------------------
 
 http://ejohn.org/blog/google-groups-is-dead/
 
 
 Potential pitfalls for groupware development
----------------------------------------------------------------------
+--------------------------------------------
 
 http://research.microsoft.com/en-us/um/people/jgrudin/past/papers/cacm94/cacm94.html
 
 AMQP Online References
----------------------------------------------------------------------
+----------------------
 
 http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/
 http://www.igvita.com/2009/10/08/advanced-messaging-routing-with-amqp/

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/platform.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/platform.rst b/Allura/docs/platform.rst
index 9ca334b..acf0124 100644
--- a/Allura/docs/platform.rst
+++ b/Allura/docs/platform.rst
@@ -16,7 +16,7 @@
        under the License.
 
 Platform Architecture overview
-===================================
+==============================
 
 I'm told that the reason you build a platform is to "reduce the marginal cost
 of developing applications."  Sounds good.   Well, actually it sounds a bit
@@ -25,7 +25,7 @@ tools faster, easier, and more fun, which I guess is the "reduce the marginal
 cost" thing.
 
 Platform building blocks
----------------------------------------------------------------------
+------------------------
 
 Before we get into the details of how to extend the Allura platform, perhaps
 it would be smart to explain some of the big pieces and why they are there.
@@ -78,7 +78,7 @@ working with the RabbitMQ based AMQP bus a LOT easer.
 
 
 Application Tools
----------------------------------------------------------------------
+-----------------
 
 Writing a tool for Allura is as simple as defining a few controllers
 to handle particular URL's, templates to render pages, and defining the schemas
@@ -98,7 +98,7 @@ When you write Allura tools, you'll get lots of stuff for free:
 * Access to a real-time event publishing system
 
 What's in a tool?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~
 
 The most basic app tool consists of a few things:
 
@@ -111,7 +111,7 @@ The most basic app tool consists of a few things:
 * Event publisher (optional)
 
 Users/groups and Permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 In order to facilitate more open processes, where more users can contribute
 -- while still protecting data -- documents can easily be "versioned", and

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/platform_tour.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/platform_tour.rst b/Allura/docs/platform_tour.rst
index 73a0a14..06d3140 100644
--- a/Allura/docs/platform_tour.rst
+++ b/Allura/docs/platform_tour.rst
@@ -16,10 +16,10 @@
        under the License.
 
 Platform Tour
-=================
+=============
 
 Introduction
----------------
+------------
 
 Allura is implemented as a collection of tool applications on top of a
 robust and open platform.  Some of the services provided by the platform include:
@@ -54,7 +54,7 @@ Discussion
   The forum also handles attachments to posts either via the web interface or via email.
 
 The Context Object
----------------------------------------------------
+------------------
 
 The Pylons "context" object `c` has several properties which are automatically
 set for each request:
@@ -94,7 +94,7 @@ if you need to change the context for some situation:
 
 
 Artifacts
--------------
+---------
 
 We've mentioned artifacts a couple of times now without definition.  An artifact,
 as used in Allura, is some object that a tool needs to store in the
@@ -140,7 +140,7 @@ the methods of the `allura.model.artifact.Artifact` class::
             return self.shortname
 
 Platform services provided for artifacts
----------------------------------------------------
+----------------------------------------
 
 Whenever you create, modify, or delete an artifact, the platform does a couple of
 things for you:
@@ -162,7 +162,7 @@ They both have many tickets in them.  To distinguish, use the tracker mount poin
 within the reference.  For example [features:#3] or [bugs:#3]
 
 Asynchronous Processing
------------------------------------------
+-----------------------
 
 Much of the actual functionality of Allura comes from code that runs
 *outside* the context of a web request, in the `taskd` server (invoked by
@@ -196,7 +196,7 @@ Event
 
 
 Email Integration
------------------------------------------
+-----------------
 
 The Allura platform provides easy-to-use email integration.  Forge email addresses
 are of the form

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/scm_host.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/scm_host.rst b/Allura/docs/scm_host.rst
index 9054991..d3fe205 100644
--- a/Allura/docs/scm_host.rst
+++ b/Allura/docs/scm_host.rst
@@ -18,7 +18,7 @@
 .. _scm_hosting:
 
 Git and Subversion Hosting Installation
-==========================================================
+=======================================
 
 Allura can manage and display Git and SVN repositories, but it doesn't
 automatically run the git and svn services for you.  Here we'll describe how
@@ -33,7 +33,7 @@ an Ubuntu system, but should be similar on other systems.
     works with no additional configuration.
 
 Git
---------------
+---
 
 We'll cover the basics to get you going.  For additional options and details,
 see http://git-scm.com/docs/git-http-backend and http://git-scm.com/book/en/Git-on-the-Server
@@ -78,14 +78,14 @@ when they browse the code repo web pages.  The exact values to use will depend o
 hostnames and port numbers you are using.
 
 Read-only `git://`
-^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^
 If you want to run a separate readonly git service, using the git protocol instead of http,
 run: :program:`git daemon --reuseaddr --export-all --base-path=/srv/git /srv/git`  It can
 be accessed at :code:`git://localhost/p/test/git`
 
 
 Subversion
---------------
+----------
 
 These instructions will cover the recommended easiest way to run Subversion with Allura.
 For an overview of other options, see http://svnbook.red-bean.com/en/1.8/svn.serverconfig.choosing.html
@@ -173,7 +173,7 @@ Then Apache SVN will serve repositories for all Allura projects and subprojects.
 .. _auth_apache:
 
 Configuring Auth with Apache
------------------------------------------------
+----------------------------
 
 This is the easiest way to integrate authentication and authorization for SCM access with Allura.  It uses
 mod_python and the handler in :file:`scripts/ApacheAccessHandler.py` to query Allura directly
@@ -231,6 +231,6 @@ message.
 
 
 Advanced Alternative
------------------------------------------------
+--------------------
 
 An advanced alternative for SCM hosting using :ref:`SSH, LDAP, and a FUSE driver <scm_hosting_ssh>` is available.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/Allura/docs/scm_host_ssh.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/scm_host_ssh.rst b/Allura/docs/scm_host_ssh.rst
index fee11f6..81b21d8 100644
--- a/Allura/docs/scm_host_ssh.rst
+++ b/Allura/docs/scm_host_ssh.rst
@@ -18,7 +18,7 @@
 .. _scm_hosting_ssh:
 
 Configuring Git/SVN/Hg to use Allura auth via LDAP and ssh
-============================================================
+==========================================================
 
 The following instructions will use a chroot, a custom FUSE driver, and LDAP.
 Once completed, an ssh-based configuration of Git, SVN, or Hg that has repos in
@@ -35,7 +35,7 @@ support for schroot and debootstrap.  We will use a chroot jail to allow users t
 access their repositories via ssh.
 
 Install a chroot environment
--------------------------------------------
+----------------------------
 
 These instructions are based on the documentation in `Debootstrap Chroot`_.  and `OpenLDAPServer`_.
 
@@ -92,7 +92,7 @@ Test that the chroot is installed by entering it:
     (scm) # logout
 
 Configure OpenLDAP in the Chroot
---------------------------------------------------------------
+--------------------------------
 
 Copy the ldap-setup script into the chroot environment:
 
@@ -127,7 +127,7 @@ In particular, you will need to answer the following questions (substitute your
 * PAM profiles to enable: **2**
 
 Update the chroot ssh configuration
--------------------------------------------------
+-----------------------------------
 
 Update the file :file:`/var/chroot/scm/etc/ssh/sshd_config`, changing the port directive:
 
@@ -137,7 +137,7 @@ Update the file :file:`/var/chroot/scm/etc/ssh/sshd_config`, changing the port d
     Port 8022
 
 Setup the Custom FUSE Driver
--------------------------------------
+----------------------------
 
 Copy the accessfs script into the chroot environment:
 
@@ -179,7 +179,7 @@ Start the SSH daemon:
     (scm) # /etc/init.d/ssh start
 
 Configure Allura to Use the LDAP Server
-------------------------------------------------
+---------------------------------------
 
 Set the following values in your .ini file:
 

http://git-wip-us.apache.org/repos/asf/allura/blob/aa14b0d8/INSTALL.markdown
----------------------------------------------------------------------
diff --git a/INSTALL.markdown b/INSTALL.markdown
index cbee9a3..f552a2a 100644
--- a/INSTALL.markdown
+++ b/INSTALL.markdown
@@ -66,6 +66,10 @@ In order to use the virtual environment, you'll need to activate it:
 
 You'll need to do this whenever you're working on the Allura codebase so you may want to consider adding it to your `~/.bashrc` file.
 
+## Creating the log directory
+    (env-allura)~$ sudo mkdir -p /var/log/allura
+    (env-allura)~$ sudo chown $(whoami) /var/log/allura
+
 ## Installing the Allura code and dependencies
 
 Now we can get down to actually getting the Allura code and dependencies downloaded and ready to go.  If you don't have the source code yet, run:
@@ -109,8 +113,7 @@ We have a custom config ready for use.
     (env-allura)~/src$ cp -f allura/solr_config/schema.xml solr-4.2.1/example/solr/collection1/conf
 
     (env-allura)~/src$ cd solr-4.2.1/example/
-    (env-allura)~/src/apache-solr-4.2.1/example/$ mkdir ~/logs/
-    (env-allura)~/src/apache-solr-4.2.1/example/$ nohup java -jar start.jar > ~/logs/solr.log &
+    (env-allura)~/src/apache-solr-4.2.1/example/$ nohup java -jar start.jar > /var/log/allura/solr.log &
 
 
 ### Create code repo directories
@@ -130,7 +133,7 @@ If you want to set up remote access to the repositories, see <http://forge-allur
 Allura uses a background task service called "taskd" to do async tasks like sending emails, and indexing data into solr, etc.  Let's get it running
 
     (env-allura)~$ cd ~/src/allura/Allura
-    (env-allura)~/src/allura/Allura$ nohup paster taskd development.ini > ~/logs/taskd.log &
+    (env-allura)~/src/allura/Allura$ nohup paster taskd development.ini > /var/log/allura/taskd.log 2>&1 &
 
 ### The application server
 
@@ -140,7 +143,7 @@ In order to initialize the Allura database, you'll need to run the following:
 
 This shouldn't take too long, but it will start the taskd server doing tons of stuff in the background.  Once this is done, you can start the application server:
 
-    (env-allura)~/src/allura/Allura$ nohup paster serve --reload development.ini > ~/logs/tg.log &
+    (env-allura)~/src/allura/Allura$ nohup paster serve --reload development.ini  > /var/log/allura/allura.log 2>&1 &
 
 ## Next Steps
 


[09/26] allura git commit: [#7827] ticket:722 Add jquery-migrate dev version

Posted by je...@apache.org.
[#7827] ticket:722 Add jquery-migrate dev version


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/63674961
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/63674961
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/63674961

Branch: refs/heads/ib/7830
Commit: 63674961c7e3be9be11f24218aaddb9a83b2c6a1
Parents: 397652f
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Feb 9 14:55:06 2015 +0200
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:18 2015 +0000

----------------------------------------------------------------------
 .../allura/public/nf/js/jquery-migrate-1.2.1.js | 521 +++++++++++++++++++
 1 file changed, 521 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/63674961/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js b/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js
new file mode 100644
index 0000000..25b6c81
--- /dev/null
+++ b/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js
@@ -0,0 +1,521 @@
+/*!
+ * jQuery Migrate - v1.2.1 - 2013-05-08
+ * https://github.com/jquery/jquery-migrate
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
+ */
+(function( jQuery, window, undefined ) {
+// See http://bugs.jquery.com/ticket/13335
+// "use strict";
+
+
+var warnedAbout = {};
+
+// List of warnings already given; public read only
+jQuery.migrateWarnings = [];
+
+// Set to true to prevent console output; migrateWarnings still maintained
+// jQuery.migrateMute = false;
+
+// Show a message on the console so devs know we're active
+if ( !jQuery.migrateMute && window.console && window.console.log ) {
+	window.console.log("JQMIGRATE: Logging is active");
+}
+
+// Set to false to disable traces that appear with warnings
+if ( jQuery.migrateTrace === undefined ) {
+	jQuery.migrateTrace = true;
+}
+
+// Forget any warnings we've already given; public
+jQuery.migrateReset = function() {
+	warnedAbout = {};
+	jQuery.migrateWarnings.length = 0;
+};
+
+function migrateWarn( msg) {
+	var console = window.console;
+	if ( !warnedAbout[ msg ] ) {
+		warnedAbout[ msg ] = true;
+		jQuery.migrateWarnings.push( msg );
+		if ( console && console.warn && !jQuery.migrateMute ) {
+			console.warn( "JQMIGRATE: " + msg );
+			if ( jQuery.migrateTrace && console.trace ) {
+				console.trace();
+			}
+		}
+	}
+}
+
+function migrateWarnProp( obj, prop, value, msg ) {
+	if ( Object.defineProperty ) {
+		// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
+		// allow property to be overwritten in case some other plugin wants it
+		try {
+			Object.defineProperty( obj, prop, {
+				configurable: true,
+				enumerable: true,
+				get: function() {
+					migrateWarn( msg );
+					return value;
+				},
+				set: function( newValue ) {
+					migrateWarn( msg );
+					value = newValue;
+				}
+			});
+			return;
+		} catch( err ) {
+			// IE8 is a dope about Object.defineProperty, can't warn there
+		}
+	}
+
+	// Non-ES5 (or broken) browser; just set the property
+	jQuery._definePropertyBroken = true;
+	obj[ prop ] = value;
+}
+
+if ( document.compatMode === "BackCompat" ) {
+	// jQuery has never supported or tested Quirks Mode
+	migrateWarn( "jQuery is not compatible with Quirks Mode" );
+}
+
+
+var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
+	oldAttr = jQuery.attr,
+	valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
+		function() { return null; },
+	valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
+		function() { return undefined; },
+	rnoType = /^(?:input|button)$/i,
+	rnoAttrNodeType = /^[238]$/,
+	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+	ruseDefault = /^(?:checked|selected)$/i;
+
+// jQuery.attrFn
+migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
+
+jQuery.attr = function( elem, name, value, pass ) {
+	var lowerName = name.toLowerCase(),
+		nType = elem && elem.nodeType;
+
+	if ( pass ) {
+		// Since pass is used internally, we only warn for new jQuery
+		// versions where there isn't a pass arg in the formal params
+		if ( oldAttr.length < 4 ) {
+			migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
+		}
+		if ( elem && !rnoAttrNodeType.test( nType ) &&
+			(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
+			return jQuery( elem )[ name ]( value );
+		}
+	}
+
+	// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
+	// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
+	if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
+		migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
+	}
+
+	// Restore boolHook for boolean property/attribute synchronization
+	if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
+		jQuery.attrHooks[ lowerName ] = {
+			get: function( elem, name ) {
+				// Align boolean attributes with corresponding properties
+				// Fall back to attribute presence where some booleans are not supported
+				var attrNode,
+					property = jQuery.prop( elem, name );
+				return property === true || typeof property !== "boolean" &&
+					( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
+
+					name.toLowerCase() :
+					undefined;
+			},
+			set: function( elem, value, name ) {
+				var propName;
+				if ( value === false ) {
+					// Remove boolean attributes when set to false
+					jQuery.removeAttr( elem, name );
+				} else {
+					// value is true since we know at this point it's type boolean and not false
+					// Set boolean attributes to the same name and set the DOM property
+					propName = jQuery.propFix[ name ] || name;
+					if ( propName in elem ) {
+						// Only set the IDL specifically if it already exists on the element
+						elem[ propName ] = true;
+					}
+
+					elem.setAttribute( name, name.toLowerCase() );
+				}
+				return name;
+			}
+		};
+
+		// Warn only for attributes that can remain distinct from their properties post-1.9
+		if ( ruseDefault.test( lowerName ) ) {
+			migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
+		}
+	}
+
+	return oldAttr.call( jQuery, elem, name, value );
+};
+
+// attrHooks: value
+jQuery.attrHooks.value = {
+	get: function( elem, name ) {
+		var nodeName = ( elem.nodeName || "" ).toLowerCase();
+		if ( nodeName === "button" ) {
+			return valueAttrGet.apply( this, arguments );
+		}
+		if ( nodeName !== "input" && nodeName !== "option" ) {
+			migrateWarn("jQuery.fn.attr('value') no longer gets properties");
+		}
+		return name in elem ?
+			elem.value :
+			null;
+	},
+	set: function( elem, value ) {
+		var nodeName = ( elem.nodeName || "" ).toLowerCase();
+		if ( nodeName === "button" ) {
+			return valueAttrSet.apply( this, arguments );
+		}
+		if ( nodeName !== "input" && nodeName !== "option" ) {
+			migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
+		}
+		// Does not return so that setAttribute is also used
+		elem.value = value;
+	}
+};
+
+
+var matched, browser,
+	oldInit = jQuery.fn.init,
+	oldParseJSON = jQuery.parseJSON,
+	// Note: XSS check is done below after string is trimmed
+	rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
+
+// $(html) "looks like html" rule change
+jQuery.fn.init = function( selector, context, rootjQuery ) {
+	var match;
+
+	if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
+			(match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
+		// This is an HTML string according to the "old" rules; is it still?
+		if ( selector.charAt( 0 ) !== "<" ) {
+			migrateWarn("$(html) HTML strings must start with '<' character");
+		}
+		if ( match[ 3 ] ) {
+			migrateWarn("$(html) HTML text after last tag is ignored");
+		}
+		// Consistently reject any HTML-like string starting with a hash (#9521)
+		// Note that this may break jQuery 1.6.x code that otherwise would work.
+		if ( match[ 0 ].charAt( 0 ) === "#" ) {
+			migrateWarn("HTML string cannot start with a '#' character");
+			jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
+		}
+		// Now process using loose rules; let pre-1.8 play too
+		if ( context && context.context ) {
+			// jQuery object as context; parseHTML expects a DOM object
+			context = context.context;
+		}
+		if ( jQuery.parseHTML ) {
+			return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ),
+					context, rootjQuery );
+		}
+	}
+	return oldInit.apply( this, arguments );
+};
+jQuery.fn.init.prototype = jQuery.fn;
+
+// Let $.parseJSON(falsy_value) return null
+jQuery.parseJSON = function( json ) {
+	if ( !json && json !== null ) {
+		migrateWarn("jQuery.parseJSON requires a valid JSON string");
+		return null;
+	}
+	return oldParseJSON.apply( this, arguments );
+};
+
+jQuery.uaMatch = function( ua ) {
+	ua = ua.toLowerCase();
+
+	var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
+		/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+		/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
+		/(msie) ([\w.]+)/.exec( ua ) ||
+		ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
+		[];
+
+	return {
+		browser: match[ 1 ] || "",
+		version: match[ 2 ] || "0"
+	};
+};
+
+// Don't clobber any existing jQuery.browser in case it's different
+if ( !jQuery.browser ) {
+	matched = jQuery.uaMatch( navigator.userAgent );
+	browser = {};
+
+	if ( matched.browser ) {
+		browser[ matched.browser ] = true;
+		browser.version = matched.version;
+	}
+
+	// Chrome is Webkit, but Webkit is also Safari.
+	if ( browser.chrome ) {
+		browser.webkit = true;
+	} else if ( browser.webkit ) {
+		browser.safari = true;
+	}
+
+	jQuery.browser = browser;
+}
+
+// Warn if the code tries to get jQuery.browser
+migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
+
+jQuery.sub = function() {
+	function jQuerySub( selector, context ) {
+		return new jQuerySub.fn.init( selector, context );
+	}
+	jQuery.extend( true, jQuerySub, this );
+	jQuerySub.superclass = this;
+	jQuerySub.fn = jQuerySub.prototype = this();
+	jQuerySub.fn.constructor = jQuerySub;
+	jQuerySub.sub = this.sub;
+	jQuerySub.fn.init = function init( selector, context ) {
+		if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+			context = jQuerySub( context );
+		}
+
+		return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+	};
+	jQuerySub.fn.init.prototype = jQuerySub.fn;
+	var rootjQuerySub = jQuerySub(document);
+	migrateWarn( "jQuery.sub() is deprecated" );
+	return jQuerySub;
+};
+
+
+// Ensure that $.ajax gets the new parseJSON defined in core.js
+jQuery.ajaxSetup({
+	converters: {
+		"text json": jQuery.parseJSON
+	}
+});
+
+
+var oldFnData = jQuery.fn.data;
+
+jQuery.fn.data = function( name ) {
+	var ret, evt,
+		elem = this[0];
+
+	// Handles 1.7 which has this behavior and 1.8 which doesn't
+	if ( elem && name === "events" && arguments.length === 1 ) {
+		ret = jQuery.data( elem, name );
+		evt = jQuery._data( elem, name );
+		if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
+			migrateWarn("Use of jQuery.fn.data('events') is deprecated");
+			return evt;
+		}
+	}
+	return oldFnData.apply( this, arguments );
+};
+
+
+var rscriptType = /\/(java|ecma)script/i,
+	oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
+
+jQuery.fn.andSelf = function() {
+	migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
+	return oldSelf.apply( this, arguments );
+};
+
+// Since jQuery.clean is used internally on older versions, we only shim if it's missing
+if ( !jQuery.clean ) {
+	jQuery.clean = function( elems, context, fragment, scripts ) {
+		// Set context per 1.8 logic
+		context = context || document;
+		context = !context.nodeType && context[0] || context;
+		context = context.ownerDocument || context;
+
+		migrateWarn("jQuery.clean() is deprecated");
+
+		var i, elem, handleScript, jsTags,
+			ret = [];
+
+		jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
+
+		// Complex logic lifted directly from jQuery 1.8
+		if ( fragment ) {
+			// Special handling of each script element
+			handleScript = function( elem ) {
+				// Check if we consider it executable
+				if ( !elem.type || rscriptType.test( elem.type ) ) {
+					// Detach the script and store it in the scripts array (if provided) or the fragment
+					// Return truthy to indicate that it has been handled
+					return scripts ?
+						scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
+						fragment.appendChild( elem );
+				}
+			};
+
+			for ( i = 0; (elem = ret[i]) != null; i++ ) {
+				// Check if we're done after handling an executable script
+				if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
+					// Append to fragment and handle embedded scripts
+					fragment.appendChild( elem );
+					if ( typeof elem.getElementsByTagName !== "undefined" ) {
+						// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
+						jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
+
+						// Splice the scripts into ret after their former ancestor and advance our index beyond them
+						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+						i += jsTags.length;
+					}
+				}
+			}
+		}
+
+		return ret;
+	};
+}
+
+var eventAdd = jQuery.event.add,
+	eventRemove = jQuery.event.remove,
+	eventTrigger = jQuery.event.trigger,
+	oldToggle = jQuery.fn.toggle,
+	oldLive = jQuery.fn.live,
+	oldDie = jQuery.fn.die,
+	ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
+	rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
+	rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
+	hoverHack = function( events ) {
+		if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
+			return events;
+		}
+		if ( rhoverHack.test( events ) ) {
+			migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
+		}
+		return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
+	};
+
+// Event props removed in 1.9, put them back if needed; no practical way to warn them
+if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
+	jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
+}
+
+// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
+if ( jQuery.event.dispatch ) {
+	migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
+}
+
+// Support for 'hover' pseudo-event and ajax event warnings
+jQuery.event.add = function( elem, types, handler, data, selector ){
+	if ( elem !== document && rajaxEvent.test( types ) ) {
+		migrateWarn( "AJAX events should be attached to document: " + types );
+	}
+	eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
+};
+jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
+	eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
+};
+
+jQuery.fn.error = function() {
+	var args = Array.prototype.slice.call( arguments, 0);
+	migrateWarn("jQuery.fn.error() is deprecated");
+	args.splice( 0, 0, "error" );
+	if ( arguments.length ) {
+		return this.bind.apply( this, args );
+	}
+	// error event should not bubble to window, although it does pre-1.7
+	this.triggerHandler.apply( this, args );
+	return this;
+};
+
+jQuery.fn.toggle = function( fn, fn2 ) {
+
+	// Don't mess with animation or css toggles
+	if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
+		return oldToggle.apply( this, arguments );
+	}
+	migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
+
+	// Save reference to arguments for access in closure
+	var args = arguments,
+		guid = fn.guid || jQuery.guid++,
+		i = 0,
+		toggler = function( event ) {
+			// Figure out which function to execute
+			var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+			jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+			// Make sure that clicks stop
+			event.preventDefault();
+
+			// and execute the function
+			return args[ lastToggle ].apply( this, arguments ) || false;
+		};
+
+	// link all the functions, so any of them can unbind this click handler
+	toggler.guid = guid;
+	while ( i < args.length ) {
+		args[ i++ ].guid = guid;
+	}
+
+	return this.click( toggler );
+};
+
+jQuery.fn.live = function( types, data, fn ) {
+	migrateWarn("jQuery.fn.live() is deprecated");
+	if ( oldLive ) {
+		return oldLive.apply( this, arguments );
+	}
+	jQuery( this.context ).on( types, this.selector, data, fn );
+	return this;
+};
+
+jQuery.fn.die = function( types, fn ) {
+	migrateWarn("jQuery.fn.die() is deprecated");
+	if ( oldDie ) {
+		return oldDie.apply( this, arguments );
+	}
+	jQuery( this.context ).off( types, this.selector || "**", fn );
+	return this;
+};
+
+// Turn global events into document-triggered events
+jQuery.event.trigger = function( event, data, elem, onlyHandlers  ){
+	if ( !elem && !rajaxEvent.test( event ) ) {
+		migrateWarn( "Global events are undocumented and deprecated" );
+	}
+	return eventTrigger.call( this,  event, data, elem || document, onlyHandlers  );
+};
+jQuery.each( ajaxEvents.split("|"),
+	function( _, name ) {
+		jQuery.event.special[ name ] = {
+			setup: function() {
+				var elem = this;
+
+				// The document needs no shimming; must be !== for oldIE
+				if ( elem !== document ) {
+					jQuery.event.add( document, name + "." + jQuery.guid, function() {
+						jQuery.event.trigger( name, null, elem, true );
+					});
+					jQuery._data( this, name, jQuery.guid++ );
+				}
+				return false;
+			},
+			teardown: function() {
+				if ( this !== document ) {
+					jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
+				}
+				return false;
+			}
+		};
+	}
+);
+
+
+})( jQuery, window );


[14/26] allura git commit: [#7827] ticket:722 Add browser detection snippet to allura-base.js

Posted by je...@apache.org.
[#7827] ticket:722 Add browser detection snippet to allura-base.js

We need it for plugins that still rely on that.
See comment in the code for full details.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d1f5521f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d1f5521f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d1f5521f

Branch: refs/heads/ib/7830
Commit: d1f5521f883497dd453cb2a2279c9e4968849328
Parents: 0ce4968
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Feb 10 09:53:46 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:19 2015 +0000

----------------------------------------------------------------------
 Allura/allura/public/nf/js/jquery-base.js | 38 ++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d1f5521f/Allura/allura/public/nf/js/jquery-base.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/jquery-base.js b/Allura/allura/public/nf/js/jquery-base.js
index 673b5a9..1493550 100644
--- a/Allura/allura/public/nf/js/jquery-base.js
+++ b/Allura/allura/public/nf/js/jquery-base.js
@@ -131,3 +131,41 @@ return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBeha
 	};
 
 }));
+
+
+/**
+ * It's the piece from jquery-migrate plugin to detect browser.
+ * https://github.com/jquery/jquery-migrate/blob/master/src/core.js#L68-L102
+ * Browser detection was removed in 1.9+, but we still need it for
+ * `pb.transformie.min.js` (see jinja_master/master.html) and lightbox_me
+ * plugin which we use a lot.
+ */
+jQuery.uaMatch = function( ua ) {
+  ua = ua.toLowerCase();
+  var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
+    /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+    /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
+    /(msie) ([\w.]+)/.exec( ua ) ||
+    ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
+    [];
+  return {
+    browser: match[ 1 ] || "",
+    version: match[ 2 ] || "0"
+  };
+};
+// Don't clobber any existing jQuery.browser in case it's different
+if ( !jQuery.browser ) {
+  matched = jQuery.uaMatch( navigator.userAgent );
+  browser = {};
+  if ( matched.browser ) {
+    browser[ matched.browser ] = true;
+    browser.version = matched.version;
+  }
+  // Chrome is Webkit, but Webkit is also Safari.
+  if ( browser.chrome ) {
+    browser.webkit = true;
+  } else if ( browser.webkit ) {
+    browser.safari = true;
+  }
+  jQuery.browser = browser;
+}


[19/26] allura git commit: Update test_set_password_sets_last_updated to match changes in [#7516] for similar test

Posted by je...@apache.org.
Update test_set_password_sets_last_updated to match changes in [#7516] for similar test


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9f832dd5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9f832dd5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9f832dd5

Branch: refs/heads/ib/7830
Commit: 9f832dd5fbc7a515acf5427e05cd6c79f43913d9
Parents: 0180e68
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Feb 24 20:57:33 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 20:57:33 2015 +0000

----------------------------------------------------------------------
 Allura/allura/tests/test_plugin.py | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/9f832dd5/Allura/allura/tests/test_plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index b3073f3..08bdc6c 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -231,15 +231,13 @@ class TestLocalAuthenticationProvider(object):
         self.provider.set_password(user, 'old', 'new')
         user._encode_password.assert_callued_once_with('new')
 
-    def test_set_password_sets_last_updated(self):
+    @patch('allura.lib.plugin.datetime', autospec=True)
+    def test_set_password_sets_last_updated(self, dt_mock):
         user = Mock()
         user.__ming__ = Mock()
         user.last_password_updated = None
-        now1 = dt.datetime.utcnow()
         self.provider.set_password(user, None, 'new')
-        now2 = dt.datetime.utcnow()
-        assert_true(user.last_password_updated > now1)
-        assert_true(user.last_password_updated < now2)
+        assert_equal(user.last_password_updated, dt_mock.utcnow.return_value)
 
     def test_get_last_password_updated_not_set(self):
         user = Mock()


[20/26] allura git commit: Force trailing slash on merge request URLs, so form submit goes to right place

Posted by je...@apache.org.
Force trailing slash on merge request URLs, so form submit goes to right place


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/55cd10b6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/55cd10b6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/55cd10b6

Branch: refs/heads/ib/7830
Commit: 55cd10b65bc2a247c210fbbaa85b8b4df2507f61
Parents: 9f832dd
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Feb 25 15:36:46 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Feb 25 15:36:46 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py                | 1 +
 ForgeGit/forgegit/tests/functional/test_controllers.py | 5 +++++
 2 files changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/55cd10b6/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 1751839..1e1e840 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -354,6 +354,7 @@ class MergeRequestController(object):
         if self.req is None:
             raise exc.HTTPNotFound
 
+    @with_trailing_slash
     @expose('jinja:allura:templates/repo/merge_request.html')
     def index(self, page=0, limit=250, **kw):
         c.thread = self.thread_widget

http://git-wip-us.apache.org/repos/asf/allura/blob/55cd10b6/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 632cad5..c048599 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -542,6 +542,11 @@ class TestFork(_TestCase):
         assert 'git merge {}'.format(c_id) in merge_instructions
         assert_in('less than 1 minute ago', r.html.findAll('p')[0].getText())
 
+    def test_merge_request_detail_noslash(self):
+        self._request_merge()
+        r = self.app.get('/p/test/src-git/merge-requests/1', status=302)
+        assert_equal(r.location, 'http://localhost/p/test/src-git/merge-requests/1/')
+
     def test_merge_request_with_deleted_repo(self):
         self._request_merge()
         h.set_context('test2', 'code', neighborhood='Projects')


[03/26] allura git commit: [#7786] Invalidate pwd reset tokens after email/password change

Posted by je...@apache.org.
[#7786] Invalidate pwd reset tokens after email/password change


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b9225b8e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b9225b8e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b9225b8e

Branch: refs/heads/ib/7830
Commit: b9225b8e03c621ba07b63355d07f4b2c9cc71c14
Parents: 2d9bcf0
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Wed Feb 4 08:16:17 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Feb 19 16:21:54 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py           |  10 +-
 Allura/allura/tests/functional/test_auth.py | 117 +++++++++++++++++++++++
 2 files changed, 126 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b9225b8e/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 2183032..0bfe966 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -165,7 +165,7 @@ class AuthController(BaseController):
             raise wexc.HTTPNotFound()
         user = self._validate_hash(hash)
         user.set_password(pw)
-        user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
+        user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')  # Clear password reset token
         h.auditlog_user('Password changed (through recovery process)', user=user)
         flash('Password changed')
         redirect('/auth/?return_to=/')  # otherwise the default return_to would be the forgotten_password referrer page
@@ -409,6 +409,8 @@ class AuthController(BaseController):
             expired_user = M.User.query.get(username=expired_username) if expired_username else None
             ap.set_password(expired_user or c.user, kw['oldpw'], kw['pw'])
             expired_user.set_tool_data('allura', pwd_reset_preserve_session=session.id)
+            expired_user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')  # Clear password reset token
+
         except wexc.HTTPUnauthorized:
             flash('Incorrect password', 'error')
             redirect(tg.url('/auth/pwd_expired', dict(return_to=return_to)))
@@ -471,11 +473,13 @@ class PreferencesController(BaseController):
                         # clear it now, a new one will get set below
                         user.set_pref('email_address', None)
                         primary_addr = None
+                        user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
                 h.auditlog_user('Email address deleted: %s', user.email_addresses[i], user=user)
                 del user.email_addresses[i]
                 if obj:
                     obj.delete()
         if new_addr.get('claim') or new_addr.get('addr'):
+            user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')  # Clear password reset token
             claimed_emails_limit = config.get('user_prefs.maximum_claimed_emails', None)
             if claimed_emails_limit and len(user.email_addresses) >= int(claimed_emails_limit):
                 flash('You cannot claim more than %s email addresses.' % claimed_emails_limit, 'error')
@@ -505,6 +509,7 @@ class PreferencesController(BaseController):
                         em.send_claim_attempt()
 
                     if not admin:
+                        user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
                         flash('A verification email has been sent.  Please check your email and click to confirm.')
 
                     h.auditlog_user('New email address: %s', new_addr['addr'], user=user)
@@ -525,6 +530,7 @@ class PreferencesController(BaseController):
                     primary_addr,
                     user=user)
             user.set_pref('email_address', primary_addr)
+            user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
 
     @h.vardec
     @expose()
@@ -561,6 +567,8 @@ class PreferencesController(BaseController):
         try:
             ap.set_password(c.user, kw['oldpw'], kw['pw'])
             c.user.set_tool_data('allura', pwd_reset_preserve_session=session.id)
+            c.user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
+
         except wexc.HTTPUnauthorized:
             flash('Incorrect password', 'error')
             redirect('.')

http://git-wip-us.apache.org/repos/asf/allura/blob/b9225b8e/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index eacabd0..f288b0b 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -324,6 +324,90 @@ class TestAuth(TestController):
         email = M.EmailAddress.find(dict(email=email_address, claimed_by_user_id=user._id)).first()
         assert not email.confirmed
 
+    @staticmethod
+    def _create_password_reset_hash():
+        """ Generates a password reset token for a given user.
+
+        :return: User object
+        :rtype: User
+        """
+        # test-user claimed email address
+        user = M.User.by_username('test-admin')
+        user.set_tool_data('AuthPasswordReset',
+                           hash="generated_hash_value",
+                           hash_expiry="04-08-2020")
+        hash = user.get_tool_data('AuthPasswordReset', 'hash')
+        session(user).flush(user)
+
+        hash_expiry = user.get_tool_data('AuthPasswordReset', 'hash_expiry')
+        assert_equal(hash, 'generated_hash_value')
+        assert_equal(hash_expiry, '04-08-2020')
+        return user
+
+    def test_token_generator(self):
+        """ Generates new token invalidation tests.
+
+        The tests cover: changing, claiming, updating, removing email addresses.
+        :returns: email_change_invalidates_token
+        """
+        _params = [{'new_addr.addr': 'test_abcd@domain.net',  # Change primary address
+                    'primary_addr': 'test@example.com', },
+                   {'new_addr.addr': 'test@example.com',  # Claim new address
+                    'new_addr.claim': 'Claim Address',
+                    'primary_addr': 'test-admin@users.localhost',
+                    'password': 'foo',
+                    'preferences.email_format': 'plain'},
+                   {'addr-1.ord': '1',  # remove test-admin@users.localhost
+                    'addr-1.delete': 'on',
+                    'addr-2.ord': '2',
+                    'new_addr.addr': '',
+                    'primary_addr': 'test-admin@users.localhost',
+                    'password': 'foo',
+                    'preferences.email_format': 'plain'},
+                   {'addr-1.ord': '1',  # Remove email
+                    'addr-2.ord': '2',
+                    'addr-2.delete': 'on',
+                    'new_addr.addr': '',
+                    'primary_addr': 'test-admin@users.localhost'}]
+
+        for param in _params:
+            yield self.email_change_invalidates_token, param
+
+    def email_change_invalidates_token(self, change_params):
+        user = self._create_password_reset_hash()
+        session(user).flush(user)
+
+        self.app.post('/auth/preferences/update_emails',
+                      extra_environ=dict(username='test-admin'),
+                      params=change_params)
+
+        u = M.User.by_username('test-admin')
+        print(u.get_tool_data('AuthPasswordReset', 'hash'))
+        assert_equal(u.get_tool_data('AuthPasswordReset', 'hash'), '')
+        assert_equal(u.get_tool_data('AuthPasswordReset', 'hash_expiry'), '')
+
+    @td.with_user_project('test-admin')
+    def test_change_password(self):
+        # Get and assert user with password reset token.
+        user = self._create_password_reset_hash()
+        old_pass = user.get_pref('password')
+
+        # Change password
+        self.app.post('/auth/preferences/change_password',
+                      extra_environ=dict(username='test-admin'),
+                      params={
+                          'oldpw': 'foo',
+                          'pw': 'asdfasdf',
+                          'pw2': 'asdfasdf',
+                      })
+
+        # Confirm password was changed.
+        assert_not_equal(old_pass, user.get_pref('password'))
+
+        # Confirm any existing tokens were reset.
+        assert_equal(user.get_tool_data('AuthPasswordReset', 'hash'), '')
+        assert_equal(user.get_tool_data('AuthPasswordReset', 'hash_expiry'), '')
+
     @td.with_user_project('test-admin')
     def test_prefs(self):
         r = self.app.get('/auth/preferences/',
@@ -1619,6 +1703,39 @@ class TestPasswordExpire(TestController):
             r = self.login(pwd='foo')
             assert_in('Invalid login', r)
 
+    def test_expired_pwd_change_invalidates_token(self):
+        self.set_expire_for_user()
+        with h.push_config(config, **{'auth.pwdexpire.days': 90}):
+            r = self.login()
+            assert_true(self.expired(r))
+            self.assert_redirects()
+            user = M.User.by_username('test-user')
+            user.set_tool_data('AuthPasswordReset',
+                          hash="generated_hash_value",
+                          hash_expiry="04-08-2020")
+            hash = user.get_tool_data('AuthPasswordReset', 'hash')
+            hash_expiry = user.get_tool_data('AuthPasswordReset', 'hash_expiry')
+            assert_equal(hash, 'generated_hash_value')
+            assert_equal(hash_expiry, '04-08-2020')
+            session(user).flush(user)
+
+            # Change expired password
+            r = self.app.get('/auth/pwd_expired', extra_environ={'username': 'test-user'})
+            f = r.forms[0]
+            f['oldpw'] = 'foo'
+            f['pw'] = 'qwerty'
+            f['pw2'] = 'qwerty'
+            r = f.submit(extra_environ={'username': 'test-user'}, status=302)
+            assert_equal(r.location, 'http://localhost/')
+
+            user = M.User.by_username('test-user')
+            hash = user.get_tool_data('AuthPasswordReset', 'hash')
+            hash_expiry = user.get_tool_data('AuthPasswordReset', 'hash_expiry')
+
+            assert_equal(hash, '')
+            assert_equal(hash_expiry, '')
+
+
     def check_validation(self, oldpw, pw, pw2):
         user = M.User.by_username('test-user')
         old_update_time = user.last_password_updated


[05/26] allura git commit: [#5467] Updated failing tests

Posted by je...@apache.org.
[#5467] Updated failing tests


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/746ee514
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/746ee514
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/746ee514

Branch: refs/heads/ib/7830
Commit: 746ee514a962117d7f4e9d7ab62669614e127359
Parents: fa4c23d
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Fri Feb 20 17:31:42 2015 +0000
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Fri Feb 20 17:31:42 2015 +0000

----------------------------------------------------------------------
 .../tests/functional/test_forum.py              | 36 +++++++++++---------
 1 file changed, 20 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/746ee514/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index f557e6c..9c5397f 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -26,7 +26,7 @@ from email.mime.multipart import MIMEMultipart
 
 import pkg_resources
 from pylons import tmpl_context as c
-from nose.tools import assert_equal, assert_in
+from nose.tools import assert_equal, assert_in, assert_not_in
 import feedparser
 
 from allura import model as M
@@ -760,12 +760,14 @@ class TestForum(TestController):
 
     def test_sidebar_menu(self):
         r = self.app.get('/discussion/')
-        sidebarmenu = str(r.html.find('div', {'id': 'sidebar'}))
-        assert '<a href="/p/test/discussion/create_topic/"><b data-icon="+" class="ico ico-plus"></b> <span>Create Topic</span></a>' in sidebarmenu
-        assert '<a href="/p/test/discussion/new_forum"><b data-icon="q" class="ico ico-conversation"></b> <span>Add Forum</span></a>' in sidebarmenu
-        assert '<h3 class="">Help</h3>' in sidebarmenu
-        assert '<a href="/p/test/discussion/markdown_syntax"><span>Formatting Help</span></a>' in sidebarmenu
-        assert '<a href="flag_as_spam" class="sidebar_thread_spam"><b data-icon="^" class="ico ico-flag"></b> <span>Mark as Spam</span></a>' not in sidebarmenu
+        sidebar = r.html.find('div', {'id': 'sidebar'})
+        sidebar_menu = str(sidebar)
+        sidebar_links = [i['href'] for i in sidebar.findAll('a')]
+        assert_in("/p/test/discussion/create_topic/", sidebar_links)
+        assert_in("/p/test/discussion/new_forum", sidebar_links)
+        assert_in('<h3 class="">Help</h3>', sidebar_menu)
+        assert_in("/p/test/discussion/markdown_syntax", sidebar_links)
+        assert_not_in("flag_as_spam", sidebar_links)
         r = self.app.get('/discussion/create_topic/')
         f = r.html.find('form', {'action': '/p/test/discussion/save_new_topic'})
         params = dict()
@@ -778,16 +780,18 @@ class TestForum(TestController):
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'AAA'
         thread = self.app.post('/discussion/save_new_topic', params=params).follow()
         thread_sidebarmenu = str(thread.html.find('div', {'id': 'sidebar'}))
-        assert '<a href="flag_as_spam" class="sidebar_thread_spam"><b data-icon="^" class="ico ico-flag"></b> <span>Mark as Spam</span></a>' in thread_sidebarmenu
+        assert_in("flag_as_spam", thread_sidebarmenu)
 
     def test_sidebar_menu_anon(self):
         r = self.app.get('/discussion/')
-        sidebarmenu = str(r.html.find('div', {'id': 'sidebar'}))
-        assert '<a href="/p/test/discussion/create_topic/"><b data-icon="+" class="ico ico-plus"></b> <span>Create Topic</span></a>' in sidebarmenu
-        assert '<a href="/p/test/discussion/new_forum"><b data-icon="q" class="ico ico-conversation"></b> <span>Add Forum</span></a>' in sidebarmenu
-        assert '<h3 class="">Help</h3>' in sidebarmenu
-        assert '<a href="/p/test/discussion/markdown_syntax"><span>Formatting Help</span></a>' in sidebarmenu
-        assert '<a href="flag_as_spam" class="sidebar_thread_spam"><b data-icon="^" class="ico ico-flag"></b> <span>Mark as Spam</span></a>' not in sidebarmenu
+        sidebar = r.html.find('div', {'id': 'sidebar'})
+        sidebar_menu = str(sidebar)
+        sidebar_links = [i['href'] for i in sidebar.findAll('a')]
+        assert_in("/p/test/discussion/create_topic/", sidebar_links)
+        assert_in("/p/test/discussion/new_forum", sidebar_links)
+        assert_in('<h3 class="">Help</h3>', sidebar_menu)
+        assert_in("/p/test/discussion/markdown_syntax", sidebar_links)
+        assert_not_in("flag_as_spam", sidebar_menu)
         r = self.app.get('/discussion/create_topic/')
         f = r.html.find('form', {'action': '/p/test/discussion/save_new_topic'})
         params = dict()
@@ -800,8 +804,8 @@ class TestForum(TestController):
         params[f.find('input', {'style': 'width: 90%'})['name']] = 'AAA'
         thread = self.app.post('/discussion/save_new_topic',
                                params=params).follow(extra_environ=dict(username='*anonymous'))
-        thread_sidebarmenu = str(thread.html.find('div', {'id': 'sidebar'}))
-        assert '<a href="flag_as_spam" class="sidebar_thread_spam"><b data-icon="^" class="ico ico-flag"></b> <span>Mark as Spam</span></a>' not in thread_sidebarmenu
+        thread_sidebar_menu = str(thread.html.find('div', {'id': 'sidebar'}))
+        assert_not_in("flag_as_spam", thread_sidebar_menu)
 
     def test_feed(self):
         for ext in ['', '.rss', '.atom']:


[22/26] allura git commit: [#7830] ticket:729 Move actual merge to background task

Posted by je...@apache.org.
[#7830] ticket:729 Move actual merge to background task


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/52a40c64
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/52a40c64
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/52a40c64

Branch: refs/heads/ib/7830
Commit: 52a40c64c4e4cf755771ba76328a44d005a85e1a
Parents: ad310b8
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Feb 19 12:14:52 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Feb 26 09:56:36 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py         | 11 +--
 Allura/allura/model/repository.py               | 27 ++++---
 Allura/allura/tasks/repo_tasks.py               | 15 ++++
 Allura/allura/templates/repo/merge_request.html | 82 +++++++++++++++++---
 4 files changed, 107 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/52a40c64/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 0869982..2d1295c 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -365,6 +365,7 @@ class MergeRequestController(object):
         return dict(
             downstream_app=downstream_app,
             req=self.req,
+            status=self.req.merge_task_status(),
             page=page,
             limit=limit,
             count=self.req.discussion_thread.post_count)
@@ -446,13 +447,13 @@ class MergeRequestController(object):
         require_access(c.app, 'write')
         if self.req.status != 'open' or not self.req.can_merge():
             raise exc.HTTPNotFound
-        ok = self.req.merge()
-        if ok:
-            flash('Merged successfully', 'ok')
-        else:
-            flash('Merge failed. Please, merge manually', 'error')
+        self.req.merge()
         redirect(self.req.url())
 
+    @expose('json:')
+    def merge_task_status(self):
+        return {'status': self.req.merge_task_status()}
+
 
 class RefsController(object):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/52a40c64/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 5e4a171..d866598 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -23,7 +23,7 @@ import string
 import re
 from subprocess import Popen, PIPE
 from hashlib import sha1
-from datetime import datetime
+from datetime import datetime, timedelta
 from time import time
 from collections import defaultdict, OrderedDict
 from urlparse import urljoin
@@ -818,16 +818,21 @@ class MergeRequest(VersionedArtifact, ActivityObject):
         return result
 
     def merge(self):
-        if not self.app.forkable:
-            return False
-        try:
-            self.app.repo.merge(self)
-        except:
-            log.exception("Can't merge merge request %s", self.url())
-            return False
-        self.status = 'merged'
-        session(self).flush(self)
-        return True
+        in_progress = self.merge_task_status() in ['ready', 'busy']
+        if self.app.forkable and not in_progress:
+            from allura.tasks import repo_tasks
+            repo_tasks.merge.post(self._id)
+
+    def merge_task_status(self):
+        task = MonQTask.query.find({
+            'state': {'$in': ['busy', 'complete', 'error', 'ready']},  # needed to use index
+            'task_name': 'allura.tasks.repo_tasks.merge',
+            'args': [self._id],
+            'time_queue': {'$gt': datetime.utcnow() - timedelta(days=1)}, # constrain on index further
+        }).sort('_id', -1).limit(1).first()
+        if task:
+            return task.state
+        return None
 
 
 # Basic commit information

http://git-wip-us.apache.org/repos/asf/allura/blob/52a40c64/Allura/allura/tasks/repo_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/repo_tasks.py b/Allura/allura/tasks/repo_tasks.py
index 61cac83..e50f9d2 100644
--- a/Allura/allura/tasks/repo_tasks.py
+++ b/Allura/allura/tasks/repo_tasks.py
@@ -20,6 +20,7 @@ import logging
 import traceback
 
 from pylons import tmpl_context as c, app_globals as g
+from ming.odm import session
 
 from allura.lib.decorators import task
 from allura.lib.repository import RepositoryApp
@@ -152,3 +153,17 @@ def tarball(revision, path):
         log.warn(
             'Skipped creation of snapshot: %s:%s because revision is not specified' %
             (c.project.shortname, c.app.config.options.mount_point))
+
+
+@task
+def merge(merge_request_id):
+    from allura import model as M
+    log = logging.getLogger(__name__)
+    mr = M.MergeRequest.query.get(_id=merge_request_id)
+    try:
+        mr.app.repo.merge(mr)
+    except:
+        log.exception("Can't merge merge request %s", mr.url())
+        return
+    mr.status = 'merged'
+    session(mr).flush(mr)

http://git-wip-us.apache.org/repos/asf/allura/blob/52a40c64/Allura/allura/templates/repo/merge_request.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/merge_request.html b/Allura/allura/templates/repo/merge_request.html
index 060b5b9..1520270 100644
--- a/Allura/allura/templates/repo/merge_request.html
+++ b/Allura/allura/templates/repo/merge_request.html
@@ -33,6 +33,19 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
 {% endblock %}
 
 {% block content %}
+  <div class="grid-19">
+    <div id="task_status">
+      {% if status == 'complete' %}
+        <h2 class="complete">Merged</h2>
+      {% else %}
+        <img src="{{g.forge_static('images/spinner.gif')}}" class="spinner" style="display:none"/>
+        <h2 class="busy ready">Merging...</h2>
+        <h2 class="complete">Merged</h2>
+        <h2 class="fail">Something went wrong. Please, merge manually</h2>
+      {% endif %}
+    </div>
+  </div>
+
   {% if req.downstream_repo %}
     <p>
       <a href="{{req.creator_url}}">{{req.creator_name}}</a>
@@ -49,7 +62,7 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
       <div class="grid-19">
         <form action="merge" method="POST">
           {{ lib.csrf_token() }}
-          <input type="submit" value="Merge"{% if not can_merge %}disabled="disabled"{% endif %}>
+          <input type="submit" value="Merge"{% if not can_merge or status in ('ready', 'busy') %}disabled="disabled"{% endif %}>
           {% if can_merge %}
             <div class="merge-ok">
               Merge request has no conflicts. You can merge automatically.
@@ -68,14 +81,16 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
     <div class="grid-19"><a href="#discussion_holder">Discuss</a></div>
 
     {% if h.has_access(c.app, 'write')() %}
-       <div class="grid-19">To merge the commits, please execute the following commands in your working
-         copy: </div>
-       <div class="grid-19"><textarea
-          style="width:80%; height:60px;"
-          readonly
-          >{{ c.app.repo.merge_command(req) | safe }}</textarea></div>
-      {{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
-       <br style="clear:both">
+      <div class="grid-19">
+        To merge the commits, please execute the following commands in your working copy:
+      </div>
+      <div class="grid-19">
+        <textarea style="width:80%; height:60px;" readonly>{{ c.app.repo.merge_command(req) | safe }}</textarea>
+      </div>
+      {% if status not in ('ready', 'busy') %}
+        {{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
+        <br style="clear:both">
+      {% endif %}
     {% endif %}
   {% else %}
     <p>
@@ -83,12 +98,10 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
       <a href="{{req.creator_url}}">{{req.creator_name}}</a>
       is deleted
     </p>
-
     <div>{{g.markdown.convert(req.description)}}</div>
-
     {% if h.has_access(c.app, 'write')() %}
       {{ c.mr_dispose_form.display(action="save", value=dict(status=req.status)) }}
-       <br style="clear:both">
+      <br style="clear:both">
     {% endif %}
   {% endif %}
 
@@ -111,5 +124,50 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
 <style type="text/css">
   .merge-ok { color: green; }
   .merge-conflicts { color: red; }
+
+  #task_status { margin: 0 10px; }
+  #task_status h2 { display: none; }
+  #task_status .{{ status }} { display: inline-block; }
+  #task_status h2.complete { color: #C6D880; }
+  #task_status h2.busy, #task_status h2.busy { color: #003565; }
+  #task_status h2.fail { color: #f33; }
 </style>
 {% endblock %}
+
+{% block extra_js %}
+{{ super() }}
+<script type="text/javascript">
+$(function() {
+    {% if status in ('ready', 'busy') %}
+        $('.spinner').show();
+        var delay = 500;
+        function check_status() {
+          $.get("{{request.path.rstrip('/') + '/merge_task_status'}}", function(data) {
+                if (data.status === 'complete') {
+                    $('.spinner').hide();
+                    $('#task_status h2').hide();
+                    $('#task_status h2.complete').show();
+                    location.reload();
+                } else {
+                    if (data.status === 'ready' || data.status === 'busy') {
+                        // keep waiting
+                        $('#task_status h2').hide();
+                        $('#task_status h2.busy').show();
+                    } else {
+                        // something went wrong
+                        $('.spinner').hide();
+                        $('#task_status h2').hide();
+                        $('#task_status h2.fail').show();
+                    }
+                    if (delay < 60000){
+                        delay = delay * 2;
+                    }
+                    window.setTimeout(check_status, delay);
+                }
+            });
+        }
+        window.setTimeout(check_status, delay);
+    {% endif %}
+});
+</script>
+{% endblock %}


[11/26] allura git commit: [#7827] ticket:722 New jQuery & base plugins

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/397652f4/Allura/allura/public/nf/js/jquery-base.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/jquery-base.js b/Allura/allura/public/nf/js/jquery-base.js
index 92dfa34..673b5a9 100644
--- a/Allura/allura/public/nf/js/jquery-base.js
+++ b/Allura/allura/public/nf/js/jquery-base.js
@@ -1,410 +1,133 @@
-// This is the minified version of jquery, jquery ui, and some jquery plugins we are using
-
-
-
-/*! jQuery v@1.8.0 jquery.com | jquery.org/license */
-(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(
 a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="scri
 pt"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bX(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bV.length;while(e--){b=bV[e]+c;if(b in a)return b}return d}function bY(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function bZ(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bY(c)&&(e[f]=p._data(c,"olddisplay",cb(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b$(a,b,c){
 var d=bO.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function b_(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bU[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bU[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bU[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bU[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bU[e]+"Width"))||0));return f}function ca(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bP.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+b_(a,b,c||(f?"border":"content"),e)+"px"}function cb(a){if(bR[a])return bR[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createEle
 ment)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bR[a]=c,c}function ch(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||cd.test(a)?d(a,e):ch(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ch(a+"["+e+"]",b[e],c,d);else d(a,b)}function cy(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cz(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cu;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cz(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cz(a,c,d,e,"*",g)),h}function cA(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c
 )c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cB(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cC(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"succe
 ss",data:b}}function cK(){try{return new a.XMLHttpRequest}catch(b){}}function cL(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cT(){return setTimeout(function(){cM=b},0),cM=p.now()}function cU(a,b){p.each(b,function(b,c){var d=(cS[b]||[]).concat(cS["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cV(a,b,c){var d,e=0,f=0,g=cR.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cM||cT(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cM||cT(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.t
 weens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cW(k,j.opts.specialEasing);for(;e<g;e++){d=cR[e].call(j,a,k,j.opts);if(d)return d}return cU(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cW(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cX(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bY(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||
 "width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cb(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cO.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cY(a,b,c,d,e){return new cY.prototype.init(a,b,c,d,e)}function cZ(a,b){var c,d={height:a},e=0;for(;e<4;e+=2-b)c=bU[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d
 .width=a),d}function c_(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=r.test("Â ")?/^[\s\xA0]+|[\s\xA0]+$/g:/^\s+|\s+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:f
 unction(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);retur
 n d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)conti
 nue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.
 prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("I
 nvalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":a.toString().replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:funct
 ion(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||f.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));i
 f(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete"||e.readyState!=="loading"&&e.addEventListener)setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g
 ;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){p.isFunction(c)&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callb
 acks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return typeof a=="object"?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.
 notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length||!d)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,check
 On:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).
 cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;displa
 y:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/^(?:\{.*\}|\[.*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQ
 uery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||++p.uuid:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]]
 ;if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")===0&&(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a
 ,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.shift(),e=p._queueHooks(a,b),f=function(){p.dequeue(a,b)};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),delete e.stop,d.call(a,f,e)),!c.length&&e&&e.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeu
 e:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)(d=p._data(g[h],a+"queueHooks"))&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.pr
 op,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)~f.indexOf(" "+b[g]+" ")||(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>-1)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleCl
 ass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.v
 al()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return
 ;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,""+d),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,
 b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id
 :!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.sele
 ctedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arg
 uments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split
 (".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join
 ("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f
 [m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,k,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=[].slice.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click")){g=p(this),g.context=this;for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){i={},k=[],g[0]=f;for(d=0;d<q;d++)l=o[d],m=l.selector,i[m]===b&&(i[m]=g.is(m)),i[m]&&k.push(l);k.length&&u.push({elem:f,matches:k})}}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){j=u[d],c.currentTarget=j.elem;for(e=0;e<j.matches.length&&!c.isImmediatePropagationStopped();e++){l=j.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj
 =l,h=((p.event.special[l.origType]||{}).handle||l.handler).apply(j.elem,r),h!==b&&(c.result=h,h===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g
 &&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{ready:{setup:p.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventLis
 tener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationSto
 pped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(
 this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simu
 late(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(
 this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown 
 mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bd(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)Z(a,b[e],c,d)}function be(a,b,c,d,e,f){var g,h=$.setFilters[b.toLowerCase()];return h||Z.error(b),(a||!(g=e))&&bd(a||"*",d,g=[],e),g.length>0?h(g,c,f):[]}function bf(a,c,d,e,f){var g,h,i,j,k,l,m,n,p=0,q=f.length,s=L.POS,t=new RegExp("^"+s.source+"(?!"+r+")","i"),u=function(){var a=1,c=arguments.length-2;for(;a<c;a++)arguments[a]===b&&(g[a]=b)};for(;p<q;p++){s.exec(""),a=f[p],j=[],i=0,k=e;while(g=s.exec(a)){n=s.lastIndex=g.index+g[0].length;if(n>i){m=a.slice(i,g.index),i=n,l=[c],B.test(m)&&(k&&(l=k),k=e);if(h=H.test(m))m=m.slice(0,-5).replace(B,"$&*");g.length>1&&g[0
 ].replace(t,u),k=be(m,g[1],g[2],l,k,h)}}k?(j=j.concat(k),(m=a.slice(i))&&m!==")"?B.test(m)?bd(m,j,d,e):Z(m,c,d,e?e.concat(k):k):o.apply(d,j)):Z(a,c,d,e)}return q===1?d:Z.uniqueSort(d)}function bg(a,b,c){var d,e,f,g=[],i=0,j=D.exec(a),k=!j.pop()&&!j.pop(),l=k&&a.match(C)||[""],m=$.preFilter,n=$.filter,o=!c&&b!==h;for(;(e=l[i])!=null&&k;i++){g.push(d=[]),o&&(e=" "+e);while(e){k=!1;if(j=B.exec(e))e=e.slice(j[0].length),k=d.push({part:j.pop().replace(A," "),captures:j});for(f in n)(j=L[f].exec(e))&&(!m[f]||(j=m[f](j,b,c)))&&(e=e.slice(j.shift().length),k=d.push({part:f,captures:j}));if(!k)break}}return k||Z.error(a),g}function bh(a,b,e){var f=b.dir,g=m++;return a||(a=function(a){return a===e}),b.first?function(b,c){while(b=b[f])if(b.nodeType===1)return a(b,c)&&b}:function(b,e){var h,i=g+"."+d,j=i+"."+c;while(b=b[f])if(b.nodeType===1){if((h=b[q])===j)return b.sizset;if(typeof h=="string"&&h.indexOf(i)===0){if(b.sizset)return b}else{b[q]=j;if(a(b,e))return b.sizset=!0,b;b.sizset=!1}}}}fun
 ction bi(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function bj(a,b,c){var d,e,f=0;for(;d=a[f];f++)$.relative[d.part]?e=bh(e,$.relative[d.part],b):(d.captures.push(b,c),e=bi(e,$.filter[d.part].apply(null,d.captures)));return e}function bk(a){return function(b,c){var d,e=0;for(;d=a[e];e++)if(d(b,c))return!0;return!1}}var c,d,e,f,g,h=a.document,i=h.documentElement,j="undefined",k=!1,l=!0,m=0,n=[].slice,o=[].push,q=("sizcache"+Math.random()).replace(".",""),r="[\\x20\\t\\r\\n\\f]",s="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",t=s.replace("w","w#"),u="([*^$|!~]?=)",v="\\["+r+"*("+s+")"+r+"*(?:"+u+r+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+t+")|)|)"+r+"*\\]",w=":("+s+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",x=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",y=r+"*([\\x20\\t\\r\\n\\f>+~])"+r+"*",z="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+v+"|"+w.replace(2,7)+"|[^\\\\(),])+",A=new RegExp("^"+r+"+
 |((?:^|[^\\\\])(?:\\\\.)*)"+r+"+$","g"),B=new RegExp("^"+y),C=new RegExp(z+"?(?="+r+"*,|$)","g"),D=new RegExp("^(?:(?!,)(?:(?:^|,)"+r+"*"+z+")*?|"+r+"*(.*?))(\\)|$)"),E=new RegExp(z.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+y,"g"),F=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,G=/[\x20\t\r\n\f]*[+~]/,H=/:not\($/,I=/h\d/i,J=/input|select|textarea|button/i,K=/\\(?!\\)/g,L={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),NAME:new RegExp("^\\[name=['\"]?("+s+")['\"]?\\]"),TAG:new RegExp("^("+s.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+v),PSEUDO:new RegExp("^"+w),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+r+"*(even|odd|(([+-]|)(\\d*)n|)"+r+"*(?:([+-]|)"+r+"*(\\d+)|))"+r+"*\\)|)","i"),POS:new RegExp(x,"ig"),needsContext:new RegExp("^"+r+"*[>+~]|"+x,"i")},M={},N=[],O={},P=[],Q=function(a){return a.sizzleFilter=!0,a},R=function(a){return function(b){return b.nodeName.toLowerCase()==="input"&&b.type===a}},S=function(a){return function(b){var c=b.nodeName.toLowerCase();retur
 n(c==="input"||c==="button")&&b.type===a}},T=function(a){var b=!1,c=h.createElement("div");try{b=a(c)}catch(d){}return c=null,b},U=T(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),V=T(function(a){a.id=q+0,a.innerHTML="<a name='"+q+"'></a><div name='"+q+"'></div>",i.insertBefore(a,i.firstChild);var b=h.getElementsByName&&h.getElementsByName(q).length===2+h.getElementsByName(q+0).length;return g=!h.getElementById(q),i.removeChild(a),b}),W=T(function(a){return a.appendChild(h.createComment("")),a.getElementsByTagName("*").length===0}),X=T(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==j&&a.firstChild.getAttribute("href")==="#"}),Y=T(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||a.getElementsByClassName("e").length===0?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length!
 ==1)}),Z=function(a,b,c,d){c=c||[],b=b||h;var e,f,g,i,j=b.nodeType;if(j!==1&&j!==9)return[];if(!a||typeof a!="string")return c;g=ba(b);if(!g&&!d)if(e=F.exec(a))if(i=e[1]){if(j===9){f=b.getElementById(i);if(!f||!f.parentNode)return c;if(f.id===i)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(i))&&bb(b,f)&&f.id===i)return c.push(f),c}else{if(e[2])return o.apply(c,n.call(b.getElementsByTagName(a),0)),c;if((i=e[3])&&Y&&b.getElementsByClassName)return o.apply(c,n.call(b.getElementsByClassName(i),0)),c}return bm(a,b,c,d,g)},$=Z.selectors={cacheLength:50,match:L,order:["ID","TAG"],attrHandle:{},createPseudo:Q,find:{ID:g?function(a,b,c){if(typeof b.getElementById!==j&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==j&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==j&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:W?function(a,b){if(typeof b.getElementsByTagName!==j)retu
 rn b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(K,""),a[3]=(a[4]||a[5]||"").replace(K,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||Z.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&Z.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return L.CHILD.test(a[0])?null:(c&&(b=D.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:g?function(a){return a=a.replace(K,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(K,""),function(b){var c=typeof b.getAttributeNode!==
 j&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(K,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=M[a];return b||(b=M[a]=new RegExp("(^|"+r+")"+a+"("+r+"|$)"),N.push(a),N.length>$.cacheLength&&delete M[N.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==j&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=Z.attr(d,a),f=e+"";if(e==null)return b==="!=";switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&f.indexOf(c)===0;case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return Z.attr(b,a)!=null}},CHILD:function(a,b,c,d){if(a==="nth"){var e=m++;return function(a){var b,f,g=0,h=a;if(c===1&&d===0)return!0;b=a.parentNode;if(b&&(b[q]!==e||!a.sizset)){for
 (h=b.firstChild;h;h=h.nextSibling)if(h.nodeType===1){h.sizset=++g;if(h===a)break}b[q]=e}return f=a.sizset-d,c===0?f===0:f%c===0&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=$.pseudos[a]||$.pseudos[a.toLowerCase()];return e||Z.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:Q(function(a,b,c){var d=bl(a.replace(A,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!$.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.n
 odeType)===3||b===4)return!1;a=a.nextSibling}return!0},contains:Q(function(a){return function(b){return(b.textContent||b.innerText||bc(b)).indexOf(a)>-1}}),has:Q(function(a){return function(b){return Z(a,b).length>0}}),header:function(a){return I.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:R("radio"),checkbox:R("checkbox"),file:R("file"),password:R("password"),image:R("image"),submit:S("submit"),reset:S("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return J.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function
 (a,b,c){var d=[],e=c?1:0,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},odd:function(a,b,c){var d=[],e=c?0:1,f=a.length;for(;e<f;e=e+2)d.push(a[e]);return d},lt:function(a,b,c){return c?a.slice(+b):a.slice(0,+b)},gt:function(a,b,c){return c?a.slice(0,+b+1):a.slice(+b+1)},eq:function(a,b,c){var d=a.splice(+b,1);return c?a:d}}};$.setFilters.nth=$.setFilters.eq,$.filters=$.pseudos,X||($.attrHandle={href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}}),V&&($.order.push("NAME"),$.find.NAME=function(a,b){if(typeof b.getElementsByName!==j)return b.getElementsByName(a)}),Y&&($.order.splice(1,0,"CLASS"),$.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!==j&&!c)return b.getElementsByClassName(a)});try{n.call(i.childNodes,0)[0].nodeType}catch(_){n=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}var ba=Z.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},bb=Z.contains=i.comp
 areDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16)}:i.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc=Z.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=bc(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=bc(b);return c};Z.attr=function(a,b){var c,d=ba(a);return d||(b=b.toLowerCase()),$.attrHandle[b]?$.attrHandle[b](a):U||d?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},Z.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},[0,0].sort(function(){return l=0}),i.compareDocumentPosition?e=function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPo
 sition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:(e=function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],g=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return f(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)g.unshift(j),j=j.parentNode;c=e.length,d=g.length;for(var l=0;l<c&&l<d;l++)if(e[l]!==g[l])return f(e[l],g[l]);return l===c?f(a,g[l],-1):f(e[l],b,1)},f=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),Z.uniqueSort=function(a){var b,c=1;if(e){k=l,a.sort(e);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1)}return a};var bl=Z.compile=function(a,b,c){var d,e,f,g=O[a];if(g&&g.context===b)return g;e=bg(a,b,c);for(f=0;d=e[f];f++)e[f]=bj(d,b,c);return g=O[a]=bk(e),g.context=b,g.runs=g.dirruns=0,P.push(a),P.length>$.cacheLength&&delete O[P.shift()],g};Z.matches=function(a,b){return Z(a,null,null,b)},Z.matchesSe
 lector=function(a,b){return Z(b,null,null,[a]).length>0};var bm=function(a,b,e,f,g){a=a.replace(A,"$1");var h,i,j,k,l,m,p,q,r,s=a.match(C),t=a.match(E),u=b.nodeType;if(L.POS.test(a))return bf(a,b,e,f,s);if(f)h=n.call(f,0);else if(s&&s.length===1){if(t.length>1&&u===9&&!g&&(s=L.ID.exec(t[0]))){b=$.find.ID(s[1],b,g)[0];if(!b)return e;a=a.slice(t.shift().length)}q=(s=G.exec(t[0]))&&!s.index&&b.parentNode||b,r=t.pop(),m=r.split(":not")[0];for(j=0,k=$.order.length;j<k;j++){p=$.order[j];if(s=L[p].exec(m)){h=$.find[p]((s[1]||"").replace(K,""),q,g);if(h==null)continue;m===r&&(a=a.slice(0,a.length-r.length)+m.replace(L[p],""),a||o.apply(e,n.call(h,0)));break}}}if(a){i=bl(a,b,g),d=i.dirruns++,h==null&&(h=$.find.TAG("*",G.test(a)&&b.parentNode||b));for(j=0;l=h[j];j++)c=i.runs++,i(l,b)&&e.push(l)}return e};h.querySelectorAll&&function(){var a,b=bm,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[],f=[":active"],g=i.matchesSelector||i.mozMatchesSelector||i.webkitMatchesSelector||i.
 oMatchesSelector||i.msMatchesSelector;T(function(a){a.innerHTML="<select><option selected></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+r+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),T(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+r+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),bm=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a)))if(d.nodeType===9)try{return o.apply(f,n.call(d.querySelectorAll(a),0)),f}catch(i){}else if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){var j=d.getAttribute("id"),k=j||q,l=G.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return o.apply(f,n.call(l.querySelectorAll(a.replace(C,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return 
 b(a,d,f,g,h)},g&&(T(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push($.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),Z.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!ba(b)&&!f.test(c)&&(!e||!e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&b.document.nodeType!==11)return h}catch(i){}return Z(c,null,null,[b]).length>0})}(),Z.attr=p.attr,p.find=Z,p.expr=Z.selectors,p.expr[":"]=p.expr.pseudos,p.unique=Z.uniqueSort,p.text=Z.getText,p.isXMLDoc=Z.isXML,p.contains=Z.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splic
 e(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p
 .merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p
 .map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new Re
 gExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={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,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this
 [0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function
 (a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.no
 deType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(
 ){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=(c[0]||c).ownerDocument||c[0]||c,typeof c.createDocumentFragment=="undefined"&&(c=e),a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=
 p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return
  d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=0,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(g=b===e&&bA;(h=a[s])!=null;s++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{g=g||bk(b),l=l||g.appendChild(b.createElement("div")),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(f=n.length-1;f>=0;--f)p.nodeName(n[f],"tbody")&&!n[f].childNodes.length&&n[f].parentNode.removeChild(n[f])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l=g.lastChild}h.nodeType?t.push(h):t=p.merge(t,h)}l&&(g.removeChild(l),h=l=g=null);if(!p.support.appendChecked)for(s=0;(h=t[s])!=null;s++)p.nodeName(h,"input")?bG(h):typ
 eof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(s=0;(h=t[s])!=null;s++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[s+1,0].concat(r)),s+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(m
 sie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^margin/,bO=new RegExp("^("+q+")(.*)$","i"),bP=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bQ=new RegExp("^([-+])=("+q+")","i"),bR={},bS={position:"absolute",visibility:"hidden",display:"block"},bT={letterSpacing:0,fontWeight:400,lineHeight:1},bU=["Top","Right","Bottom","Left"],bV=["Webkit","O","Moz","ms"],bW=p.fn.toggle;p.fn.extend({css:func
 tion(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return bZ(this,!0)},hide:function(){return bZ(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bW.apply(this,arguments):this.each(function(){(c?a:bY(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bX(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bQ.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&i
 sNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bX(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bT&&(f=bT[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],c===""&&!p.contains(a.ownerDocument.documentElement,a)&&(c=p.style(a,b)),bP.test(c)&&bN.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bP.test(e)&&!bM.t
 est(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0||bH(a,"display")!=="none"?ca(a,b,d):p.swap(a,bS,function(){return ca(a,b,d)})},set:function(a,c,d){return b$(a,c,d?b_(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMar
 ginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bP.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bU[d]+b]=e[d]||e[d-2]||e[0];return f}},bN.test(a)||(p.cssHooks[a+b].set=b$)});var cc=/%20/g,cd=/\[\]$/,ce=/\r?\n/g,cf=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,cg=/^(?:select|
 textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||cg.test(this.nodeName)||cf.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(ce,"\r\n")}}):{name:b.name,value:c.replace(ce,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ch(d,a[d],c,f);return e.join("&").replace(cc,"+")};var ci,cj,ck=/#.*$/,cl=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cm=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,cn=/^(?:GET|HEAD)$
 /,co=/^\/\//,cp=/\?/,cq=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cr=/([?&])_=[^&]*/,cs=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,ct=p.fn.load,cu={},cv={},cw=["*/"]+["*"];try{ci=f.href}catch(cx){ci=e.createElement("a"),ci.href="",ci=ci.href}cj=cs.exec(ci.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&ct)return ct.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cq,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({t
 ype:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cA(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cA(a,b),a},ajaxSettings:{url:ci,isLocal:cm.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cw},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cy(cu),ajaxTransport:cy(cv),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cB(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHe
 ader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cC(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=""+(c||y),k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cl.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}retur
 n c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(ck,"").replace(co,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=cs.exec(l.url.toLowerCase()),l.crossDomain=!(!i||i[1]==cj[1]&&i[2]==cj[2]&&(i[3]||(i[1]==="http:"?80:443))==(cj[3]||(cj[1]==="http:"?80:443)))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cz(cu,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!cn.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cp.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cr,"$1_="+z);l.url=A+(A==
 =l.url?(cp.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cw+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cz(cv,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cD=[],cE=/\?/,cF=/(=)\?(?=&|$)|\?\?/,cG=p.now();p.ajaxSetup({
 jsonp:"callback",jsonpCallback:function(){var a=cD.pop()||p.expando+"_"+cG++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cF.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cF.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cF,"$1"+f):m?c.data=i.replace(cF,"$1"+f):k&&(c.url+=(cE.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cD.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":f
 unction(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cH,cI=a.ActiveXObject?function(){for(var a in cH)cH[a](0,1)}:!1,cJ=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cK()||cL()}:cK,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){
 var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cI&&delete cH[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cJ,cI&&(cH||(cH={},p(a).unload(cI)),cH[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}})
 ;var cM,cN,cO=/^(?:toggle|show|hide)$/,cP=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cQ=/queueHooks$/,cR=[cX],cS={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=cP.exec(b),h=f.cur(),i=+h||0,j=1;if(g){c=+g[2],d=g[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&i){i=p.css(f.elem,a,!0)||c||1;do e=j=j||".5",i=i/j,p.style(f.elem,a,i+d),j=f.cur()/h;while(j!==1&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};p.Animation=p.extend(cV,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cS[c]=cS[c]||[],cS[c].unshift(b)},prefilter:function(a,b){b?cR.unshift(a):cR.push(a)}}),p.Tween=cY,cY.prototype={constructor:cY,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cY.propHooks[this.prop];return a&&a.get?a.get(this):cY.propHooks._default.get(this)},run:function(a){var b,c=cY.pro
 pHooks[this.prop];return this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration),this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cY.propHooks._default.set(this),this}},cY.prototype.init.prototype=cY.prototype,cY.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cY.propHooks.scrollTop=cY.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,argu
 ments):this.animate(cZ(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bY).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cV(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cQ.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:cZ("show"),slideUp:cZ("hide"),slideToggle:cZ("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.
 animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration

<TRUNCATED>

[10/26] allura git commit: [#7827] ticket:722 New jQuery & base plugins

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/397652f4/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index dc21fd8..1027bd6 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -23,6 +23,7 @@
   {% import g.theme.jinja_macros as theme_macros with context %}
 {% endif %}
 {% do g.register_forge_js('js/jquery-base.js') %}
+{% do g.register_forge_js('js/jquery-migrate-1.2.1.js') %}
 {% do g.register_forge_js('js/jquery.notify.js') %}
 {% do g.register_forge_js('js/modernizr.js') %}
 {% do g.register_forge_js('js/sylvester.js') %}


[13/26] allura git commit: [#7827] ticket:722 Fix some jquery-migrate warnings

Posted by je...@apache.org.
[#7827] ticket:722 Fix some jquery-migrate warnings

- Use `prop` instead of `attr` for properties
- Fix our custom combobox plugin


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0ce4968f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0ce4968f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0ce4968f

Branch: refs/heads/ib/7830
Commit: 0ce4968f8861bfeeb29b5818bfe6f6e90717666a
Parents: e6b42cc
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Feb 9 16:00:19 2015 +0200
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:19 2015 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/templates/export.html             |  2 +-
 Allura/allura/ext/admin/templates/project_overview.html   | 10 +++++-----
 Allura/allura/lib/widgets/form_fields.py                  |  2 +-
 Allura/allura/lib/widgets/forms.py                        |  8 ++++----
 Allura/allura/lib/widgets/resources/js/combobox.js        |  2 +-
 ForgeShortUrl/forgeshorturl/templates/index.html          |  6 +++---
 .../forgetracker/templates/tracker/admin_fields.html      |  4 ++--
 .../forgetracker/templates/tracker/milestones.html        |  4 ++--
 .../forgetracker/widgets/resources/js/mass-edit.js        |  4 ++--
 .../forgetracker/widgets/resources/js/ticket-list.js      |  2 +-
 ForgeTracker/forgetracker/widgets/ticket_form.py          |  2 +-
 11 files changed, 23 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/Allura/allura/ext/admin/templates/export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/export.html b/Allura/allura/ext/admin/templates/export.html
index a8081f1..c8b7c2b 100644
--- a/Allura/allura/ext/admin/templates/export.html
+++ b/Allura/allura/ext/admin/templates/export.html
@@ -27,7 +27,7 @@
   <script type="text/javascript">
     $(function() {
       $('#check-all').click(function() {
-        $(':checkbox[name="tools"]').attr('checked', $(this).attr('checked') || null);
+        $(':checkbox[name="tools"]').prop('checked', $(this).prop('checked'));
       });
     });
   </script>

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/Allura/allura/ext/admin/templates/project_overview.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_overview.html b/Allura/allura/ext/admin/templates/project_overview.html
index af2aca1..3991241 100644
--- a/Allura/allura/ext/admin/templates/project_overview.html
+++ b/Allura/allura/ext/admin/templates/project_overview.html
@@ -50,10 +50,10 @@
       var $moved_to_url = $('input[name=moved_to_url]');
       var update_url = function(check_cb, url_input){
         if(check_cb.is(':checked')){
-          url_input.attr('disabled', false);
+          url_input.prop('disabled', false);
         }
         else{
-          url_input.attr('disabled', true);
+          url_input.prop('disabled', true);
           url_input.val('');
         }
       };
@@ -92,13 +92,13 @@
             $('#metadata_form').submit();
           }
           else{
-            $removal_original.attr('checked', true);
+            $removal_original.prop('checked', true);
           }
         }
         {% if not allow_project_undelete %}
         else if($(this).val()!=='deleted' && currently_deleted){
           alert('You may not undelete a project that has already been deleted.');
-          $removal_original.attr('checked', true);
+          $removal_original.prop('checked', true);
         }
         {% else %}
         else if($(this).val()!=='deleted' && currently_deleted){
@@ -107,7 +107,7 @@
             $('#metadata_form').submit();
           }
           else{
-            $removal_original.attr('checked', true);
+            $removal_original.prop('checked', true);
           }
         }
         {% endif %}

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index a43014a..7d94e47 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -87,7 +87,7 @@ class LabelEdit(ew.InputField):
                       if ((value !== default_value) && (!exists) && value !== '') {
                           $('input.label_edit').addTag(value);
                       }
-                      $('input[type=submit]', this).attr('disabled', 'disabled');
+                      $('input[type=submit]', this).prop('disabled', true);
                   }
                 }, 1);
             });

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/Allura/allura/lib/widgets/forms.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index 6f23e40..27fd242 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -891,12 +891,12 @@ table.table_class select.add_opt {width: 5em; margin:0; padding: 0;}
                 var inp_name = cb_name.substr(0, cb_name.length-4);
                 var inp_el = $('div[class="'+inp_name+'-inp"]');
 
-                if ($(this).attr('checked')) {
+                if ($(this).prop('checked')) {
                   inp_el.hide();
                 }
 
                 $(element).click(function(e) {
-                  if ($(this).attr('checked')) {
+                  if ($(this).prop('checked')) {
                     inp_el.hide();
                   } else {
                     inp_el.show();
@@ -1003,11 +1003,11 @@ class NeighborhoodAddProjectForm(ForgeForm):
                     }
                 });
                 $scms.change(function(){
-                    if ( $(this).attr('checked') ) {
+                    if ( $(this).prop('checked') ) {
                         var on = this;
                         $scms.each(function(){
                             if ( this !== on ) {
-                                $(this).removeAttr('checked');
+                                $(this).prop('checked', false);
                             }
                         });
                     }

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/Allura/allura/lib/widgets/resources/js/combobox.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/combobox.js b/Allura/allura/lib/widgets/resources/js/combobox.js
index 60e1b9a..b36c3df 100644
--- a/Allura/allura/lib/widgets/resources/js/combobox.js
+++ b/Allura/allura/lib/widgets/resources/js/combobox.js
@@ -131,7 +131,7 @@
                 }
               });
 
-      input.data('autocomplete')._renderItem = function(ul, item) {
+      input.autocomplete('instance')._renderItem = function(ul, item) {
         return $('<li>')
           .data('item.autocomplete', item)
           .append('<a>' + item.label + '</a>')

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/ForgeShortUrl/forgeshorturl/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/templates/index.html b/ForgeShortUrl/forgeshorturl/templates/index.html
index c0607f3..e370812 100644
--- a/ForgeShortUrl/forgeshorturl/templates/index.html
+++ b/ForgeShortUrl/forgeshorturl/templates/index.html
@@ -75,13 +75,13 @@
                   modal.find('#short-url-form-title').show();
                   modal.find('#short-url-form-action-label').text('Update');
                   modal.find('input[name="update"]').val('True');
-                  modal.find('input[name="short_url"]').val('{{ su.short_name }}').attr('readonly', true).trigger('keyup');
+                  modal.find('input[name="short_url"]').val('{{ su.short_name }}').prop('readonly', true).trigger('keyup');
                   modal.find('input[name="full_url"]').val('{{ su.full_url }}');
                   modal.find('textarea[name="description"]').val('{{su.description|replace("\n", "\\n")|replace("\r", "\\r")}}');
                   if ('{{ su.private }}' == 'True') {
-                    modal.find('input[name="private"]').attr('checked', 'checked');
+                    modal.find('input[name="private"]').prop('checked', true);
                   } else {
-                    modal.find('input[name="private"]').removeAttr('checked');
+                    modal.find('input[name="private"]').prop('checked', false);
                   }
                   return false;
                 });

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/ForgeTracker/forgetracker/templates/tracker/admin_fields.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/admin_fields.html b/ForgeTracker/forgetracker/templates/tracker/admin_fields.html
index 1d09e3c..33f05a7 100644
--- a/ForgeTracker/forgetracker/templates/tracker/admin_fields.html
+++ b/ForgeTracker/forgetracker/templates/tracker/admin_fields.html
@@ -66,8 +66,8 @@
             // page can contain more that one milestone field,
             // so we should touch only radio buttons corresponding to given field
             var parent_table = $(this).closest('table');
-            $(":radio.default-milestone", parent_table).attr("checked", false);
-            $(this).attr("checked", true);
+            $(":radio.default-milestone", parent_table).prop("checked", false);
+            $(this).prop("checked", true);
         });
     });
 </script>

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/ForgeTracker/forgetracker/templates/tracker/milestones.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/milestones.html b/ForgeTracker/forgetracker/templates/tracker/milestones.html
index 3dc748c..a5e6db9 100644
--- a/ForgeTracker/forgetracker/templates/tracker/milestones.html
+++ b/ForgeTracker/forgetracker/templates/tracker/milestones.html
@@ -139,8 +139,8 @@
         return false;
       });
       $(':radio.default-milestone').click(function(){
-          $(':radio.default-milestone').attr("checked", false);
-          $(this).attr("checked", true);
+          $(':radio.default-milestone').prop("checked", false);
+          $(this).prop("checked", true);
       });
       $('a.cancel_edit').click(function(){
         $('td.view', $form).show();

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js b/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js
index 798473d..35d91aa 100644
--- a/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js
+++ b/ForgeTracker/forgetracker/widgets/resources/js/mass-edit.js
@@ -29,10 +29,10 @@ $(function(){
     $('#assigned_to').val('');
     $('#select_all').click(function(){
         if(this.checked){
-            $('tbody.ticket-list input[type=checkbox]').attr('checked', 'checked');
+            $('tbody.ticket-list input[type=checkbox]').prop('checked', true);
         }
         else{
-            $('tbody.ticket-list input[type=checkbox]').removeAttr('checked');
+            $('tbody.ticket-list input[type=checkbox]').prop('checked', false);
         }
     });
     $form.submit(function(){

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js b/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
index 138270c..9221389 100644
--- a/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
+++ b/ForgeTracker/forgetracker/widgets/resources/js/ticket-list.js
@@ -21,7 +21,7 @@
 
     function ico_active() {
       $('.ticket-filter').each(function() {
-        if ($(this).find('select option').attr('selected')) {
+        if ($(this).find('select option').prop('selected')) {
           $(this).parent().css('color', 'green');
         } else {
           $(this).parent().css('color', '');

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce4968f/ForgeTracker/forgetracker/widgets/ticket_form.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index 0ac3973..d107aeb 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -160,7 +160,7 @@ class TicketForm(GenericTicketForm):
                 evt.preventDefault();
             });
             $('form').submit(function() {
-                $('input[type=submit]', this).attr('disabled', 'disabled');
+                $('input[type=submit]', this).prop('disabled', true);
             });
             $('div.reply.discussion-post a.markdown_preview').click(function(){
                 var arrow = $(this).closest('.discussion-post').find('span.arw');


[08/26] allura git commit: [#7827] ticket:722 Emit jquery to the

Posted by je...@apache.org.
[#7827] ticket:722 Emit jquery to the <head>

By default g.register_forge_js emits js to the <body> tail, but some tools
can independently emit js pieces into the body *before* jquery, which
leads to "Uncaught ReferenceError: $ is not defined".

For example it affects ticket bin counts, which are loaded by ajax call.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e6b42cc0
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e6b42cc0
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e6b42cc0

Branch: refs/heads/ib/7830
Commit: e6b42cc0fd4a32088196419ce05fbd90b2836465
Parents: 6367496
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Feb 9 15:32:48 2015 +0200
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:18 2015 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/master.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e6b42cc0/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index 1027bd6..0dd1e92 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -22,7 +22,7 @@
 {% if g.theme.jinja_macros %}
   {% import g.theme.jinja_macros as theme_macros with context %}
 {% endif %}
-{% do g.register_forge_js('js/jquery-base.js') %}
+{% do g.register_forge_js('js/jquery-base.js', location='head_js') %}
 {% do g.register_forge_js('js/jquery-migrate-1.2.1.js') %}
 {% do g.register_forge_js('js/jquery.notify.js') %}
 {% do g.register_forge_js('js/modernizr.js') %}


[18/26] allura git commit: [#7827] ticket:734 Get rid of (not used) tooltip

Posted by je...@apache.org.
[#7827] ticket:734 Get rid of (not used) tooltip


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0180e68a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0180e68a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0180e68a

Branch: refs/heads/ib/7830
Commit: 0180e68a530da411c32aac7fbbd573b7805884e0
Parents: 0660ec4
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Feb 24 11:15:43 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:21 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/project_list.py       | 21 --------------------
 .../widgets/resources/js/jquery.tools.min.js    | 17 ----------------
 Allura/allura/public/nf/js/allura-base.js       |  6 ------
 3 files changed, 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0180e68a/Allura/allura/lib/widgets/project_list.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/project_list.py b/Allura/allura/lib/widgets/project_list.py
index cc2b933..b5aa619 100644
--- a/Allura/allura/lib/widgets/project_list.py
+++ b/Allura/allura/lib/widgets/project_list.py
@@ -83,27 +83,6 @@ class ProjectSummary(ew_core.Widget):
 
         return response
 
-    def resources(self):
-        yield ew.JSLink('js/jquery.tools.min.js')
-        yield ew.JSScript('''
-        $(document).ready(function () {
-            var badges = $('small.badge');
-            var i = badges.length;
-            while (i) {
-                i--;
-                var tipHolder = document.createElement('div');
-                tipHolder.id = "tip" + i;
-                tipHolder.className = "tip";
-                document.body.appendChild(tipHolder);
-                $(badges[i]).parent('a[title]').tooltip({
-                    tip: '#tip' + i,
-                    opacity: '.9',
-                    offset: [-10, 0]
-                });
-            }
-        });
-        ''')
-
 
 class ProjectList(ew_core.Widget):
     template = 'jinja:allura:templates/widgets/project_list_widget.html'

http://git-wip-us.apache.org/repos/asf/allura/blob/0180e68a/Allura/allura/lib/widgets/resources/js/jquery.tools.min.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/jquery.tools.min.js b/Allura/allura/lib/widgets/resources/js/jquery.tools.min.js
deleted file mode 100644
index 2baa515..0000000
--- a/Allura/allura/lib/widgets/resources/js/jquery.tools.min.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * jquery.tools 1.1.2 - The missing UI library for the Web
- * 
- * [tools.tooltip-1.1.3]
- * 
- * Copyright (c) 2009 Tero Piirainen
- * http://flowplayer.org/tools/
- *
- * Dual licensed under MIT and GPL 2+ licenses
- * http://www.opensource.org/licenses
- * 
- * -----
- * 
- * File generated: Mon Mar 22 08:45:44 GMT 2010
- */
-(function(c){var d=[];c.tools=c.tools||{};c.tools.tooltip={version:"1.1.3",conf:{effect:"toggle",fadeOutSpeed:"fast",tip:null,predelay:0,delay:30,opacity:1,lazy:undefined,position:["top","center"],offset:[0,0],cancelDefault:true,relative:false,oneInstance:true,events:{def:"mouseover,mouseout",input:"focus,blur",widget:"focus mouseover,blur mouseout",tooltip:"mouseover,mouseout"},api:false},addEffect:function(e,g,f){b[e]=[g,f]}};var b={toggle:[function(e){var f=this.getConf(),g=this.getTip(),h=f.opacity;if(h<1){g.css({opacity:h})}g.show();e.call()},function(e){this.getTip().hide();e.call()}],fade:[function(e){this.getTip().fadeIn(this.getConf().fadeInSpeed,e)},function(e){this.getTip().fadeOut(this.getConf().fadeOutSpeed,e)}]};function a(f,g){var p=this,k=c(this);f.data("tooltip",p);var l=f.next();if(g.tip){l=c(g.tip);if(l.length>1){l=f.nextAll(g.tip).eq(0);if(!l.length){l=f.parent().nextAll(g.tip).eq(0)}}}function o(u){var t=g.relative?f.position().top:f.offset().top,s=g.relative?f.
 position().left:f.offset().left,v=g.position[0];t-=l.outerHeight()-g.offset[0];s+=f.outerWidth()+g.offset[1];var q=l.outerHeight()+f.outerHeight();if(v=="center"){t+=q/2}if(v=="bottom"){t+=q}v=g.position[1];var r=l.outerWidth()+f.outerWidth();if(v=="center"){s-=r/2}if(v=="left"){s-=r}return{top:t,left:s}}var i=f.is(":input"),e=i&&f.is(":checkbox, :radio, select, :button"),h=f.attr("type"),n=g.events[h]||g.events[i?(e?"widget":"input"):"def"];n=n.split(/,\s*/);if(n.length!=2){throw"Tooltip: bad events configuration for "+h}f.bind(n[0],function(r){if(g.oneInstance){c.each(d,function(){this.hide()})}var q=l.data("trigger");if(q&&q[0]!=this){l.hide().stop(true,true)}r.target=this;p.show(r);n=g.events.tooltip.split(/,\s*/);l.bind(n[0],function(){p.show(r)});if(n[1]){l.bind(n[1],function(){p.hide(r)})}});f.bind(n[1],function(q){p.hide(q)});if(!c.browser.msie&&!i&&!g.predelay){f.mousemove(function(){if(!p.isShown()){f.triggerHandler("mouseover")}})}if(g.opacity<1){l.css("opacity",g.opacity
 )}var m=0,j=f.attr("title");if(j&&g.cancelDefault){f.removeAttr("title");f.data("title",j)}c.extend(p,{show:function(r){if(r){f=c(r.target)}clearTimeout(l.data("timer"));if(l.is(":animated")||l.is(":visible")){return p}function q(){l.data("trigger",f);var t=o(r);if(g.tip&&j){l.html(f.data("title"))}r=r||c.Event();r.type="onBeforeShow";k.trigger(r,[t]);if(r.isDefaultPrevented()){return p}t=o(r);l.css({position:"absolute",top:t.top,left:t.left});var s=b[g.effect];if(!s){throw'Nonexistent effect "'+g.effect+'"'}s[0].call(p,function(){r.type="onShow";k.trigger(r)})}if(g.predelay){clearTimeout(m);m=setTimeout(q,g.predelay)}else{q()}return p},hide:function(r){clearTimeout(l.data("timer"));clearTimeout(m);if(!l.is(":visible")){return}function q(){r=r||c.Event();r.type="onBeforeHide";k.trigger(r);if(r.isDefaultPrevented()){return}b[g.effect][1].call(p,function(){r.type="onHide";k.trigger(r)})}if(g.delay&&r){l.data("timer",setTimeout(q,g.delay))}else{q()}return p},isShown:function(){return l
 .is(":visible, :animated")},getConf:function(){return g},getTip:function(){return l},getTrigger:function(){return f},bind:function(q,r){k.bind(q,r);return p},onHide:function(q){return this.bind("onHide",q)},onBeforeShow:function(q){return this.bind("onBeforeShow",q)},onShow:function(q){return this.bind("onShow",q)},onBeforeHide:function(q){return this.bind("onBeforeHide",q)},unbind:function(q){k.unbind(q);return p}});c.each(g,function(q,r){if(c.isFunction(r)){p.bind(q,r)}})}c.prototype.tooltip=function(e){var f=this.eq(typeof e=="number"?e:0).data("tooltip");if(f){return f}var g=c.extend(true,{},c.tools.tooltip.conf);if(c.isFunction(e)){e={onBeforeShow:e}}else{if(typeof e=="string"){e={tip:e}}}e=c.extend(true,g,e);if(typeof e.position=="string"){e.position=e.position.split(/,?\s/)}if(e.lazy!==false&&(e.lazy===true||this.length>20)){this.one("mouseover",function(h){f=new a(c(this),e);f.show(h);d.push(f)})}else{this.each(function(){f=new a(c(this),e);d.push(f)})}return e.api?f:this}})
 (jQuery);
-

http://git-wip-us.apache.org/repos/asf/allura/blob/0180e68a/Allura/allura/public/nf/js/allura-base.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/allura-base.js b/Allura/allura/public/nf/js/allura-base.js
index ec32bf6..b1c7c3d 100644
--- a/Allura/allura/public/nf/js/allura-base.js
+++ b/Allura/allura/public/nf/js/allura-base.js
@@ -18,12 +18,6 @@
 */
 
 (function($) {
-    // Setup label help text
-    $('label[title]').each(function(){
-        var $this = $(this);
-        $this.append('<a href="#" class="help_icon"><b data-icon="h" class="ico ico-help"></b></a>');
-        $this.tooltip({showURL: false});
-    });
     // Setup title-pane widgets
     $('.title-pane .title').click(function(e) {
         e.preventDefault();


[25/26] allura git commit: [#7830] ticket:733 Don't catch exception in merge task

Posted by je...@apache.org.
[#7830] ticket:733 Don't catch exception in merge task

So that merge task will get 'error' status and proper message will be displayed
to the user.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/4e289266
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/4e289266
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/4e289266

Branch: refs/heads/ib/7830
Commit: 4e2892660a201327788aa299de8c7409f8eda4b0
Parents: 035f4f5
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Feb 26 13:16:23 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Feb 26 13:16:23 2015 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/repo_tasks.py | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/4e289266/Allura/allura/tasks/repo_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/repo_tasks.py b/Allura/allura/tasks/repo_tasks.py
index e50f9d2..e873694 100644
--- a/Allura/allura/tasks/repo_tasks.py
+++ b/Allura/allura/tasks/repo_tasks.py
@@ -160,10 +160,6 @@ def merge(merge_request_id):
     from allura import model as M
     log = logging.getLogger(__name__)
     mr = M.MergeRequest.query.get(_id=merge_request_id)
-    try:
-        mr.app.repo.merge(mr)
-    except:
-        log.exception("Can't merge merge request %s", mr.url())
-        return
+    mr.app.repo.merge(mr)
     mr.status = 'merged'
     session(mr).flush(mr)


[12/26] allura git commit: [#7827] ticket:722 New jQuery & base plugins

Posted by je...@apache.org.
[#7827] ticket:722 New jQuery & base plugins


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/397652f4
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/397652f4
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/397652f4

Branch: refs/heads/ib/7830
Commit: 397652f447520ac9f01f22ca093c0dd8e4586fa7
Parents: 840e802
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Feb 9 14:53:26 2015 +0200
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:18 2015 +0000

----------------------------------------------------------------------
 Allura/allura/public/nf/js/jquery-base.js       | 477 ++++---------------
 .../allura/templates/jinja_master/master.html   |   1 +
 2 files changed, 101 insertions(+), 377 deletions(-)
----------------------------------------------------------------------



[26/26] allura git commit: [#7830] ticket:733 Temporary fix for the case when downstream repo has no new commits from upstream

Posted by je...@apache.org.
[#7830] ticket:733 Temporary fix for the case when downstream repo has no new commits from upstream

In the case of Mercurial, log raises Exception. It might happen after automerge
of merge request. Will be fixed more rigorously in [#7836].


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/7c2bef4e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/7c2bef4e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/7c2bef4e

Branch: refs/heads/ib/7830
Commit: 7c2bef4e5554179c74da830f97c2cb1ddc030ec7
Parents: 4e28926
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Feb 26 14:20:16 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Feb 26 14:20:16 2015 +0000

----------------------------------------------------------------------
 Allura/allura/model/repository.py | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/7c2bef4e/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index d866598..867a6d2 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -775,10 +775,16 @@ class MergeRequest(VersionedArtifact, ActivityObject):
                 commit = rev._id
             else:
                 commit = self.app.repo.head
-            return list(c.app.repo.log(
-                self.downstream.commit_id,
-                exclude=commit,
-                id_only=False))
+            try:
+                return list(c.app.repo.log(
+                    self.downstream.commit_id,
+                    exclude=commit,
+                    id_only=False))
+            except Exception:
+                log.exception(
+                    "Can't get commits for merge request",
+                    self.url())
+                return []
 
     @classmethod
     def upsert(cls, **kw):


[23/26] allura git commit: [#7830] ticket:729 One-click merge for git

Posted by je...@apache.org.
[#7830] ticket:729 One-click merge for git


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/ad310b87
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/ad310b87
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/ad310b87

Branch: refs/heads/ib/7830
Commit: ad310b87e53f8134e73912592579c741e9386328
Parents: e5e176d
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Feb 18 17:00:27 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Feb 26 09:56:36 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py         | 13 ++++++++
 Allura/allura/model/repository.py               | 24 +++++++++++++++
 Allura/allura/templates/repo/merge_request.html | 26 ++++++++++++++++
 ForgeGit/forgegit/model/git_repo.py             | 32 ++++++++++++++++++++
 4 files changed, 95 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/ad310b87/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 1e1e840..0869982 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -440,6 +440,19 @@ class MergeRequestController(object):
             self.req.status = status
         redirect('.')
 
+    @expose()
+    @require_post()
+    def merge(self):
+        require_access(c.app, 'write')
+        if self.req.status != 'open' or not self.req.can_merge():
+            raise exc.HTTPNotFound
+        ok = self.req.merge()
+        if ok:
+            flash('Merged successfully', 'ok')
+        else:
+            flash('Merge failed. Please, merge manually', 'error')
+        redirect(self.req.url())
+
 
 class RefsController(object):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/ad310b87/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index 0030aa5..5e4a171 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -805,6 +805,30 @@ class MergeRequest(VersionedArtifact, ActivityObject):
                 self.request_number, self.project.name, self.app.repo.name))
         return result
 
+    def can_merge(self):
+        if not self.app.forkable:
+            return False
+        try:
+            result = self.app.repo.can_merge(self)
+        except:
+            log.exception(
+                "Can't determine if merge request %s can be merged",
+                self.url())
+            return False
+        return result
+
+    def merge(self):
+        if not self.app.forkable:
+            return False
+        try:
+            self.app.repo.merge(self)
+        except:
+            log.exception("Can't merge merge request %s", self.url())
+            return False
+        self.status = 'merged'
+        session(self).flush(self)
+        return True
+
 
 # Basic commit information
 # One of these for each commit in the physical repo on disk. The _id is the

http://git-wip-us.apache.org/repos/asf/allura/blob/ad310b87/Allura/allura/templates/repo/merge_request.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/repo/merge_request.html b/Allura/allura/templates/repo/merge_request.html
index 3c79654..060b5b9 100644
--- a/Allura/allura/templates/repo/merge_request.html
+++ b/Allura/allura/templates/repo/merge_request.html
@@ -44,6 +44,25 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
 
     <div>{{g.markdown.convert(req.description)}}</div>
 
+    {% if req.status == 'open' and c.app.forkable and h.has_access(c.app, 'write')() %}
+      {% set can_merge = req.can_merge() %}
+      <div class="grid-19">
+        <form action="merge" method="POST">
+          {{ lib.csrf_token() }}
+          <input type="submit" value="Merge"{% if not can_merge %}disabled="disabled"{% endif %}>
+          {% if can_merge %}
+            <div class="merge-ok">
+              Merge request has no conflicts. You can merge automatically.
+            </div>
+          {% else %}
+            <div class="merge-conflicts">
+              Merge request has conflicts. Follow manual instructions below to merge.
+            </div>
+          {% endif %}
+        </form>
+      </div>
+    {% endif %}
+
     {{ c.log_widget.display(value=req.commits, app=downstream_app) }}
 
     <div class="grid-19"><a href="#discussion_holder">Discuss</a></div>
@@ -87,3 +106,10 @@ Merge Request #{{req.request_number}}: {{req.summary}} ({{req.status}})
         count=count)}}
   </div>
 {% endblock %}
+
+{% block extra_css %}
+<style type="text/css">
+  .merge-ok { color: green; }
+  .merge-conflicts { color: red; }
+</style>
+{% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/ad310b87/ForgeGit/forgegit/model/git_repo.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index 7fda67a..831da5b 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -19,6 +19,7 @@ import os
 import shutil
 import string
 import logging
+import tempfile
 from datetime import datetime
 
 import tg
@@ -95,6 +96,37 @@ class Repository(M.Repository):
             merge_request.downstream.commit_id,
         )
 
+    def can_merge(self, mr):
+        """
+        Given merge request `mr` determine if it can be merged w/o conflicts.
+        """
+        g = self._impl._git.git
+        # http://stackoverflow.com/a/6283843
+        # fetch source branch
+        g.fetch(mr.downstream_repo_url, mr.source_branch)
+        # find merge base
+        merge_base = g.merge_base(mr.downstream.commit_id, mr.target_branch)
+        # print out merge result, but don't actually touch anything
+        merge_tree = g.merge_tree(
+            merge_base, mr.target_branch, mr.downstream.commit_id)
+        return '+<<<<<<<' not in merge_tree
+
+    def merge(self, mr):
+        g = self._impl._git.git
+        # can't merge in bare repo, so need to clone
+        tmp_path = tempfile.mkdtemp()
+        tmp_repo = git.Repo.clone_from(
+            self.clone_url('rw'),
+            to_path=tmp_path,
+            bare=False)
+        tmp_repo = GitImplementation(Object(full_fs_path=tmp_path))._git
+        tmp_repo.git.fetch('origin', mr.target_branch)
+        tmp_repo.git.checkout(mr.target_branch)
+        tmp_repo.git.fetch(mr.downstream_repo_url, mr.source_branch)
+        tmp_repo.git.merge(mr.downstream.commit_id)
+        tmp_repo.git.push('origin', mr.target_branch)
+        shutil.rmtree(tmp_path, ignore_errors=True)
+
     def rev_to_commit_id(self, rev):
         return self._impl.rev_parse(rev).hexsha
 


[24/26] allura git commit: [#7830] ticket:729 Add tests

Posted by je...@apache.org.
[#7830] ticket:729 Add tests


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/035f4f54
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/035f4f54
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/035f4f54

Branch: refs/heads/ib/7830
Commit: 035f4f54314ba06f1a4f4dac536edc46877e6ef4
Parents: 52a40c6
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Feb 19 15:53:48 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Feb 26 09:56:37 2015 +0000

----------------------------------------------------------------------
 Allura/allura/tests/model/test_repo.py          | 38 ++++++++++++++++
 Allura/allura/tests/test_tasks.py               | 11 +++++
 .../forgegit/tests/model/test_repository.py     | 46 ++++++++++++++++++++
 3 files changed, 95 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/035f4f54/Allura/allura/tests/model/test_repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index 9e2af07..669f940 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -713,3 +713,41 @@ class TestModelCache(unittest.TestCase):
         session.assert_called_once_with(tree1)
         session.return_value.flush.assert_called_once_with(tree1)
         session.return_value.expunge.assert_called_once_with(tree1)
+
+
+class TestMergeRequest(object):
+
+    def setUp(self):
+        setup_basic_test()
+        setup_global_objects()
+        self.mr = M.MergeRequest(app_config=mock.Mock(_id=ObjectId()))
+        self.mr.app = mock.Mock(forkable=True)
+
+    def test_can_merge(self):
+        assert_equal(self.mr.can_merge(),
+                     self.mr.app.repo.can_merge.return_value)
+        self.mr.app.repo.can_merge.assert_called_once_with(self.mr)
+
+        self.mr.app.reset_mock()
+        self.mr.app.forkable = False
+        assert_equal(self.mr.can_merge(), False)
+        assert_equal(self.mr.app.repo.can_merge.called, False)
+
+    @mock.patch('allura.tasks.repo_tasks.merge', autospec=True)
+    def test_merge(self, merge_task):
+        self.mr.merge_task_status = lambda: None
+        self.mr.merge()
+        merge_task.post.assert_called_once_with(self.mr._id)
+
+        merge_task.reset_mock()
+        self.mr.merge_task_status = lambda: 'ready'
+        self.mr.merge()
+        assert_equal(merge_task.post.called, False)
+
+    def test_merge_task_status(self):
+        from allura.tasks import repo_tasks
+        assert_equal(self.mr.merge_task_status(), None)
+        repo_tasks.merge.post(self.mr._id)
+        assert_equal(self.mr.merge_task_status(), 'ready')
+        M.MonQTask.run_ready()
+        assert_equal(self.mr.merge_task_status(), 'complete')

http://git-wip-us.apache.org/repos/asf/allura/blob/035f4f54/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 13d5c17..d822229 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -64,6 +64,17 @@ class TestRepoTasks(unittest.TestCase):
         assert_equal(post_event.call_args[0][2], None)
         # ignore args[3] which is a traceback string
 
+    @mock.patch('allura.tasks.repo_tasks.session', autospec=True)
+    @mock.patch.object(M, 'MergeRequest', autospec=True)
+    def test_merge(self, MR, session):
+        mr = mock.Mock(_id='_id')
+        MR.query.get.return_value = mr
+        repo_tasks.merge(mr._id)
+        mr.app.repo.merge.assert_called_once_with(mr)
+        assert_equal(mr.status, 'merged')
+        session.assert_called_once_with(mr)
+        session.return_value.flush.assert_called_once_with(mr)
+
 
 class TestEventTasks(unittest.TestCase):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/035f4f54/ForgeGit/forgegit/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 231e479..d79fc7b 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -592,6 +592,52 @@ class TestGitRepo(unittest.TestCase, RepoImplTestBase):
         }
         assert_equals(payload, expected_payload)
 
+    def test_can_merge(self):
+        mr = mock.Mock(downstream_repo_url='downstream-url',
+                       source_branch='source-branch',
+                       target_branch='target-branch',
+                       downstream=mock.Mock(commit_id='cid'))
+        git = mock.Mock()
+        git.merge_tree.return_value = 'clean merge'
+        self.repo._impl._git.git = git
+        assert_equal(self.repo.can_merge(mr), True)
+        git.fetch.assert_called_once_with('downstream-url', 'source-branch')
+        git.merge_base.assert_called_once_with('cid', 'target-branch')
+        git.merge_tree.assert_called_once_with(
+            git.merge_base.return_value,
+            'target-branch',
+            'cid')
+        git.merge_tree.return_value = '+<<<<<<<'
+        assert_equal(self.repo.can_merge(mr), False)
+
+    @mock.patch('forgegit.model.git_repo.tempfile', autospec=True)
+    @mock.patch('forgegit.model.git_repo.git', autospec=True)
+    @mock.patch('forgegit.model.git_repo.GitImplementation', autospec=True)
+    @mock.patch('forgegit.model.git_repo.shutil', autospec=True)
+    def test_merge(self, shutil, GitImplementation, git, tempfile):
+        mr = mock.Mock(downstream_repo_url='downstream-url',
+                       source_branch='source-branch',
+                       target_branch='target-branch',
+                       downstream=mock.Mock(commit_id='cid'))
+        _git = mock.Mock()
+        self.repo._impl._git.git = _git
+        self.repo.merge(mr)
+        git.Repo.clone_from.assert_called_once_with(
+            self.repo.clone_url('rw'),
+            to_path=tempfile.mkdtemp.return_value,
+            bare=False)
+        tmp_repo = GitImplementation.return_value._git
+        assert_equal(
+            tmp_repo.git.fetch.call_args_list,
+            [mock.call('origin', 'target-branch'),
+             mock.call('downstream-url', 'source-branch')])
+        tmp_repo.git.checkout.assert_called_once_with('target-branch')
+        tmp_repo.git.merge.assert_called_once_with('cid')
+        tmp_repo.git.push.assert_called_once_with('origin', 'target-branch')
+        shutil.rmtree.assert_called_once_with(
+            tempfile.mkdtemp.return_value,
+            ignore_errors=True)
+
 
 class TestGitImplementation(unittest.TestCase):
 


[07/26] allura git commit: [#7829] ticket:732 Add webhooks to API docs

Posted by je...@apache.org.
[#7829] ticket:732 Add webhooks to API docs


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/784b8b42
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/784b8b42
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/784b8b42

Branch: refs/heads/ib/7830
Commit: 784b8b4208bf995ce4d0951b40e050161aeb6641
Parents: 746ee51
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Feb 23 17:47:46 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Feb 24 09:43:03 2015 -0500

----------------------------------------------------------------------
 Allura/allura/webhooks.py         |  2 +-
 Allura/docs/api/model/webhook.rst | 25 +++++++++++++++++++++++++
 Allura/docs/api/webhooks.rst      | 24 ++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/784b8b42/Allura/allura/webhooks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index fc21bf4..fb37820 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -286,7 +286,7 @@ class WebhookSender(object):
     def send(self, params_or_list):
         """Post a task that will send webhook payload
 
-        :param:`params_or_list` - dict with keyword parameters to be passed to
+        :param params_or_list: dict with keyword parameters to be passed to
         :meth:`get_payload` or a list of such dicts. If it's a list for each
         element appropriate payload will be submitted, but limit will be
         enforced only once for each webhook.

http://git-wip-us.apache.org/repos/asf/allura/blob/784b8b42/Allura/docs/api/model/webhook.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/model/webhook.rst b/Allura/docs/api/model/webhook.rst
new file mode 100644
index 0000000..b911b1a
--- /dev/null
+++ b/Allura/docs/api/model/webhook.rst
@@ -0,0 +1,25 @@
+..     Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+
+:mod:`allura.model.webhook`
+-------------------------------------
+
+.. automodule:: allura.model.webhook
+
+  .. autoclass:: Webhook
+      :members:
+      :special-members: __json__

http://git-wip-us.apache.org/repos/asf/allura/blob/784b8b42/Allura/docs/api/webhooks.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/webhooks.rst b/Allura/docs/api/webhooks.rst
new file mode 100644
index 0000000..d146ed6
--- /dev/null
+++ b/Allura/docs/api/webhooks.rst
@@ -0,0 +1,24 @@
+..     Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+
+.. _webhooks_module:
+
+:mod:`allura.webhooks`
+--------------------------------
+
+.. automodule:: allura.webhooks
+    :members:


[06/26] allura git commit: [#7829] add link from extending.rst to WebhookSender class

Posted by je...@apache.org.
[#7829] add link from extending.rst to WebhookSender class


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/840e802c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/840e802c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/840e802c

Branch: refs/heads/ib/7830
Commit: 840e802c3ebd093cc03ce42e65d53a9041a015dc
Parents: 784b8b4
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Feb 24 09:42:57 2015 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Feb 24 09:43:03 2015 -0500

----------------------------------------------------------------------
 Allura/docs/extending.rst | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/840e802c/Allura/docs/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/extending.rst b/Allura/docs/extending.rst
index 01218c3..825bcbd 100644
--- a/Allura/docs/extending.rst
+++ b/Allura/docs/extending.rst
@@ -40,6 +40,7 @@ The available extension points for Allura are:
 * ``[allura.middleware]`` classes, which are standard WSGI middleware.  They will receive the ``app`` instance and a ``config`` dict as constructor parameters.
   The middleware will be used for all requests.  By default the middleware wraps the base app directly and other middleware wrap around it.
   If your middleware needs to wrap around the other Allura middleware (except error handling), set ``when = 'outer'`` on your middleware.
+* :class:`allura.webhooks.WebhookSender`
 
 A listing of available 3rd-party extensions is at https://forge-allura.apache.org/p/allura/wiki/Extensions/
 


[04/26] allura git commit: [#5467] Made "Create ticket" visible to users without permission.

Posted by je...@apache.org.
[#5467] Made "Create ticket" visible to users without permission.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/fa4c23d3
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/fa4c23d3
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/fa4c23d3

Branch: refs/heads/ib/7830
Commit: fa4c23d3f1e0113b2b0537a8b842510ff69dc198
Parents: b9225b8
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Wed Feb 18 15:59:45 2015 -0500
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Thu Feb 19 23:29:53 2015 +0000

----------------------------------------------------------------------
 Allura/allura/app.py                                    |  3 ++-
 Allura/allura/nf/allura/css/site_style.css              | 11 ++++++++++-
 Allura/allura/templates/jinja_master/sidebar_menu.html  |  9 ++++++---
 ForgeTracker/forgetracker/tests/functional/test_root.py |  6 ++++--
 ForgeTracker/forgetracker/tracker_main.py               |  7 +++++++
 5 files changed, 29 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/fa4c23d3/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 5a6db3e..b9fd6b7 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -81,7 +81,7 @@ class SitemapEntry(object):
     """
 
     def __init__(self, label, url=None, children=None, className=None,
-                 ui_icon=None, small=None, tool_name=None, matching_urls=None):
+                 ui_icon=None, small=None, tool_name=None, matching_urls=None, extra_html_attrs=None):
         """Create a new SitemapEntry.
 
         """
@@ -95,6 +95,7 @@ class SitemapEntry(object):
         self.children = children or []
         self.tool_name = tool_name
         self.matching_urls = matching_urls or []
+        self.extra_html_attrs = extra_html_attrs or {}
 
     def __getitem__(self, x):
         """Automatically expand the list of sitemap child entries with the

http://git-wip-us.apache.org/repos/asf/allura/blob/fa4c23d3/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 9f8f1b3..01f6c8e 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -1952,7 +1952,16 @@ nav .ico {
 #sidebar li > a:last-child {
   border-bottom: none !important;
 }
-
+a.sidebar-disabled {
+    opacity: 0.4;
+}
+a.sidebar-disabled:focus:hover{
+        pointer-events: none;
+}
+a.sidebar-disabled:hover,
+a.sidebar-disabled:focus {
+    cursor: not-allowed;
+}
 .pad {
   margin: 14px 0 10px 0 !important;
   min-height: 600px;

http://git-wip-us.apache.org/repos/asf/allura/blob/fa4c23d3/Allura/allura/templates/jinja_master/sidebar_menu.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/sidebar_menu.html b/Allura/allura/templates/jinja_master/sidebar_menu.html
index 08beed2..b51a15b 100644
--- a/Allura/allura/templates/jinja_master/sidebar_menu.html
+++ b/Allura/allura/templates/jinja_master/sidebar_menu.html
@@ -23,9 +23,12 @@
       <ul class="sidebarmenu">
       {% do ul_active.append(True) %}
     {% endif %}
-    <li{% if request.path.find(s.url,-s.url.__len__()) != -1 %} class="active"{% endif %}>
-      <a href="{{s.url}}"{% if s.className %} class="{{s.className or ''}}"{% endif %}>{% if s.ui_icon %}<b data-icon="{{s.ui_icon.char}}" class="ico {{s.ui_icon.css}}"></b> {% endif %}<span{% if s.small != None %} class="has_small"{% endif %}>{{h.really_unicode(s.label)}}</span>{% if s.small != None %}<small>{{s.small}}</small>{% endif %}</a>
-    </li>
+  <li{% if request.path.find(s.url,-s.url.__len__()) != -1 %} class="active"{% endif %}>
+      <a href="{{ s.url }}" {{ s.extra_html_attrs|xmlattr }} {% if s.className %} class="{{ s.className or '' }}" {% endif %} >
+      {% if s.ui_icon %} <b data-icon="{{ s.ui_icon.char }}" class="ico {{ s.ui_icon.css }}"></b>{% endif %}
+      <span{% if s.small != None %} class="has_small"{% endif %}>{{ h.really_unicode(s.label) }}</span>
+      {% if s.small != None %}<small>{{ s.small }}</small>{% endif %} </a>
+  </li>
   {% else %}
     {% if ul_active[-1] %}
       </ul>

http://git-wip-us.apache.org/repos/asf/allura/blob/fa4c23d3/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 46cf8ce..b2c5c11 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -656,9 +656,11 @@ class TestFunctionalController(TrackerTestController):
         index_view = self.app.get('/bugs/')
         assert 'No open tickets found.' in index_view
         assert 'Create Ticket' in index_view
-        # No 'Create Ticket' button for user without 'create' perm
+
+        # Make sure the 'Create Ticket' button is disabled for user without 'create' perm
         r = self.app.get('/bugs/', extra_environ=dict(username='*anonymous'))
-        assert 'Create Ticket' not in r
+        create_button = r.html.find('a', attrs={'href': u'/p/test/bugs/new/'})
+        assert_equal(create_button['class'], 'sidebar-disabled')
 
     def test_render_markdown_syntax(self):
         r = self.app.get('/bugs/markdown_syntax')

http://git-wip-us.apache.org/repos/asf/allura/blob/fa4c23d3/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index a7c4e61..aedf6ff 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -304,6 +304,13 @@ class ForgeTrackerApp(Application):
         if has_access(self, 'create')():
             links.append(SitemapEntry('Create Ticket',
                                       self.config.url() + 'new/', ui_icon=g.icons['plus']))
+        else:
+            extra_attrs = {"title": "To create a new ticket, you must be authorized by the project admin."}
+            links.append(SitemapEntry('Create Ticket',
+                                      self.config.url() + 'new/',
+                                      extra_html_attrs=extra_attrs,
+                                      className='sidebar-disabled',
+                                      ui_icon=g.icons['plus']))
         if has_access(self, 'configure')():
             links.append(SitemapEntry('Edit Milestones', self.config.url()
                          + 'milestones', ui_icon=g.icons['table']))


[21/26] allura git commit: [#7834] Fixed issue that prevented markdown caching.

Posted by je...@apache.org.
[#7834] Fixed issue that prevented markdown caching.


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e5e176d4
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e5e176d4
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e5e176d4

Branch: refs/heads/ib/7830
Commit: e5e176d42699c9f07e263d2fd1e04f06c8e59239
Parents: 55cd10b
Author: Heith Seewald <hs...@slashdotmedia.com>
Authored: Wed Feb 25 15:15:15 2015 -0500
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Feb 26 08:16:48 2015 +0000

----------------------------------------------------------------------
 Allura/allura/model/types.py        | 1 +
 Allura/allura/tests/test_globals.py | 6 ++++++
 2 files changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e5e176d4/Allura/allura/model/types.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/types.py b/Allura/allura/model/types.py
index be4b48e..6a8ff71 100644
--- a/Allura/allura/model/types.py
+++ b/Allura/allura/model/types.py
@@ -27,6 +27,7 @@ class MarkdownCache(S.Object):
         super(MarkdownCache, self).__init__(
             fields=dict(
                 md5=S.String(),
+                fix7528=S.Bool,
                 html=S.String(),
                 render_time=S.Float()),
             **kw)

http://git-wip-us.apache.org/repos/asf/allura/blob/e5e176d4/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 53c8af1..6920f6d 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -728,6 +728,12 @@ class TestCachedMarkdown(unittest.TestCase):
         self.assertIsNone(self.post.text_cache.html)
         self.assertIsNone(self.post.text_cache.render_time)
 
+    @patch.dict('allura.lib.app_globals.config', {})
+    def test_all_expected_keys_exist_in_cache(self):
+        self.md.cached_convert(self.post, 'text')
+        required_keys = ['fix7528', 'html', 'md5', 'render_time']
+        keys = sorted(self.post.text_cache.keys())
+        self.assertEqual(required_keys, keys)
 
 
 class TestHandlePaging(unittest.TestCase):


[16/26] allura git commit: [#7827] ticket:722 Remove jquery-migrate

Posted by je...@apache.org.
[#7827] ticket:722 Remove jquery-migrate


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/82a802d2
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/82a802d2
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/82a802d2

Branch: refs/heads/ib/7830
Commit: 82a802d27c1c9aabc769e5e38cc316278d28fdf1
Parents: d1f5521
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Feb 10 09:55:32 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:20 2015 +0000

----------------------------------------------------------------------
 .../allura/public/nf/js/jquery-migrate-1.2.1.js | 521 -------------------
 .../allura/templates/jinja_master/master.html   |   1 -
 2 files changed, 522 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/82a802d2/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js b/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js
deleted file mode 100644
index 25b6c81..0000000
--- a/Allura/allura/public/nf/js/jquery-migrate-1.2.1.js
+++ /dev/null
@@ -1,521 +0,0 @@
-/*!
- * jQuery Migrate - v1.2.1 - 2013-05-08
- * https://github.com/jquery/jquery-migrate
- * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
- */
-(function( jQuery, window, undefined ) {
-// See http://bugs.jquery.com/ticket/13335
-// "use strict";
-
-
-var warnedAbout = {};
-
-// List of warnings already given; public read only
-jQuery.migrateWarnings = [];
-
-// Set to true to prevent console output; migrateWarnings still maintained
-// jQuery.migrateMute = false;
-
-// Show a message on the console so devs know we're active
-if ( !jQuery.migrateMute && window.console && window.console.log ) {
-	window.console.log("JQMIGRATE: Logging is active");
-}
-
-// Set to false to disable traces that appear with warnings
-if ( jQuery.migrateTrace === undefined ) {
-	jQuery.migrateTrace = true;
-}
-
-// Forget any warnings we've already given; public
-jQuery.migrateReset = function() {
-	warnedAbout = {};
-	jQuery.migrateWarnings.length = 0;
-};
-
-function migrateWarn( msg) {
-	var console = window.console;
-	if ( !warnedAbout[ msg ] ) {
-		warnedAbout[ msg ] = true;
-		jQuery.migrateWarnings.push( msg );
-		if ( console && console.warn && !jQuery.migrateMute ) {
-			console.warn( "JQMIGRATE: " + msg );
-			if ( jQuery.migrateTrace && console.trace ) {
-				console.trace();
-			}
-		}
-	}
-}
-
-function migrateWarnProp( obj, prop, value, msg ) {
-	if ( Object.defineProperty ) {
-		// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
-		// allow property to be overwritten in case some other plugin wants it
-		try {
-			Object.defineProperty( obj, prop, {
-				configurable: true,
-				enumerable: true,
-				get: function() {
-					migrateWarn( msg );
-					return value;
-				},
-				set: function( newValue ) {
-					migrateWarn( msg );
-					value = newValue;
-				}
-			});
-			return;
-		} catch( err ) {
-			// IE8 is a dope about Object.defineProperty, can't warn there
-		}
-	}
-
-	// Non-ES5 (or broken) browser; just set the property
-	jQuery._definePropertyBroken = true;
-	obj[ prop ] = value;
-}
-
-if ( document.compatMode === "BackCompat" ) {
-	// jQuery has never supported or tested Quirks Mode
-	migrateWarn( "jQuery is not compatible with Quirks Mode" );
-}
-
-
-var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
-	oldAttr = jQuery.attr,
-	valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
-		function() { return null; },
-	valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
-		function() { return undefined; },
-	rnoType = /^(?:input|button)$/i,
-	rnoAttrNodeType = /^[238]$/,
-	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
-	ruseDefault = /^(?:checked|selected)$/i;
-
-// jQuery.attrFn
-migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
-
-jQuery.attr = function( elem, name, value, pass ) {
-	var lowerName = name.toLowerCase(),
-		nType = elem && elem.nodeType;
-
-	if ( pass ) {
-		// Since pass is used internally, we only warn for new jQuery
-		// versions where there isn't a pass arg in the formal params
-		if ( oldAttr.length < 4 ) {
-			migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
-		}
-		if ( elem && !rnoAttrNodeType.test( nType ) &&
-			(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
-			return jQuery( elem )[ name ]( value );
-		}
-	}
-
-	// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
-	// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
-	if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
-		migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
-	}
-
-	// Restore boolHook for boolean property/attribute synchronization
-	if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
-		jQuery.attrHooks[ lowerName ] = {
-			get: function( elem, name ) {
-				// Align boolean attributes with corresponding properties
-				// Fall back to attribute presence where some booleans are not supported
-				var attrNode,
-					property = jQuery.prop( elem, name );
-				return property === true || typeof property !== "boolean" &&
-					( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
-
-					name.toLowerCase() :
-					undefined;
-			},
-			set: function( elem, value, name ) {
-				var propName;
-				if ( value === false ) {
-					// Remove boolean attributes when set to false
-					jQuery.removeAttr( elem, name );
-				} else {
-					// value is true since we know at this point it's type boolean and not false
-					// Set boolean attributes to the same name and set the DOM property
-					propName = jQuery.propFix[ name ] || name;
-					if ( propName in elem ) {
-						// Only set the IDL specifically if it already exists on the element
-						elem[ propName ] = true;
-					}
-
-					elem.setAttribute( name, name.toLowerCase() );
-				}
-				return name;
-			}
-		};
-
-		// Warn only for attributes that can remain distinct from their properties post-1.9
-		if ( ruseDefault.test( lowerName ) ) {
-			migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
-		}
-	}
-
-	return oldAttr.call( jQuery, elem, name, value );
-};
-
-// attrHooks: value
-jQuery.attrHooks.value = {
-	get: function( elem, name ) {
-		var nodeName = ( elem.nodeName || "" ).toLowerCase();
-		if ( nodeName === "button" ) {
-			return valueAttrGet.apply( this, arguments );
-		}
-		if ( nodeName !== "input" && nodeName !== "option" ) {
-			migrateWarn("jQuery.fn.attr('value') no longer gets properties");
-		}
-		return name in elem ?
-			elem.value :
-			null;
-	},
-	set: function( elem, value ) {
-		var nodeName = ( elem.nodeName || "" ).toLowerCase();
-		if ( nodeName === "button" ) {
-			return valueAttrSet.apply( this, arguments );
-		}
-		if ( nodeName !== "input" && nodeName !== "option" ) {
-			migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
-		}
-		// Does not return so that setAttribute is also used
-		elem.value = value;
-	}
-};
-
-
-var matched, browser,
-	oldInit = jQuery.fn.init,
-	oldParseJSON = jQuery.parseJSON,
-	// Note: XSS check is done below after string is trimmed
-	rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
-
-// $(html) "looks like html" rule change
-jQuery.fn.init = function( selector, context, rootjQuery ) {
-	var match;
-
-	if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
-			(match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
-		// This is an HTML string according to the "old" rules; is it still?
-		if ( selector.charAt( 0 ) !== "<" ) {
-			migrateWarn("$(html) HTML strings must start with '<' character");
-		}
-		if ( match[ 3 ] ) {
-			migrateWarn("$(html) HTML text after last tag is ignored");
-		}
-		// Consistently reject any HTML-like string starting with a hash (#9521)
-		// Note that this may break jQuery 1.6.x code that otherwise would work.
-		if ( match[ 0 ].charAt( 0 ) === "#" ) {
-			migrateWarn("HTML string cannot start with a '#' character");
-			jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
-		}
-		// Now process using loose rules; let pre-1.8 play too
-		if ( context && context.context ) {
-			// jQuery object as context; parseHTML expects a DOM object
-			context = context.context;
-		}
-		if ( jQuery.parseHTML ) {
-			return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ),
-					context, rootjQuery );
-		}
-	}
-	return oldInit.apply( this, arguments );
-};
-jQuery.fn.init.prototype = jQuery.fn;
-
-// Let $.parseJSON(falsy_value) return null
-jQuery.parseJSON = function( json ) {
-	if ( !json && json !== null ) {
-		migrateWarn("jQuery.parseJSON requires a valid JSON string");
-		return null;
-	}
-	return oldParseJSON.apply( this, arguments );
-};
-
-jQuery.uaMatch = function( ua ) {
-	ua = ua.toLowerCase();
-
-	var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
-		/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
-		/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
-		/(msie) ([\w.]+)/.exec( ua ) ||
-		ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
-		[];
-
-	return {
-		browser: match[ 1 ] || "",
-		version: match[ 2 ] || "0"
-	};
-};
-
-// Don't clobber any existing jQuery.browser in case it's different
-if ( !jQuery.browser ) {
-	matched = jQuery.uaMatch( navigator.userAgent );
-	browser = {};
-
-	if ( matched.browser ) {
-		browser[ matched.browser ] = true;
-		browser.version = matched.version;
-	}
-
-	// Chrome is Webkit, but Webkit is also Safari.
-	if ( browser.chrome ) {
-		browser.webkit = true;
-	} else if ( browser.webkit ) {
-		browser.safari = true;
-	}
-
-	jQuery.browser = browser;
-}
-
-// Warn if the code tries to get jQuery.browser
-migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
-
-jQuery.sub = function() {
-	function jQuerySub( selector, context ) {
-		return new jQuerySub.fn.init( selector, context );
-	}
-	jQuery.extend( true, jQuerySub, this );
-	jQuerySub.superclass = this;
-	jQuerySub.fn = jQuerySub.prototype = this();
-	jQuerySub.fn.constructor = jQuerySub;
-	jQuerySub.sub = this.sub;
-	jQuerySub.fn.init = function init( selector, context ) {
-		if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
-			context = jQuerySub( context );
-		}
-
-		return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
-	};
-	jQuerySub.fn.init.prototype = jQuerySub.fn;
-	var rootjQuerySub = jQuerySub(document);
-	migrateWarn( "jQuery.sub() is deprecated" );
-	return jQuerySub;
-};
-
-
-// Ensure that $.ajax gets the new parseJSON defined in core.js
-jQuery.ajaxSetup({
-	converters: {
-		"text json": jQuery.parseJSON
-	}
-});
-
-
-var oldFnData = jQuery.fn.data;
-
-jQuery.fn.data = function( name ) {
-	var ret, evt,
-		elem = this[0];
-
-	// Handles 1.7 which has this behavior and 1.8 which doesn't
-	if ( elem && name === "events" && arguments.length === 1 ) {
-		ret = jQuery.data( elem, name );
-		evt = jQuery._data( elem, name );
-		if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
-			migrateWarn("Use of jQuery.fn.data('events') is deprecated");
-			return evt;
-		}
-	}
-	return oldFnData.apply( this, arguments );
-};
-
-
-var rscriptType = /\/(java|ecma)script/i,
-	oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
-
-jQuery.fn.andSelf = function() {
-	migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
-	return oldSelf.apply( this, arguments );
-};
-
-// Since jQuery.clean is used internally on older versions, we only shim if it's missing
-if ( !jQuery.clean ) {
-	jQuery.clean = function( elems, context, fragment, scripts ) {
-		// Set context per 1.8 logic
-		context = context || document;
-		context = !context.nodeType && context[0] || context;
-		context = context.ownerDocument || context;
-
-		migrateWarn("jQuery.clean() is deprecated");
-
-		var i, elem, handleScript, jsTags,
-			ret = [];
-
-		jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
-
-		// Complex logic lifted directly from jQuery 1.8
-		if ( fragment ) {
-			// Special handling of each script element
-			handleScript = function( elem ) {
-				// Check if we consider it executable
-				if ( !elem.type || rscriptType.test( elem.type ) ) {
-					// Detach the script and store it in the scripts array (if provided) or the fragment
-					// Return truthy to indicate that it has been handled
-					return scripts ?
-						scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
-						fragment.appendChild( elem );
-				}
-			};
-
-			for ( i = 0; (elem = ret[i]) != null; i++ ) {
-				// Check if we're done after handling an executable script
-				if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
-					// Append to fragment and handle embedded scripts
-					fragment.appendChild( elem );
-					if ( typeof elem.getElementsByTagName !== "undefined" ) {
-						// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
-						jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
-
-						// Splice the scripts into ret after their former ancestor and advance our index beyond them
-						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
-						i += jsTags.length;
-					}
-				}
-			}
-		}
-
-		return ret;
-	};
-}
-
-var eventAdd = jQuery.event.add,
-	eventRemove = jQuery.event.remove,
-	eventTrigger = jQuery.event.trigger,
-	oldToggle = jQuery.fn.toggle,
-	oldLive = jQuery.fn.live,
-	oldDie = jQuery.fn.die,
-	ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
-	rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
-	rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
-	hoverHack = function( events ) {
-		if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
-			return events;
-		}
-		if ( rhoverHack.test( events ) ) {
-			migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
-		}
-		return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
-	};
-
-// Event props removed in 1.9, put them back if needed; no practical way to warn them
-if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
-	jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
-}
-
-// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
-if ( jQuery.event.dispatch ) {
-	migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
-}
-
-// Support for 'hover' pseudo-event and ajax event warnings
-jQuery.event.add = function( elem, types, handler, data, selector ){
-	if ( elem !== document && rajaxEvent.test( types ) ) {
-		migrateWarn( "AJAX events should be attached to document: " + types );
-	}
-	eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
-};
-jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
-	eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
-};
-
-jQuery.fn.error = function() {
-	var args = Array.prototype.slice.call( arguments, 0);
-	migrateWarn("jQuery.fn.error() is deprecated");
-	args.splice( 0, 0, "error" );
-	if ( arguments.length ) {
-		return this.bind.apply( this, args );
-	}
-	// error event should not bubble to window, although it does pre-1.7
-	this.triggerHandler.apply( this, args );
-	return this;
-};
-
-jQuery.fn.toggle = function( fn, fn2 ) {
-
-	// Don't mess with animation or css toggles
-	if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
-		return oldToggle.apply( this, arguments );
-	}
-	migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
-
-	// Save reference to arguments for access in closure
-	var args = arguments,
-		guid = fn.guid || jQuery.guid++,
-		i = 0,
-		toggler = function( event ) {
-			// Figure out which function to execute
-			var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
-			jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
-			// Make sure that clicks stop
-			event.preventDefault();
-
-			// and execute the function
-			return args[ lastToggle ].apply( this, arguments ) || false;
-		};
-
-	// link all the functions, so any of them can unbind this click handler
-	toggler.guid = guid;
-	while ( i < args.length ) {
-		args[ i++ ].guid = guid;
-	}
-
-	return this.click( toggler );
-};
-
-jQuery.fn.live = function( types, data, fn ) {
-	migrateWarn("jQuery.fn.live() is deprecated");
-	if ( oldLive ) {
-		return oldLive.apply( this, arguments );
-	}
-	jQuery( this.context ).on( types, this.selector, data, fn );
-	return this;
-};
-
-jQuery.fn.die = function( types, fn ) {
-	migrateWarn("jQuery.fn.die() is deprecated");
-	if ( oldDie ) {
-		return oldDie.apply( this, arguments );
-	}
-	jQuery( this.context ).off( types, this.selector || "**", fn );
-	return this;
-};
-
-// Turn global events into document-triggered events
-jQuery.event.trigger = function( event, data, elem, onlyHandlers  ){
-	if ( !elem && !rajaxEvent.test( event ) ) {
-		migrateWarn( "Global events are undocumented and deprecated" );
-	}
-	return eventTrigger.call( this,  event, data, elem || document, onlyHandlers  );
-};
-jQuery.each( ajaxEvents.split("|"),
-	function( _, name ) {
-		jQuery.event.special[ name ] = {
-			setup: function() {
-				var elem = this;
-
-				// The document needs no shimming; must be !== for oldIE
-				if ( elem !== document ) {
-					jQuery.event.add( document, name + "." + jQuery.guid, function() {
-						jQuery.event.trigger( name, null, elem, true );
-					});
-					jQuery._data( this, name, jQuery.guid++ );
-				}
-				return false;
-			},
-			teardown: function() {
-				if ( this !== document ) {
-					jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
-				}
-				return false;
-			}
-		};
-	}
-);
-
-
-})( jQuery, window );

http://git-wip-us.apache.org/repos/asf/allura/blob/82a802d2/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index 0dd1e92..af56986 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -23,7 +23,6 @@
   {% import g.theme.jinja_macros as theme_macros with context %}
 {% endif %}
 {% do g.register_forge_js('js/jquery-base.js', location='head_js') %}
-{% do g.register_forge_js('js/jquery-migrate-1.2.1.js') %}
 {% do g.register_forge_js('js/jquery.notify.js') %}
 {% do g.register_forge_js('js/modernizr.js') %}
 {% do g.register_forge_js('js/sylvester.js') %}


[15/26] allura git commit: [#7827] ticket:722 Upgrade autosize plugin

Posted by je...@apache.org.
[#7827] ticket:722 Upgrade autosize plugin


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8e4af913
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8e4af913
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8e4af913

Branch: refs/heads/ib/7830
Commit: 8e4af913e3322199ea14e3457d3f58965583047e
Parents: 82a802d
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Feb 10 10:03:42 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:20 2015 +0000

----------------------------------------------------------------------
 .../lib/widgets/resources/js/jquery.autosize-min.js       | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8e4af913/Allura/allura/lib/widgets/resources/js/jquery.autosize-min.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/jquery.autosize-min.js b/Allura/allura/lib/widgets/resources/js/jquery.autosize-min.js
index 278da76..5c764dc 100644
--- a/Allura/allura/lib/widgets/resources/js/jquery.autosize-min.js
+++ b/Allura/allura/lib/widgets/resources/js/jquery.autosize-min.js
@@ -1,4 +1,6 @@
-// Autosize 1.11 - jQuery plugin for textareas
-// (c) 2012 Jack Moore - jacklmoore.com
-// license: www.opensource.org/licenses/mit-license.php
-(function(e){var t="hidden",n="border-box",r="lineHeight",i='<textarea tabindex="-1" style="position:absolute; top:-9999px; left:-9999px; right:auto; bottom:auto; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden;">',s=["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent"],o="oninput",u="onpropertychange",a=e(i)[0];a.setAttribute(o,"return"),e.isFunction(a[o])||u in a?(e(a).css(r,"99px"),e(a).css(r)==="99px"&&s.push(r),e.fn.autosize=function(r){return this.each(function(){function g(){var e,n;p||(p=!0,l.value=a.value,l.style.overflowY=a.style.overflowY,l.style.width=f.css("width"),l.scrollTop=0,l.scrollTop=9e4,e=l.scrollTop,n=t,e>h?(e=h,n="scroll"):e<c&&(e=c),a.style.overflowY=n,a.style.height=e+m+"px",setTimeout(function(){p=!1},1))}var a=this,f=e(a),l,c=f.height(),h=parseInt(f.css("maxHeight"),10),p,d=s.length
 ,v,m=0;if(f.css("box-sizing")===n||f.css("-moz-box-sizing")===n||f.css("-webkit-box-sizing")===n)m=f.outerHeight()-f.height();if(f.data("mirror")||f.data("ismirror"))return;l=e(i).data("ismirror",!0).addClass(r||"autosizejs")[0],v=f.css("resize")==="none"?"none":"horizontal",f.data("mirror",e(l)).css({overflow:t,overflowY:t,wordWrap:"break-word",resize:v}),h=h&&h>0?h:9e4;while(d--)l.style[s[d]]=f.css(s[d]);e("body").append(l),u in a?o in a?a[o]=a.onkeyup=g:a[u]=g:a[o]=g,e(window).resize(g),f.bind("autosize",g),f.text(f.text()),g()})}):e.fn.autosize=function(){return this}})(jQuery);
\ No newline at end of file
+/*!
+	Autosize 1.18.17
+	license: MIT
+	http://www.jacklmoore.com/autosize
+*/
+!function(e){var t,o={className:"autosizejs",id:"autosizejs",append:"\n",callback:!1,resizeDelay:10,placeholder:!0},i='<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"/>',a=["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent","whiteSpace"],n=e(i).data("autosize",!0)[0];n.style.lineHeight="99px","99px"===e(n).css("lineHeight")&&a.push("lineHeight"),n.style.lineHeight="",e.fn.autosize=function(i){return this.length?(i=e.extend({},o,i||{}),n.parentNode!==document.body&&e(document.body).append(n),this.each(function(){function o(){var t,o=window.getComputedStyle?window.getComputedStyle(u,null):null;o?(t=parseFloat(o.width),("border-box
 "===o.boxSizing||"border-box"===o.webkitBoxSizing||"border-box"===o.mozBoxSizing)&&e.each(["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"],function(e,i){t-=parseFloat(o[i])})):t=p.width(),n.style.width=Math.max(t,0)+"px"}function s(){var s={};if(t=u,n.className=i.className,n.id=i.id,d=parseFloat(p.css("maxHeight")),e.each(a,function(e,t){s[t]=p.css(t)}),e(n).css(s).attr("wrap",p.attr("wrap")),o(),window.chrome){var r=u.style.width;u.style.width="0px";{u.offsetWidth}u.style.width=r}}function r(){var e,a;t!==u?s():o(),n.value=!u.value&&i.placeholder?p.attr("placeholder")||"":u.value,n.value+=i.append||"",n.style.overflowY=u.style.overflowY,a=parseFloat(u.style.height)||0,n.scrollTop=0,n.scrollTop=9e4,e=n.scrollTop,d&&e>d?(u.style.overflowY="scroll",e=d):(u.style.overflowY="hidden",c>e&&(e=c)),e+=z,Math.abs(a-e)>.01&&(u.style.height=e+"px",n.className=n.className,w&&i.callback.call(u,u),p.trigger("autosize.resized"))}function l(){clearTimeout(h),h=setTimeout(function
 (){var e=p.width();e!==b&&(b=e,r())},parseInt(i.resizeDelay,10))}var d,c,h,u=this,p=e(u),z=0,w=e.isFunction(i.callback),f={height:u.style.height,overflow:u.style.overflow,overflowY:u.style.overflowY,wordWrap:u.style.wordWrap,resize:u.style.resize},b=p.width(),g=p.css("resize");p.data("autosize")||(p.data("autosize",!0),("border-box"===p.css("box-sizing")||"border-box"===p.css("-moz-box-sizing")||"border-box"===p.css("-webkit-box-sizing"))&&(z=p.outerHeight()-p.height()),c=Math.max(parseFloat(p.css("minHeight"))-z||0,p.height()),p.css({overflow:"hidden",overflowY:"hidden",wordWrap:"break-word"}),"vertical"===g?p.css("resize","none"):"both"===g&&p.css("resize","horizontal"),"onpropertychange"in u?"oninput"in u?p.on("input.autosize keyup.autosize",r):p.on("propertychange.autosize",function(){"value"===event.propertyName&&r()}):p.on("input.autosize",r),i.resizeDelay!==!1&&e(window).on("resize.autosize",l),p.on("autosize.resize",r),p.on("autosize.resizeIncludeStyle",function(){t=null,r()
 }),p.on("autosize.destroy",function(){t=null,clearTimeout(h),e(window).off("resize",l),p.off("autosize").off(".autosize").css(f).removeData("autosize")}),r())})):this}}(jQuery||$);
\ No newline at end of file


[02/26] allura git commit: Improve spam config example

Posted by je...@apache.org.
Improve spam config example


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/2d9bcf0e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/2d9bcf0e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/2d9bcf0e

Branch: refs/heads/ib/7830
Commit: 2d9bcf0ea4e08aef502166246a5a485afd5ed4f8
Parents: aa14b0d
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Feb 19 15:54:35 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Feb 19 15:54:49 2015 +0000

----------------------------------------------------------------------
 Allura/development.ini | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2d9bcf0e/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 993c4a5..c581808 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -37,10 +37,6 @@ debug = true
 smtp_server = localhost
 smtp_port = 8826
 
-# Spam filtering service: mollom or akismet
-;spam.method = akismet
-;spam.key =
-
 error_email_from = paste@localhost
 ; Used to uniquify references to static resources, can be a timestamp or any unique value
 ; This should be updated each time you deploy (or make significant changes, like new tools, new css)
@@ -141,6 +137,14 @@ user_prefs_storage.ldap.fields.display_name = cn
 # Limit the number of emails a user can claim.
 user_prefs.maximum_claimed_emails = 20
 
+; Spam filtering service: mollom or akismet
+;spam.method = akismet
+; for akismet:
+;spam.key =
+; for mollom:
+;spam.public_key =
+;spam.private_key =
+
 # webhook.timeout = 30  # seconds, default = 30
 
 # List of pauses between retries, if hook fails (in seconds)


[17/26] allura git commit: [#7827] ticket:734 Emit head js always or some page will not get jquery

Posted by je...@apache.org.
[#7827] ticket:734 Emit head js always or some page will not get jquery


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/0660ec43
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/0660ec43
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/0660ec43

Branch: refs/heads/ib/7830
Commit: 0660ec43396760649e930b44eb858715916c4697
Parents: 8e4af91
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Feb 24 10:09:18 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Feb 24 18:50:21 2015 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/master.html | 2 --
 1 file changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0660ec43/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index af56986..cc6b548 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -49,11 +49,9 @@
     {% for blob in g.resource_manager.emit('head_css') %}
       {{ blob }}
     {% endfor %}
-    {% if c.project %}
     {% for blob in g.resource_manager.emit('head_js') %}
       {{ blob }}
     {% endfor %}
-    {% endif %}
 
     {% if c.project and c.project.neighborhood.css %}
       <style type="text/css">