python-dogpile.core-0.4.1/0000755000175000017500000000000012076552100014357 5ustar chuckchuckpython-dogpile.core-0.4.1/LICENSE0000644000175000017500000000265012076551651015401 0ustar chuckchuckCopyright (c) 2011-2013 Mike Bayer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author or contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. python-dogpile.core-0.4.1/README.rst0000644000175000017500000000437112076551651016065 0ustar chuckchuckdogpile.core ============ A "dogpile" lock, one which allows a single thread to generate an expensive resource while other threads use the "old" value, until the "new" value is ready. Dogpile is basically the locking code extracted from the Beaker package, for simple and generic usage. Usage ----- A simple example:: from dogpile.core import Dogpile # store a reference to a "resource", some # object that is expensive to create. the_resource = [None] def some_creation_function(): # create the resource here the_resource[0] = create_some_resource() def use_the_resource(): # some function that uses # the resource. Won't reach # here until some_creation_function() # has completed at least once. the_resource[0].do_something() # create Dogpile with 3600 second # expiry time dogpile = Dogpile(3600) with dogpile.acquire(some_creation_function): use_the_resource() Above, ``some_creation_function()`` will be called when ``Dogpile.acquire()`` is first called. The remainder of the ``with`` block then proceeds. Concurrent threads which call ``Dogpile.acquire()`` during this initial period will be blocked until ``some_creation_function()`` completes. Once the creation function has completed successfully the first time, new calls to ``Dogpile.acquire()`` will call ``some_creation_function()`` each time the "expiretime" has been reached, allowing only a single thread to call the function. Concurrent threads which call ``Dogpile.acquire()`` during this period will fall through, and not be blocked. It is expected that the "stale" version of the resource remain available at this time while the new one is generated. dogpile.core is at the core of the `dogpile.cache `_ package which provides for a basic cache API and sample backends based on the dogpile concept. Development Status ------------------- dogpile.core has been in use in a small number of production environments for a period of months, and as of 0.3.2 has entered beta status. No issues have been reported yet with its core synchronization model, and overall the project hasn't seen many changes. Most development continues within dogpile.cache. python-dogpile.core-0.4.1/setup.py0000644000175000017500000000217312076551651016106 0ustar chuckchuckimport os import sys import re from setuptools import setup, find_packages v = open(os.path.join(os.path.dirname(__file__), 'dogpile', 'core', '__init__.py')) VERSION = re.compile(r".*__version__ = '(.*?)'", re.S).match(v.read()).group(1) v.close() readme = os.path.join(os.path.dirname(__file__), 'README.rst') setup(name='dogpile.core', version=VERSION, description="A 'dogpile' lock, typically used as a component of a larger caching solution", long_description=open(readme).read(), classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', 'Programming Language :: Python :: 3', ], keywords='caching', author='Mike Bayer', author_email='mike_mp@zzzcomputing.com', url='http://bitbucket.org/zzzeek/dogpile.core', license='BSD', packages=find_packages('.', exclude=['ez_setup', 'tests*']), namespace_packages=['dogpile'], zip_safe=False, install_requires=[], test_suite='nose.collector', tests_require=['nose'], ) python-dogpile.core-0.4.1/PKG-INFO0000644000175000017500000000646112076552100015463 0ustar chuckchuckMetadata-Version: 1.0 Name: dogpile.core Version: 0.4.1 Summary: A 'dogpile' lock, typically used as a component of a larger caching solution Home-page: http://bitbucket.org/zzzeek/dogpile.core Author: Mike Bayer Author-email: mike_mp@zzzcomputing.com License: BSD Description: dogpile.core ============ A "dogpile" lock, one which allows a single thread to generate an expensive resource while other threads use the "old" value, until the "new" value is ready. Dogpile is basically the locking code extracted from the Beaker package, for simple and generic usage. Usage ----- A simple example:: from dogpile.core import Dogpile # store a reference to a "resource", some # object that is expensive to create. the_resource = [None] def some_creation_function(): # create the resource here the_resource[0] = create_some_resource() def use_the_resource(): # some function that uses # the resource. Won't reach # here until some_creation_function() # has completed at least once. the_resource[0].do_something() # create Dogpile with 3600 second # expiry time dogpile = Dogpile(3600) with dogpile.acquire(some_creation_function): use_the_resource() Above, ``some_creation_function()`` will be called when ``Dogpile.acquire()`` is first called. The remainder of the ``with`` block then proceeds. Concurrent threads which call ``Dogpile.acquire()`` during this initial period will be blocked until ``some_creation_function()`` completes. Once the creation function has completed successfully the first time, new calls to ``Dogpile.acquire()`` will call ``some_creation_function()`` each time the "expiretime" has been reached, allowing only a single thread to call the function. Concurrent threads which call ``Dogpile.acquire()`` during this period will fall through, and not be blocked. It is expected that the "stale" version of the resource remain available at this time while the new one is generated. dogpile.core is at the core of the `dogpile.cache `_ package which provides for a basic cache API and sample backends based on the dogpile concept. Development Status ------------------- dogpile.core has been in use in a small number of production environments for a period of months, and as of 0.3.2 has entered beta status. No issues have been reported yet with its core synchronization model, and overall the project hasn't seen many changes. Most development continues within dogpile.cache. Keywords: caching Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 python-dogpile.core-0.4.1/docs/0000755000175000017500000000000012076552100015307 5ustar chuckchuckpython-dogpile.core-0.4.1/docs/api.html0000644000175000017500000005210512076551752016765 0ustar chuckchuck API — dogpile.core 0.4.1 documentation

API

Dogpile

class dogpile.core.Lock(mutex, creator, value_and_created_fn, expiretime, async_creator=None)

Dogpile lock class.

Provides an interface around an arbitrary mutex that allows one thread/process to be elected as the creator of a new value, while other threads/processes continue to return the previous version of that value.

New in version 0.4.0: The Lock class was added as a single-use object representing the dogpile API without dependence on any shared state between multiple instances.

Parameters:
  • mutex – A mutex object that provides acquire() and release() methods.
  • creator – Callable which returns a tuple of the form (new_value, creation_time). “new_value” should be a newly generated value representing completed state. “creation_time” should be a floating point time value which is relative to Python’s time.time() call, representing the time at which the value was created. This time value should be associated with the created value.
  • value_and_created_fn – Callable which returns a tuple of the form (existing_value, creation_time). This basically should return what the last local call to the creator() callable has returned, i.e. the value and the creation time, which would be assumed here to be from a cache. If the value is not available, the NeedRegenerationException exception should be thrown.
  • expiretime – Expiration time in seconds. Set to None for never expires. This timestamp is compared to the creation_time result and time.time() to determine if the value returned by value_and_created_fn is “expired”.
  • async_creator

    A callable. If specified, this callable will be passed the mutex as an argument and is responsible for releasing the mutex after it finishes some asynchronous value creation. The intent is for this to be used to defer invocation of the creator callable until some later time.

    New in version 0.4.1: added the async_creator argument.

class dogpile.core.NeedRegenerationException

An exception that when raised in the ‘with’ block, forces the ‘has_value’ flag to False and incurs a regeneration of the value.

Utilities

class dogpile.core.ReadWriteMutex

A mutex which allows multiple readers, single writer.

ReadWriteMutex uses a Python threading.Condition to provide this functionality across threads within a process.

The Beaker package also contained a file-lock based version of this concept, so that readers/writers could be synchronized across processes with a common filesystem. A future Dogpile release may include this additional class at some point.

acquire_read_lock(wait=True)

Acquire the ‘read’ lock.

acquire_write_lock(wait=True)

Acquire the ‘write’ lock.

release_read_lock()

Release the ‘read’ lock.

release_write_lock()

Release the ‘write’ lock.

class dogpile.core.NameRegistry(creator)

Generates and return an object, keeping it as a singleton for a certain identifier for as long as its strongly referenced.

e.g.:

class MyFoo(object):
    "some important object."
    def __init__(self, identifier):
        self.identifier = identifier

registry = NameRegistry(MyFoo)

# thread 1:
my_foo = registry.get("foo1")

# thread 2
my_foo = registry.get("foo1")

Above, my_foo in both thread #1 and #2 will be the same object. The constructor for MyFoo will be called once, passing the identifier foo1 as the argument.

When thread 1 and thread 2 both complete or otherwise delete references to my_foo, the object is removed from the NameRegistry as a result of Python garbage collection.

Parameters:creator – A function that will create a new value, given the identifier passed to the NameRegistry.get() method.
get(identifier, *args, **kw)

Get and possibly create the value.

Parameters:
  • identifier – Hash key for the value. If the creation function is called, this identifier will also be passed to the creation function.
  • **kw (*args,) – Additional arguments which will also be passed to the creation function if it is called.

Legacy API

class dogpile.core.Dogpile(expiretime, init=False, lock=None)

Dogpile lock class.

Deprecated since version 0.4.0: The Lock object specifies the full API of the Dogpile object in a single way, rather than providing multiple modes of usage which don’t necessarily work in the majority of cases. Dogpile is now a wrapper around the Lock object which provides dogpile.core’s original usage pattern. This usage pattern began as something simple, but was not of general use in real-world caching environments without several extra complicating factors; the Lock object presents the “real-world” API more succinctly, and also fixes a cross-process concurrency issue.

Parameters:
  • expiretime – Expiration time in seconds. Set to None for never expires.
  • init – if True, set the ‘createdtime’ to the current time.
  • lock – a mutex object that provides acquire() and release() methods.
acquire(creator, value_fn=None, value_and_created_fn=None)

Acquire the lock, returning a context manager.

Parameters:
  • creator – Creation function, used if this thread is chosen to create a new value.
  • value_fn – Optional function that returns the value from some datasource. Will be returned if regeneration is not needed.
  • value_and_created_fn – Like value_fn, but returns a tuple of (value, createdtime). The returned createdtime will replace the “createdtime” value on this dogpile lock. This option removes the need for the dogpile lock itself to remain persistent across usages; another dogpile can come along later and pick up where the previous one left off.
createdtime = -1

The last known ‘creation time’ of the value, stored as an epoch (i.e. from time.time()).

If the value here is -1, it is assumed the value should recreate immediately.

has_value

Return true if the creation function has proceeded at least once.

is_expired

Return true if the expiration time is reached, or no value is available.

class dogpile.core.SyncReaderDogpile(*args, **kw)

Provide a read-write lock function on top of the Dogpile class.

Deprecated since version 0.4.0: The ReadWriteMutex object can be used directly.

acquire_write_lock(*args, **kwds)

Return the “write” lock context manager.

This will provide a section that is mutexed against all readers/writers for the dogpile-maintained value.

Table Of Contents

Previous topic

Usage Guide

Next topic

Changelog

This Page

python-dogpile.core-0.4.1/docs/search.html0000644000175000017500000000606712076551753017470 0ustar chuckchuck Search — dogpile.core 0.4.1 documentation

Search

Please activate JavaScript to enable the search functionality.

From here you can search these documents. Enter your search words into the box below and click "search". Note that the search function will automatically search for all of the words. Pages containing fewer words won't appear in the result list.

python-dogpile.core-0.4.1/docs/genindex.html0000644000175000017500000001533112076551753020016 0ustar chuckchuck Index — dogpile.core 0.4.1 documentation python-dogpile.core-0.4.1/docs/_sources/0000755000175000017500000000000012076552100017131 5ustar chuckchuckpython-dogpile.core-0.4.1/docs/_sources/index.txt0000644000175000017500000000132312076551651021012 0ustar chuckchuck======================================== Welcome to dogpile.core's documentation! ======================================== `dogpile.core `_ provides the *dogpile* lock, one which allows a single thread or process to generate an expensive resource while other threads/processes use the "old" value, until the "new" value is ready. dogpile.core is at the core of the `dogpile.cache `_ package which provides for a basic cache API and sample backends based on the dogpile concept. .. toctree:: :maxdepth: 2 front usage api changelog Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` python-dogpile.core-0.4.1/docs/_sources/usage.txt0000644000175000017500000002463412076551651021021 0ustar chuckchuck=========== Usage Guide =========== dogpile.core provides a locking interface around a "value creation" and "value retrieval" pair of functions. The primary interface is the :class:`.Lock` object, which provides for the invocation of the creation function by only one thread and/or process at a time, deferring all other threads/processes to the "value retrieval" function until the single creation thread is completed. Do I Need to Learn the dogpile.core API Directly? ================================================= It's anticipated that most users of dogpile.core will be using it indirectly via the `dogpile.cache `_ caching front-end. If you fall into this category, then the short answer is no. dogpile.core provides core internals to the `dogpile.cache `_ package, which provides a simple-to-use caching API, rudimental backends for Memcached and others, and easy hooks to add new backends. Users of dogpile.cache don't need to know or access dogpile.core's APIs directly, though a rough understanding the general idea is always helpful. Using the core dogpile.core APIs described here directly implies you're building your own resource-usage system outside, or in addition to, the one `dogpile.cache `_ provides. Rudimentary Usage ================== The primary API dogpile provides is the :class:`.Lock` object. This object allows for functions that provide mutexing, value creation, as well as value retrieval. .. versionchanged:: 0.4.0 The :class:`.Dogpile` class is no longer the primary API of dogpile, replaced by the more straightforward :class:`.Lock` object. An example usage is as follows:: from dogpile.core import Lock, NeedRegenerationException import threading import time # store a reference to a "resource", some # object that is expensive to create. the_resource = [None] def some_creation_function(): # call a value creation function value = create_some_resource() # get creationtime using time.time() creationtime = time.time() # keep track of the value and creation time in the "cache" the_resource[0] = tup = (value, creationtime) # return the tuple of (value, creationtime) return tup def retrieve_resource(): # function that retrieves the resource and # creation time. # if no resource, then raise NeedRegenerationException if the_resource[0] is None: raise NeedRegenerationException() # else return the tuple of (value, creationtime) return the_resource[0] # a mutex, which needs here to be shared across all invocations # of this particular creation function mutex = threading.Lock() with Lock(mutex, some_creation_function, retrieve_resource, 3600) as value: # some function that uses # the resource. Won't reach # here until some_creation_function() # has completed at least once. value.do_something() Above, ``some_creation_function()`` will be called when :class:`.Lock` is first invoked as a context manager. The value returned by this function is then passed into the ``with`` block, where it can be used by application code. Concurrent threads which call :class:`.Lock` during this initial period will be blocked until ``some_creation_function()`` completes. Once the creation function has completed successfully the first time, new calls to :class:`.Lock` will call ``retrieve_resource()`` in order to get the current cached value as well as its creation time; if the creation time is older than the current time minus an expiration time of 3600, then ``some_creation_function()`` will be called again, but only by one thread/process, using the given mutex object as a source of synchronization. Concurrent threads/processes which call :class:`.Lock` during this period will fall through, and not be blocked; instead, the "stale" value just returned by ``retrieve_resource()`` will continue to be returned until the creation function has finished. The :class:`.Lock` API is designed to work with simple cache backends like Memcached. It addresses such issues as: * Values can disappear from the cache at any time, before our expiration time is reached. The :class:`.NeedRegenerationException` class is used to alert the :class:`.Lock` object that a value needs regeneration ahead of the usual expiration time. * There's no function in a Memcached-like system to "check" for a key without actually retrieving it. The usage of the ``retrieve_resource()`` function allows that we check for an existing key and also return the existing value, if any, at the same time, without the need for two separate round trips. * The "creation" function used by :class:`.Lock` is expected to store the newly created value in the cache, as well as to return it. This is also more efficient than using two separate round trips to separately store, and re-retrieve, the object. .. _caching_decorator: Using dogpile.core for Caching =============================== dogpile.core is part of an effort to "break up" the Beaker package into smaller, simpler components (which also work better). Here, we illustrate how to approximate Beaker's "cache decoration" function, to decorate any function and store the value in Memcached. We create a Python decorator function called ``cached()`` which will provide caching for the output of a single function. It's given the "key" which we'd like to use in Memcached, and internally it makes usage of :class:`.Lock`, along with a thread based mutex (we'll see a distributed mutex in the next section):: import pylibmc import threading import time from dogpile.core import Lock, NeedRegenerationException mc_pool = pylibmc.ThreadMappedPool(pylibmc.Client("localhost")) def cached(key, expiration_time): """A decorator that will cache the return value of a function in memcached given a key.""" mutex = threading.Lock() def get_value(): with mc_pool.reserve() as mc: value_plus_time = mc.get(key) if value_plus_time is None: raise NeedRegenerationException() # return a tuple (value, createdtime) return value_plus_time def decorate(fn): def gen_cached(): value = fn() with mc_pool.reserve() as mc: # create a tuple (value, createdtime) value_plus_time = (value, time.time()) mc.put(key, value_plus_time) return value_plus_time def invoke(): with Lock(mutex, gen_cached, get_value, expiration_time) as value: return value return invoke return decorate Using the above, we can decorate any function as:: @cached("some key", 3600) def generate_my_expensive_value(): return slow_database.lookup("stuff") The :class:`.Lock` object will ensure that only one thread at a time performs ``slow_database.lookup()``, and only every 3600 seconds, unless Memcached has removed the value, in which case it will be called again as needed. In particular, dogpile.core's system allows us to call the memcached get() function at most once per access, instead of Beaker's system which calls it twice, and doesn't make us call get() when we just created the value. For the mutex object, we keep a ``threading.Lock`` object that's local to the decorated function, rather than using a global lock. This localizes the in-process locking to be local to this one decorated function. In the next section, we'll see the usage of a cross-process lock that accomplishes this differently. Using a File or Distributed Lock with Dogpile ============================================== The examples thus far use a ``threading.Lock()`` object for synchronization. If our application uses multiple processes, we will want to coordinate creation operations not just on threads, but on some mutex that other processes can access. In this example we'll use a file-based lock as provided by the `lockfile `_ package, which uses a unix-symlink concept to provide a filesystem-level lock (which also has been made threadsafe). Another strategy may base itself directly off the Unix ``os.flock()`` call, or use an NFS-safe file lock like `flufl.lock `_, and still another approach is to lock against a cache server, using a recipe such as that described at `Using Memcached as a Distributed Locking Service `_. What all of these locking schemes have in common is that unlike the Python ``threading.Lock`` object, they all need access to an actual key which acts as the symbol that all processes will coordinate upon. So here, we will also need to create the "mutex" which we pass to :class:`.Lock` using the ``key`` argument:: import lockfile import os from hashlib import sha1 # ... other imports and setup from the previous example def cached(key, expiration_time): """A decorator that will cache the return value of a function in memcached given a key.""" lock_path = os.path.join("/tmp", "%s.lock" % sha1(key).hexdigest()) # ... get_value() from the previous example goes here def decorate(fn): # ... gen_cached() from the previous example goes here def invoke(): # create an ad-hoc FileLock mutex = lockfile.FileLock(lock_path) with Lock(mutex, gen_cached, get_value, expiration_time) as value: return value return invoke return decorate For a given key "some_key", we generate a hex digest of the key, then use ``lockfile.FileLock()`` to create a lock against the file ``/tmp/53def077a4264bd3183d4eb21b1f56f883e1b572.lock``. Any number of :class:`.Lock` objects in various processes will now coordinate with each other, using this common filename as the "baton" against which creation of a new value proceeds. Unlike when we used ``threading.Lock``, the file lock is ultimately locking on a file, so multiple instances of ``FileLock()`` will all coordinate on that same file - it's often the case that file locks that rely upon ``flock()`` require non-threaded usage, so a unique filesystem lock per thread is often a good idea in any case. python-dogpile.core-0.4.1/docs/_sources/changelog.txt0000644000175000017500000000656412076551716021650 0ustar chuckchuck========== Changelog ========== .. changelog:: :version: 0.4.1 :released: Sat Jan 19 2013 .. change:: :pullreq: 2 An "async creator" function can be specified to :class:`.Lock` which allows the "creation" function to be called asynchronously or be subsituted for another asynchronous creation scheme. Courtesy Ralph Bean. .. changelog:: :version: 0.4.0 :released: Tue Oct 30 2012 .. change:: reworked Dogpile's API into a new object called Lock. Lock presents just one set of arguments for locking within one constructor call, and provides the "comprehensive" caching pattern that is what's desired in the vast majority of cases. The Dogpile class is now legacy, and builds its various usage patterns on top of Lock. .. change:: :tags: :tickets: 1 Fixed the dependency on storing "creationtime" locally in memory; this caused dogpile pileups for a missing cache value when used in multiple-process environments. The new Lock object now checks the value_and_created_fn() an extra time within the "lock acquired" phase so that multiple writers who entered the block don't rely upon a memory-only version of creation time. .. changelog:: :version: 0.3.3 :released: Tue Sep 25 2012 .. change:: :tags: :tickets: repair setup.py so that tests don't install, courtesy Ben Hayden. .. changelog:: :version: 0.3.2 :released: Wed Jun 13 2012 .. change:: :tags: :tickets: upgrade to beta. .. changelog:: :version: 0.3.1 :released: Sun Apr 15 2012 .. change:: :tags: :tickets: py3k compatibility is in-place now, no 2to3 needed. .. changelog:: :version: 0.3.0 :released: Sat Apr 14 2012 .. change:: :tags: :tickets: Renamed the project again - to dogpile.core. Package has been reorganized so that "dogpile" is a pure namespace package. The base dogpile features are now in "dogpile.core". .. changelog:: :version: 0.2.2 :released: Fri Mar 30 2012 .. change:: :tags: :tickets: expire time of None means "never expire". .. changelog:: :version: 0.2.1 :released: Fri Dec 23 2011 .. change:: :tags: :tickets: Add new "nameregistry" helper. Another fixture derived from Beaker, this allows the ad-hoc creation of a new Dogpile lock based on a name, where all other threads calling that name at the same time will get the same Dogpile lock. Allows any number of logical "dogpile" actions to carry on concurrently without any memory taken up outside of those operations. .. change:: :tags: :tickets: To support the use case supported by nameregistry, added value_and_created_fn to dogpile.acquire(). The idea is that the value_and_created_fn can return (value, createdtime), so that the creation time of the value can come from the cache, thus eliminating the need for the dogpile lock to hang around persistently. .. changelog:: :version: 0.2.0 :released: Sun Oct 23 2011 .. change:: :tags: :tickets: change name to lowercase "dogpile". .. changelog:: :version: 0.1.0 .. change:: initial revision. python-dogpile.core-0.4.1/docs/_sources/front.txt0000644000175000017500000000354412076551651021042 0ustar chuckchuck============ Front Matter ============ Information about the dogpile.core project. Project Homepage ================ dogpile.core is hosted on `Bitbucket `_ - the lead project page is at https://bitbucket.org/zzzeek/dogpile.core. Source code is tracked here using `Mercurial `_. Releases and project status are available on Pypi at http://pypi.python.org/pypi/dogpile.core. The most recent published version of this documentation should be at http://dogpilecore.readthedocs.org. Installation ============ Install released versions of dogpile.core from the Python package index with `pip `_ or a similar tool:: pip install dogpile.core Installation via source distribution is via the ``setup.py`` script:: python setup.py install Community ========= dogpile.core is developed by `Mike Bayer `_, and is loosely associated with the `Pylons Project `_. As usage of dogpile.core and dogpile.cache increases, it is anticipated that the Pylons mailing list and IRC channel will become the primary channels for support. Bugs ==== Bugs and feature enhancements to dogpile.core should be reported on the `Bitbucket issue tracker `_. If you're not sure that a particular issue is specific to either dogpile.cache or dogpile.core, posting to the `dogpile.cache issue tracker `_ is likely the better place to post first, but it's not critical either way. * `dogpile.cache issue tracker `_ (post here if unsure) * `dogpile.core issue tracker `_ python-dogpile.core-0.4.1/docs/_sources/api.txt0000644000175000017500000000056112076551651020457 0ustar chuckchuck=== API === .. currentmodule:: dogpile.core Dogpile ======= .. autoclass:: Lock :members: .. autoclass:: NeedRegenerationException :members: Utilities ========== .. autoclass:: ReadWriteMutex :members: .. autoclass:: NameRegistry :members: Legacy API =========== .. autoclass:: Dogpile :members: .. autoclass:: SyncReaderDogpile :members: python-dogpile.core-0.4.1/docs/searchindex.js0000644000175000017500000001527412076551753020170 0ustar chuckchuckSearch.setIndex({objects:{"dogpile.core.NameRegistry":{get:[2,2,1,""]},"dogpile.core.Dogpile":{createdtime:[2,1,1,""],acquire:[2,2,1,""],is_expired:[2,1,1,""],has_value:[2,1,1,""]},"dogpile.core.ReadWriteMutex":{acquire_write_lock:[2,2,1,""],release_write_lock:[2,2,1,""],acquire_read_lock:[2,2,1,""],release_read_lock:[2,2,1,""]},"dogpile.core":{NeedRegenerationException:[2,0,1,""],Lock:[2,0,1,""],SyncReaderDogpile:[2,0,1,""],ReadWriteMutex:[2,0,1,""],NameRegistry:[2,0,1,""],Dogpile:[2,0,1,""]},"dogpile.core.SyncReaderDogpile":{acquire_write_lock:[2,2,1,""]}},terms:{all:[4,2,3],concept:[4,1,2],illustr:4,global:4,code:[0,4],follow:4,generate_my_expensive_valu:4,depend:[2,3],init:2,those:3,value_and_created_fn:[2,3],sourc:[0,4],everi:4,straightforward:4,fals:2,baton:4,util:[1,2],fall:4,join:4,vast:3,recip:4,syncreaderdogpil:2,level:4,complic:2,list:0,previou:[4,2],readthedoc:0,round:4,impli:4,smaller:4,lock_path:4,second:[4,2],design:4,pass:[4,2],compat:3,index:[0,1],what:[4,2,3],compar:2,sun:3,section:[4,2],"while":[1,2],current:[4,2],delet:2,version:[0,2,3],"new":[4,1,2,3],method:2,elimin:3,full:2,hash:2,deriv:3,gener:[4,1,2],never:[2,3],here:[0,4,2],mc_pool:4,address:4,path:4,along:[4,2],do_someth:4,valu:[4,1,2,3],wait:2,search:1,ahead:4,memcach:4,subsitut:3,pick:2,action:3,chang:3,via:[0,4],elect:2,extra:[2,3],apr:3,modul:1,put:4,unix:4,api:[4,1,2,3],instal:[0,1,3],from:[0,4,2,3],proceed:2,would:2,memori:3,upgrad:3,next:4,call:[4,2,3],taken:3,until:[4,1,2],more:[4,2],desir:3,enhanc:0,flag:2,particular:[0,4],known:2,dogpilecor:0,effort:4,cach:[0,1,2,3,4],origin:2,none:[4,2,3],retriev:4,describ:4,setup:[0,4,3],work:[4,2],uniqu:4,remain:2,can:[4,2,3],learn:[4,1],rework:3,dec:3,def:[4,2],defer:[4,2],process:[4,1,2,3],lock:[4,1,2,3],share:[4,2],indic:1,critic:0,want:4,async_cr:2,alwai:4,multipl:[4,2,3],hoc:[4,3],rather:[4,2],anoth:[4,2,3],readwritemutex:2,write:2,how:4,"__init__":2,pure:3,answer:4,instead:4,simpl:[4,2],regener:[4,2],mar:3,resourc:[4,1],referenc:2,after:2,decor:4,befor:4,mai:[4,2],end:4,associ:[0,2],"short":4,condit:2,zzzeek:0,issu:[0,4,2],inform:0,maintain:2,environ:[2,3],allow:[4,1,2,3],enter:3,callabl:2,order:4,nameregistri:[2,3],help:4,anticip:[0,4],singleton:2,increas:0,through:4,lockfil:4,still:4,foo1:2,digest:4,paramet:2,get_valu:4,chosen:2,fix:[2,3],better:[0,4],persist:[2,3],comprehens:3,mail:0,creationtim:[4,3],non:4,good:4,"return":[4,2,3],thei:4,python:[0,4,2],timestamp:2,safe:4,initi:[4,3],"break":4,front:[0,1,4],now:[4,2,3],name:3,changelog:[1,3],separ:4,mode:2,each:4,mean:3,replac:[4,2],continu:[4,2],expect:4,our:4,flock:4,accomplish:4,goe:4,newli:[4,2],publish:0,categori:4,hayden:3,rel:2,reader:2,upon:[4,3],differ:4,base:[4,1,2,3],bayer:0,releas:[0,2,3],org:0,thrown:2,thread:[4,1,2,3],could:2,synchron:[4,2],create_some_resourc:4,keep:[4,2],place:[0,3],outsid:[4,3],first:[0,4],oper:[4,3],major:[2,3],directli:[4,1,2],carri:3,onc:[4,2],number:[4,3],hook:4,unlik:4,set:[2,3],least:[4,2],miss:3,primari:[0,4],given:[4,2],script:0,top:[2,3],sep:3,system:4,wrapper:2,mercuri:0,necessarili:2,scheme:[4,3],store:[4,2,3],includ:2,slow_databas:4,option:2,namespac:3,tool:0,specifi:[2,3],part:4,incur:2,than:[4,2],succinctli:2,hashlib:4,ben:3,provid:[4,1,2,3],remov:[4,2],project:[0,1,3],matter:[0,1],stale:4,creation_tim:2,respons:2,argument:[4,2,3],packag:[0,1,2,3,4],expir:[4,2,3],have:4,tabl:1,need:[4,1,2,3],minu:4,sat:3,caus:3,date:3,recreat:2,self:2,also:[4,2],client:4,build:[4,3],which:[4,1,2,3],singl:[4,1,2],courtesi:3,sure:0,unless:4,distribut:[0,1,4],though:4,track:[0,4],who:3,reach:[4,2],most:[0,4],beta:3,acquire_write_lock:2,phase:3,homepag:[0,1],"class":[4,2,3],renam:3,later:2,request:3,determin:2,left:2,concurr:[4,2,3],createdtim:[4,2,3],rough:4,access:4,onli:[4,3],acquir:[2,3],writer:[2,3],should:[0,2],jan:3,factor:2,local:[4,2,3],oct:3,variou:[4,3],get:[4,2,3],value_plus_tim:4,pypi:0,bean:3,report:0,requir:4,same:[4,2,3],flufl:4,twice:4,stuff:4,common:[4,2],contain:2,where:[4,2,3],legaci:[1,2,3],creator:[2,3],see:4,result:2,arg:2,reserv:4,statu:0,pattern:[2,3],someth:2,threadmappedpool:4,ralph:3,state:2,won:4,mutex:[4,2],between:2,"import":[4,2],irc:0,approach:4,across:[4,2],kei:[4,2],tup:4,lowercas:3,come:[2,3],tue:3,addit:[4,2],both:2,last:2,release_read_lock:2,retrieve_resourc:4,against:[4,2],constructor:[2,3],instanc:[4,2],context:[4,2],logic:3,some_kei:4,expiration_tim:4,dogpil:[0,1,2,3,4],kwd:2,point:2,within:[2,3],period:4,guid:[4,1],assum:2,backend:[4,1],sever:2,ultim:4,becom:0,fri:3,been:[4,3],compon:4,basic:[1,2],immedi:2,strategi:4,mike:0,existing_valu:2,ani:[4,2,3],coordin:4,understand:4,present:[2,3],"case":[4,2,3],servic:4,invok:4,abov:[4,2],invoc:[4,2],fixtur:3,loos:0,pylon:0,helper:3,readi:1,itself:[4,2],revis:3,myfoo:2,disappear:4,"53def077a4264bd3183d4eb21b1f56f883e1b572":4,develop:0,welcom:1,perform:4,make:4,cross:[4,2],hexdigest:4,check:[4,3],proce:4,epoch:2,document:[0,1],complet:[4,2],finish:[4,2],http:0,py3k:3,hang:3,alert:4,rais:[4,2],user:4,recent:0,sha1:4,off:[4,2],older:4,thu:[4,3],well:4,without:[4,2,3],exampl:4,expens:[4,1],thi:[0,4,2,3],filesystem:[4,2],usual:4,identifi:2,just:[4,3],when:[4,2,3],easi:4,wed:3,except:2,add:[4,3],els:4,approxim:4,real:2,applic:4,around:[4,2,3],read:2,has_valu:2,know:4,acquire_read_lock:2,datasourc:2,world:2,needregenerationexcept:[4,2],like:[0,4,2],specif:0,arbitrari:2,threadsaf:4,server:4,collect:2,either:0,async:3,page:[0,1],old:1,often:4,creation:[4,2,3],some:[4,2],value_fn:2,sampl:1,successfulli:4,tmp:4,lead:0,channel:0,per:4,unsur:0,tracker:0,pylibmc:4,expiretim:2,localhost:4,refer:[4,2],core:[0,1,2,3,4],object:[4,2,3],garbag:2,usag:[0,1,2,3,4],symlink:4,filelock:4,host:0,output:4,post:0,some_creation_funct:4,simpler:4,beaker:[4,2,3],about:0,actual:4,is_expir:2,commun:[0,1],manag:[4,2],act:4,block:[4,2,3],repair:3,own:4,effici:4,rudiment:4,"float":2,two:4,pair:4,ensur:4,gen_cach:4,your:4,wai:[0,2],support:[0,3],the_resourc:4,"long":2,avail:[0,2],reli:[4,3],interfac:[4,2],my_foo:2,rudimentari:[4,1],"function":[4,2,3],reorgan:3,form:2,forc:2,tupl:[4,2],jun:3,idea:[4,3],link:3,don:[4,2,3],"true":2,bug:[0,1],pull:3,made:4,release_write_lock:2,possibl:2,intern:4,asynchron:[2,3],otherwis:2,similar:0,featur:[0,3],creat:[4,2],certain:2,dure:4,filenam:4,doesn:4,repres:2,strongli:2,exist:4,file:[4,1,2],pip:0,pileup:3,trip:4,again:[4,3],hex:4,"2to3":3,new_valu:2,other:[4,1,2,3],lookup:4,futur:2,test:3,you:[0,4],registri:2,symbol:4,intent:2,began:2,bitbucket:0,longer:4,indirectli:4,time:[4,2,3],far:4},objtypes:{"0":"py:class","1":"py:attribute","2":"py:method"},titles:["Front Matter","Welcome to dogpile.core’s documentation!","API","Changelog","Usage Guide"],objnames:{"0":["py","class","Python class"],"1":["py","attribute","Python attribute"],"2":["py","method","Python method"]},filenames:["front","index","api","changelog","usage"]})python-dogpile.core-0.4.1/docs/index.html0000644000175000017500000001664412076551752017333 0ustar chuckchuck Welcome to dogpile.core’s documentation! — dogpile.core 0.4.1 documentation

Welcome to dogpile.core’s documentation!

dogpile.core provides the dogpile lock, one which allows a single thread or process to generate an expensive resource while other threads/processes use the “old” value, until the “new” value is ready.

dogpile.core is at the core of the dogpile.cache package which provides for a basic cache API and sample backends based on the dogpile concept.

Indices and tables

Table Of Contents

Next topic

Front Matter

This Page

python-dogpile.core-0.4.1/docs/changelog.html0000644000175000017500000002614612076551752020151 0ustar chuckchuck Changelog — dogpile.core 0.4.1 documentation

Changelog

0.4.1

Released: Sat Jan 19 2013
  • An “async creator” function can be specified to Lock which allows the “creation” function to be called asynchronously or be subsituted for another asynchronous creation scheme. Courtesy Ralph Bean.(link)

    pull request 2

0.4.0

Released: Tue Oct 30 2012
  • reworked Dogpile’s API into a new object called Lock. Lock presents just one set of arguments for locking within one constructor call, and provides the “comprehensive” caching pattern that is what’s desired in the vast majority of cases. The Dogpile class is now legacy, and builds its various usage patterns on top of Lock.(link)

  • Fixed the dependency on storing “creationtime” locally in memory; this caused dogpile pileups for a missing cache value when used in multiple-process environments. The new Lock object now checks the value_and_created_fn() an extra time within the “lock acquired” phase so that multiple writers who entered the block don’t rely upon a memory-only version of creation time.(link)

    #1

0.3.3

Released: Tue Sep 25 2012
  • repair setup.py so that tests don’t install, courtesy Ben Hayden.(link)

0.3.2

Released: Wed Jun 13 2012

0.3.1

Released: Sun Apr 15 2012
  • py3k compatibility is in-place now, no 2to3 needed.(link)

0.3.0

Released: Sat Apr 14 2012
  • Renamed the project again - to dogpile.core. Package has been reorganized so that “dogpile” is a pure namespace package. The base dogpile features are now in “dogpile.core”.(link)

0.2.2

Released: Fri Mar 30 2012
  • expire time of None means “never expire”.(link)

0.2.1

Released: Fri Dec 23 2011
  • Add new “nameregistry” helper. Another fixture derived from Beaker, this allows the ad-hoc creation of a new Dogpile lock based on a name, where all other threads calling that name at the same time will get the same Dogpile lock. Allows any number of logical “dogpile” actions to carry on concurrently without any memory taken up outside of those operations.(link)

  • To support the use case supported by nameregistry, added value_and_created_fn to dogpile.acquire(). The idea is that the value_and_created_fn can return (value, createdtime), so that the creation time of the value can come from the cache, thus eliminating the need for the dogpile lock to hang around persistently.(link)

0.2.0

Released: Sun Oct 23 2011
  • change name to lowercase “dogpile”.(link)

0.1.0

no release date

Table Of Contents

Previous topic

API

This Page

python-dogpile.core-0.4.1/docs/build/0000755000175000017500000000000012076552100016406 5ustar chuckchuckpython-dogpile.core-0.4.1/docs/build/conf.py0000644000175000017500000001563212076551651017726 0ustar chuckchuck# -*- coding: utf-8 -*- # # Dogpile documentation build configuration file, created by # sphinx-quickstart on Sat May 1 12:47:55 2010. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) # If your extensions are in another directory, add it here. If the directory # is relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. sys.path.insert(0, os.path.abspath('../../')) import dogpile.core # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'changelog'] changelog_sections = ["feature", "bug"] changelog_render_ticket = "https://bitbucket.org/zzzeek/dogpile.core/issue/%s" changelog_render_pullreq = "https://bitbucket.org/zzzeek/dogpile.core/pull-request/%s" changelog_render_changeset = "https://bitbucket.org/zzzeek/dogpile.core/changeset/%s" # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'dogpile.core' copyright = u'2011-2013 Mike Bayer' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = dogpile.core.__version__ # The full version, including alpha/beta/rc tags. release = dogpile.core.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. 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 # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'nature' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'dogpile.coredoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'dogpile.core.tex', u'dogpile.core Documentation', u'Mike Bayer', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True #{'python': ('http://docs.python.org/3.2', None)} intersphinx_mapping = {'sqla':('http://www.sqlalchemy.org/docs/', None)} python-dogpile.core-0.4.1/docs/build/requirements.txt0000644000175000017500000000001112076551651021674 0ustar chuckchuckchangelogpython-dogpile.core-0.4.1/docs/build/usage.rst0000644000175000017500000002463412076551651020267 0ustar chuckchuck=========== Usage Guide =========== dogpile.core provides a locking interface around a "value creation" and "value retrieval" pair of functions. The primary interface is the :class:`.Lock` object, which provides for the invocation of the creation function by only one thread and/or process at a time, deferring all other threads/processes to the "value retrieval" function until the single creation thread is completed. Do I Need to Learn the dogpile.core API Directly? ================================================= It's anticipated that most users of dogpile.core will be using it indirectly via the `dogpile.cache `_ caching front-end. If you fall into this category, then the short answer is no. dogpile.core provides core internals to the `dogpile.cache `_ package, which provides a simple-to-use caching API, rudimental backends for Memcached and others, and easy hooks to add new backends. Users of dogpile.cache don't need to know or access dogpile.core's APIs directly, though a rough understanding the general idea is always helpful. Using the core dogpile.core APIs described here directly implies you're building your own resource-usage system outside, or in addition to, the one `dogpile.cache `_ provides. Rudimentary Usage ================== The primary API dogpile provides is the :class:`.Lock` object. This object allows for functions that provide mutexing, value creation, as well as value retrieval. .. versionchanged:: 0.4.0 The :class:`.Dogpile` class is no longer the primary API of dogpile, replaced by the more straightforward :class:`.Lock` object. An example usage is as follows:: from dogpile.core import Lock, NeedRegenerationException import threading import time # store a reference to a "resource", some # object that is expensive to create. the_resource = [None] def some_creation_function(): # call a value creation function value = create_some_resource() # get creationtime using time.time() creationtime = time.time() # keep track of the value and creation time in the "cache" the_resource[0] = tup = (value, creationtime) # return the tuple of (value, creationtime) return tup def retrieve_resource(): # function that retrieves the resource and # creation time. # if no resource, then raise NeedRegenerationException if the_resource[0] is None: raise NeedRegenerationException() # else return the tuple of (value, creationtime) return the_resource[0] # a mutex, which needs here to be shared across all invocations # of this particular creation function mutex = threading.Lock() with Lock(mutex, some_creation_function, retrieve_resource, 3600) as value: # some function that uses # the resource. Won't reach # here until some_creation_function() # has completed at least once. value.do_something() Above, ``some_creation_function()`` will be called when :class:`.Lock` is first invoked as a context manager. The value returned by this function is then passed into the ``with`` block, where it can be used by application code. Concurrent threads which call :class:`.Lock` during this initial period will be blocked until ``some_creation_function()`` completes. Once the creation function has completed successfully the first time, new calls to :class:`.Lock` will call ``retrieve_resource()`` in order to get the current cached value as well as its creation time; if the creation time is older than the current time minus an expiration time of 3600, then ``some_creation_function()`` will be called again, but only by one thread/process, using the given mutex object as a source of synchronization. Concurrent threads/processes which call :class:`.Lock` during this period will fall through, and not be blocked; instead, the "stale" value just returned by ``retrieve_resource()`` will continue to be returned until the creation function has finished. The :class:`.Lock` API is designed to work with simple cache backends like Memcached. It addresses such issues as: * Values can disappear from the cache at any time, before our expiration time is reached. The :class:`.NeedRegenerationException` class is used to alert the :class:`.Lock` object that a value needs regeneration ahead of the usual expiration time. * There's no function in a Memcached-like system to "check" for a key without actually retrieving it. The usage of the ``retrieve_resource()`` function allows that we check for an existing key and also return the existing value, if any, at the same time, without the need for two separate round trips. * The "creation" function used by :class:`.Lock` is expected to store the newly created value in the cache, as well as to return it. This is also more efficient than using two separate round trips to separately store, and re-retrieve, the object. .. _caching_decorator: Using dogpile.core for Caching =============================== dogpile.core is part of an effort to "break up" the Beaker package into smaller, simpler components (which also work better). Here, we illustrate how to approximate Beaker's "cache decoration" function, to decorate any function and store the value in Memcached. We create a Python decorator function called ``cached()`` which will provide caching for the output of a single function. It's given the "key" which we'd like to use in Memcached, and internally it makes usage of :class:`.Lock`, along with a thread based mutex (we'll see a distributed mutex in the next section):: import pylibmc import threading import time from dogpile.core import Lock, NeedRegenerationException mc_pool = pylibmc.ThreadMappedPool(pylibmc.Client("localhost")) def cached(key, expiration_time): """A decorator that will cache the return value of a function in memcached given a key.""" mutex = threading.Lock() def get_value(): with mc_pool.reserve() as mc: value_plus_time = mc.get(key) if value_plus_time is None: raise NeedRegenerationException() # return a tuple (value, createdtime) return value_plus_time def decorate(fn): def gen_cached(): value = fn() with mc_pool.reserve() as mc: # create a tuple (value, createdtime) value_plus_time = (value, time.time()) mc.put(key, value_plus_time) return value_plus_time def invoke(): with Lock(mutex, gen_cached, get_value, expiration_time) as value: return value return invoke return decorate Using the above, we can decorate any function as:: @cached("some key", 3600) def generate_my_expensive_value(): return slow_database.lookup("stuff") The :class:`.Lock` object will ensure that only one thread at a time performs ``slow_database.lookup()``, and only every 3600 seconds, unless Memcached has removed the value, in which case it will be called again as needed. In particular, dogpile.core's system allows us to call the memcached get() function at most once per access, instead of Beaker's system which calls it twice, and doesn't make us call get() when we just created the value. For the mutex object, we keep a ``threading.Lock`` object that's local to the decorated function, rather than using a global lock. This localizes the in-process locking to be local to this one decorated function. In the next section, we'll see the usage of a cross-process lock that accomplishes this differently. Using a File or Distributed Lock with Dogpile ============================================== The examples thus far use a ``threading.Lock()`` object for synchronization. If our application uses multiple processes, we will want to coordinate creation operations not just on threads, but on some mutex that other processes can access. In this example we'll use a file-based lock as provided by the `lockfile `_ package, which uses a unix-symlink concept to provide a filesystem-level lock (which also has been made threadsafe). Another strategy may base itself directly off the Unix ``os.flock()`` call, or use an NFS-safe file lock like `flufl.lock `_, and still another approach is to lock against a cache server, using a recipe such as that described at `Using Memcached as a Distributed Locking Service `_. What all of these locking schemes have in common is that unlike the Python ``threading.Lock`` object, they all need access to an actual key which acts as the symbol that all processes will coordinate upon. So here, we will also need to create the "mutex" which we pass to :class:`.Lock` using the ``key`` argument:: import lockfile import os from hashlib import sha1 # ... other imports and setup from the previous example def cached(key, expiration_time): """A decorator that will cache the return value of a function in memcached given a key.""" lock_path = os.path.join("/tmp", "%s.lock" % sha1(key).hexdigest()) # ... get_value() from the previous example goes here def decorate(fn): # ... gen_cached() from the previous example goes here def invoke(): # create an ad-hoc FileLock mutex = lockfile.FileLock(lock_path) with Lock(mutex, gen_cached, get_value, expiration_time) as value: return value return invoke return decorate For a given key "some_key", we generate a hex digest of the key, then use ``lockfile.FileLock()`` to create a lock against the file ``/tmp/53def077a4264bd3183d4eb21b1f56f883e1b572.lock``. Any number of :class:`.Lock` objects in various processes will now coordinate with each other, using this common filename as the "baton" against which creation of a new value proceeds. Unlike when we used ``threading.Lock``, the file lock is ultimately locking on a file, so multiple instances of ``FileLock()`` will all coordinate on that same file - it's often the case that file locks that rely upon ``flock()`` require non-threaded usage, so a unique filesystem lock per thread is often a good idea in any case. python-dogpile.core-0.4.1/docs/build/api.rst0000644000175000017500000000056112076551651017725 0ustar chuckchuck=== API === .. currentmodule:: dogpile.core Dogpile ======= .. autoclass:: Lock :members: .. autoclass:: NeedRegenerationException :members: Utilities ========== .. autoclass:: ReadWriteMutex :members: .. autoclass:: NameRegistry :members: Legacy API =========== .. autoclass:: Dogpile :members: .. autoclass:: SyncReaderDogpile :members: python-dogpile.core-0.4.1/docs/build/changelog.rst0000644000175000017500000000656412076551716021116 0ustar chuckchuck========== Changelog ========== .. changelog:: :version: 0.4.1 :released: Sat Jan 19 2013 .. change:: :pullreq: 2 An "async creator" function can be specified to :class:`.Lock` which allows the "creation" function to be called asynchronously or be subsituted for another asynchronous creation scheme. Courtesy Ralph Bean. .. changelog:: :version: 0.4.0 :released: Tue Oct 30 2012 .. change:: reworked Dogpile's API into a new object called Lock. Lock presents just one set of arguments for locking within one constructor call, and provides the "comprehensive" caching pattern that is what's desired in the vast majority of cases. The Dogpile class is now legacy, and builds its various usage patterns on top of Lock. .. change:: :tags: :tickets: 1 Fixed the dependency on storing "creationtime" locally in memory; this caused dogpile pileups for a missing cache value when used in multiple-process environments. The new Lock object now checks the value_and_created_fn() an extra time within the "lock acquired" phase so that multiple writers who entered the block don't rely upon a memory-only version of creation time. .. changelog:: :version: 0.3.3 :released: Tue Sep 25 2012 .. change:: :tags: :tickets: repair setup.py so that tests don't install, courtesy Ben Hayden. .. changelog:: :version: 0.3.2 :released: Wed Jun 13 2012 .. change:: :tags: :tickets: upgrade to beta. .. changelog:: :version: 0.3.1 :released: Sun Apr 15 2012 .. change:: :tags: :tickets: py3k compatibility is in-place now, no 2to3 needed. .. changelog:: :version: 0.3.0 :released: Sat Apr 14 2012 .. change:: :tags: :tickets: Renamed the project again - to dogpile.core. Package has been reorganized so that "dogpile" is a pure namespace package. The base dogpile features are now in "dogpile.core". .. changelog:: :version: 0.2.2 :released: Fri Mar 30 2012 .. change:: :tags: :tickets: expire time of None means "never expire". .. changelog:: :version: 0.2.1 :released: Fri Dec 23 2011 .. change:: :tags: :tickets: Add new "nameregistry" helper. Another fixture derived from Beaker, this allows the ad-hoc creation of a new Dogpile lock based on a name, where all other threads calling that name at the same time will get the same Dogpile lock. Allows any number of logical "dogpile" actions to carry on concurrently without any memory taken up outside of those operations. .. change:: :tags: :tickets: To support the use case supported by nameregistry, added value_and_created_fn to dogpile.acquire(). The idea is that the value_and_created_fn can return (value, createdtime), so that the creation time of the value can come from the cache, thus eliminating the need for the dogpile lock to hang around persistently. .. changelog:: :version: 0.2.0 :released: Sun Oct 23 2011 .. change:: :tags: :tickets: change name to lowercase "dogpile". .. changelog:: :version: 0.1.0 .. change:: initial revision. python-dogpile.core-0.4.1/docs/build/builder.py0000644000175000017500000000041212076551651020415 0ustar chuckchuck def autodoc_skip_member(app, what, name, obj, skip, options): if what == 'class' and skip and name in ('__init__',) and obj.__doc__: return False else: return skip def setup(app): app.connect('autodoc-skip-member', autodoc_skip_member) python-dogpile.core-0.4.1/docs/build/Makefile0000644000175000017500000000635012076551651020064 0ustar chuckchuck# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = output # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dist-html same as html, but places files in /doc" @echo " dirhtml to make HTML files named index.html in directories" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dist-html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .. @echo @echo "Build finished. The HTML pages are in ../." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Alembic.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Alembic.qhc" latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." python-dogpile.core-0.4.1/docs/build/index.rst0000644000175000017500000000132312076551651020260 0ustar chuckchuck======================================== Welcome to dogpile.core's documentation! ======================================== `dogpile.core `_ provides the *dogpile* lock, one which allows a single thread or process to generate an expensive resource while other threads/processes use the "old" value, until the "new" value is ready. dogpile.core is at the core of the `dogpile.cache `_ package which provides for a basic cache API and sample backends based on the dogpile concept. .. toctree:: :maxdepth: 2 front usage api changelog Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` python-dogpile.core-0.4.1/docs/build/front.rst0000644000175000017500000000354412076551651020310 0ustar chuckchuck============ Front Matter ============ Information about the dogpile.core project. Project Homepage ================ dogpile.core is hosted on `Bitbucket `_ - the lead project page is at https://bitbucket.org/zzzeek/dogpile.core. Source code is tracked here using `Mercurial `_. Releases and project status are available on Pypi at http://pypi.python.org/pypi/dogpile.core. The most recent published version of this documentation should be at http://dogpilecore.readthedocs.org. Installation ============ Install released versions of dogpile.core from the Python package index with `pip `_ or a similar tool:: pip install dogpile.core Installation via source distribution is via the ``setup.py`` script:: python setup.py install Community ========= dogpile.core is developed by `Mike Bayer `_, and is loosely associated with the `Pylons Project `_. As usage of dogpile.core and dogpile.cache increases, it is anticipated that the Pylons mailing list and IRC channel will become the primary channels for support. Bugs ==== Bugs and feature enhancements to dogpile.core should be reported on the `Bitbucket issue tracker `_. If you're not sure that a particular issue is specific to either dogpile.cache or dogpile.core, posting to the `dogpile.cache issue tracker `_ is likely the better place to post first, but it's not critical either way. * `dogpile.cache issue tracker `_ (post here if unsure) * `dogpile.core issue tracker `_ python-dogpile.core-0.4.1/docs/_static/0000755000175000017500000000000012076552100016735 5ustar chuckchuckpython-dogpile.core-0.4.1/docs/_static/file.png0000644000175000017500000000061011767203717020374 0ustar chuckchuckPNG  IHDRabKGD pHYs  tIME  )TIDAT8˭J@Ir('[ "&xYZ X0!i|_@tD] #xjv YNaEi(əy@D&`6PZk$)5%"z.NA#Aba`Vs_3c,2mj [klvy|!Iմy;v "߮a?A7`c^nk?Bg}TЙD# "RD1yER*6MJ3K_Ut8F~IENDB`python-dogpile.core-0.4.1/docs/_static/pygments.css0000644000175000017500000000753412076551753021343 0ustar chuckchuck.highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #303030 } /* Generic.Output */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #0040D0 } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #007020 } /* Keyword.Pseudo */ .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ .highlight .s { color: #4070a0 } /* Literal.String */ .highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .highlight .no { color: #60add5 } /* Name.Constant */ .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ .highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */python-dogpile.core-0.4.1/docs/_static/comment-close.png0000644000175000017500000000677211767203717022241 0ustar chuckchuckPNG  IHDRa OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME!,IDAT8e_Hu?}s3y˕U2MvQ֊FE.łĊbE$DDZF5b@Q":2{n.s<_ y?mwV@tR`}Z _# _=_@ w^R%6gC-έ(K>| ${})[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& (d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== "find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return 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(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, "_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== "="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); (function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= {},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== "string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== 1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, ""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", ""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, "border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== "string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? "&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== 1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== "json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== "number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": "pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); python-dogpile.core-0.4.1/docs/_static/minus.png0000644000175000017500000000030711767203717020613 0ustar chuckchuckPNG  IHDR &q pHYs  tIME <8tEXtComment̖RIDATcz(BpipPc |IENDB`python-dogpile.core-0.4.1/docs/_static/up.png0000644000175000017500000000055311767203717020107 0ustar chuckchuckPNG  IHDRasRGBbKGDC pHYs B(xtIME!.<̓EIDAT8͓NABP\EG{%<|xc  cr6@t;b$;3&)h1!﫳Hzz@=)p 3۵e2/ߴ ( %^ND^ }3H1DoǪISFұ?, G`{v^X[b]&HC3{:sO& ?,[eL#IENDB`python-dogpile.core-0.4.1/docs/_static/nature.css0000644000175000017500000001011712076551753020762 0ustar chuckchuck/* * nature.css_t * ~~~~~~~~~~~~ * * Sphinx stylesheet -- nature theme. * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: Arial, sans-serif; font-size: 100%; background-color: #111; color: #555; margin: 0; padding: 0; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } hr { border: 1px solid #B1B4B6; } div.document { background-color: #eee; } div.body { background-color: #ffffff; color: #3E4349; padding: 0 30px 30px 30px; font-size: 0.9em; } div.footer { color: #555; width: 100%; padding: 13px 0; text-align: center; font-size: 75%; } div.footer a { color: #444; text-decoration: underline; } div.related { background-color: #6BA81E; line-height: 32px; color: #fff; text-shadow: 0px 1px 0 #444; font-size: 0.9em; } div.related a { color: #E2F3CC; } div.sphinxsidebar { font-size: 0.75em; line-height: 1.5em; } div.sphinxsidebarwrapper{ padding: 20px 0; } div.sphinxsidebar h3, div.sphinxsidebar h4 { font-family: Arial, sans-serif; color: #222; font-size: 1.2em; font-weight: normal; margin: 0; padding: 5px 10px; background-color: #ddd; text-shadow: 1px 1px 0 white } div.sphinxsidebar h4{ font-size: 1.1em; } div.sphinxsidebar h3 a { color: #444; } div.sphinxsidebar p { color: #888; padding: 5px 20px; } div.sphinxsidebar p.topless { } div.sphinxsidebar ul { margin: 10px 20px; padding: 0; color: #000; } div.sphinxsidebar a { color: #444; } div.sphinxsidebar input { border: 1px solid #ccc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar input[type=text]{ margin-left: 20px; } /* -- body styles ----------------------------------------------------------- */ a { color: #005B81; text-decoration: none; } a:hover { color: #E32E00; text-decoration: underline; } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: Arial, sans-serif; background-color: #BED4EB; font-weight: normal; color: #212224; margin: 30px 0px 10px 0px; padding: 5px 0 5px 10px; text-shadow: 0px 1px 0 white } div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } div.body h2 { font-size: 150%; background-color: #C8D5E3; } div.body h3 { font-size: 120%; background-color: #D8DEE3; } div.body h4 { font-size: 110%; background-color: #D8DEE3; } div.body h5 { font-size: 100%; background-color: #D8DEE3; } div.body h6 { font-size: 100%; background-color: #D8DEE3; } a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } a.headerlink:hover { background-color: #c60f0f; color: white; } div.body p, div.body dd, div.body li { line-height: 1.5em; } div.admonition p.admonition-title + p { display: inline; } div.highlight{ background-color: white; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre { padding: 10px; background-color: White; color: #222; line-height: 1.2em; border: 1px solid #C6C9CB; font-size: 1.1em; margin: 1.5em 0 1.5em 0; -webkit-box-shadow: 1px 1px 1px #d8d8d8; -moz-box-shadow: 1px 1px 1px #d8d8d8; } tt { background-color: #ecf0f3; color: #222; /* padding: 1px 2px; */ font-size: 1.1em; font-family: monospace; } .viewcode-back { font-family: Arial, sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; }python-dogpile.core-0.4.1/docs/_static/up-pressed.png0000644000175000017500000000056411767203717021554 0ustar chuckchuckPNG  IHDRasRGBbKGDC pHYs B(xtIME ,ZeIDAT8͓jA*WKk-,By@- و/`cXYh!6jf GrOlXvvfk2!p!GOOԲ &zf 6|M~%`]* ΛM]K ZĆ1Er%ȶcm1` -1) start = i; }); start = Math.max(start - 120, 0); var excerpt = ((start > 0) ? '...' : '') + $.trim(text.substr(start, 240)) + ((start + 240 - text.length) ? '...' : ''); var rv = $('
').text(excerpt); $.each(hlwords, function() { rv = rv.highlightText(this, 'highlighted'); }); return rv; } /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } /** * Search Module */ var Search = { _index : null, _queued_query : null, _pulse_status : -1, init : function() { var params = $.getQueryParameters(); if (params.q) { var query = params.q[0]; $('input[name="q"]')[0].value = query; this.performSearch(query); } }, loadIndex : function(url) { $.ajax({type: "GET", url: url, data: null, success: null, dataType: "script", cache: true}); }, setIndex : function(index) { var q; this._index = index; if ((q = this._queued_query) !== null) { this._queued_query = null; Search.query(q); } }, hasIndex : function() { return this._index !== null; }, deferQuery : function(query) { this._queued_query = query; }, stopPulse : function() { this._pulse_status = 0; }, startPulse : function() { if (this._pulse_status >= 0) return; function pulse() { Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (var i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); }; pulse(); }, /** * perform a search for something */ performSearch : function(query) { // create the required interface elements this.out = $('#search-results'); this.title = $('

' + _('Searching') + '

').appendTo(this.out); this.dots = $('').appendTo(this.title); this.status = $('

').appendTo(this.out); this.output = $('