PKêBzBuXßÔf(f((rapidsms-healthcare-latest/settings.html Full Settings Reference — rapidsms-healthcare 0.1.0 documentation

Full Settings Reference¶

Below are the full set of settings for configuring rapidsms-healthcare along with their default values.

HEALTHCARE_STORAGE_BACKEND¶

Default: 'healthcare.backends.djhealth.DjangoStorage'

Controls where rapidsms-healthcare stores patient and provider data. The default backends provided are:

Additional backends can be written as needed.

Project Versions

Table Of Contents

Previous topic

Storage Backend API

Next topic

Contributing Guide

This Page

PKêBzBPrWßI>I>%rapidsms-healthcare-latest/index.html RapidSMS Healthcare — rapidsms-healthcare 0.1.0 documentation

RapidSMS Healthcare¶

rapidsms-healthcare is a reusable Django application for managing healthcare provider and patient records for building RapidSMS applications. The goal is to create a common API for storing and accessing these records and have configurable storage backends for the data itself. For instance on site might store data using a SQL database via the Django ORM while another might store the data in OpenMRS. Additional Django/RapidSMS applications can use this API to store and retrive data without knowning how it will be stored.

Build Status :target: https://secure.travis-ci.org/caktus/rapidsms-healthcare

Dependencies¶

rapidsms-appointments currently runs on Python 2.6 and 2.7 and requires the following Python packages:

  • Django >= 1.4
  • RapidSMS >= 0.11.0

Documentation¶

Documentation on using rapidsms-healthcare is available on Read The Docs.

Running the Tests¶

With all of the dependancies installed, you can quickly run the tests with via:

python setup.py test

or:

python runtests.py

To test rapidsms-healthcare in multiple supported environments you can make use of the tox configuration.:

# You must have tox installed
pip install tox
# Build default set of environments
tox
# Build a single environment
tox -e py26-1.4.X

License¶

rapidsms-healthcare is released under the BSD License. See the LICENSE file for more details.

Contributing¶

If you think you’ve found a bug or are interested in contributing to this project check out rapidsms-healthcare on Github. A full contributing guide can be found in the online documentation.

Development sponsored by Caktus Consulting Group, LLC.

Project Versions

Table Of Contents

Next topic

Project Overview

This Page

PKêBzB˜ª ãµµ)rapidsms-healthcare-latest/searchindex.jsSearch.setIndex({objects:{"":{HealthcareStorage:[4,1,1,""]},HealthcareStorage:{delete_patient:[4,0,1,""],filter_providers:[4,0,1,""],create_provider:[4,0,1,""],create_patient:[4,0,1,""],get_provider:[4,0,1,""],filter_patients:[4,0,1,""],update_provider:[4,0,1,""],unlink_patient:[4,0,1,""],update_patient:[4,0,1,""],delete_provider:[4,0,1,""],link_patient:[4,0,1,""],get_patient:[4,0,1,""]}},terms:{represent:3,all:[5,0,4,7],code:[5,0,3],partial:7,edg:4,skip:6,global:7,llc:0,follow:[5,0,7,6],depend:0,readabl:[5,7],articl:5,under:0,sourc:[5,0,4,7],everi:5,string:[7,4],fals:4,update_provid:4,electron:3,jack:7,upstream:5,veri:3,join:7,exact:[7,4],list:[7,4],"try":[5,3],patientnotfound:7,small:5,fancybackendtestcas:4,pleas:[5,6],impli:[7,3],seper:3,pass:[7,4],patient:[7,0,2,4,3],providernotfound:7,updated_d:7,unlink_pati:4,compat:4,rapidsm:[0,1,2,3,5,6,7],section:[5,4],current:[5,0,7,3,6],delet:[7,4],version:5,intersect:4,"new":[5,7,4],method:[7,6,4],full:[0,4,2],gener:7,get_provid:4,here:[5,6],created_d:7,met:4,address:5,path:[7,4],along:[7,2],openmr:[0,4,3],sinc:4,valu:[7,4,2],great:5,medici:3,datetim:[7,4],base:4,chang:[5,6,1],chanc:5,portabl:7,via:[5,0,3,6],solut:3,app:[6,3],prefer:5,inequ:7,releas:[0,1,6],"boolean":7,instal:[5,0,6],highli:6,yourself:6,from:[5,7,4],describ:4,would:[7,6],memori:[7,1],two:3,next:[5,0,4,6],recommend:6,scope:5,checkout:5,more:[5,0],source_nam:4,peopl:3,relat:[0,3,6],ital:7,hurt:3,warn:7,flag:7,known:[5,0,3],healtcar:7,given:[5,7,4],easiest:5,must:[7,0,4],none:4,nationalid:7,retriev:[7,6],setup:[5,0],work:[3,4],uniqu:[7,4],histori:[0,1],delete_pati:4,can:[0,2,3,5,4,7,6],fetch:[5,4],control:[7,2],accept:5,want:[5,4],onlin:0,multipl:[5,0,4],goal:[0,3],rather:3,anoth:[7,0,3],write:[5,4],how:[5,0],place:5,simpl:5,updat:[5,7,4],map:4,product:7,create_provid:4,singular:3,clone:5,after:7,befor:5,updated_date__lt:7,mai:[5,6,4,7,3],filter_pati:4,unlink:7,data:[0,2,3,4,7,6],github:[5,0,3],attempt:3,correspond:4,django:[0,1,6,3,5,4,7],issu:5,inform:[5,0,7,6],environ:[5,0],incorpor:5,refetch:7,couchdb:4,help:[5,3],over:5,increas:[5,6],through:[5,3,4,7],flexibl:3,style:5,group:0,thank:5,fit:5,fix:5,better:5,whether:7,transpar:4,main:5,might:[5,0,7],them:5,"return":[7,4],greater:[7,4],thei:4,python:[5,0,4,6],overal:5,initi:[6,1],nation:7,"break":7,now:7,discuss:5,name:[7,3,4],each:[7,3,4],found:[7,0,4,6],difficult:5,mean:3,healthcar:[0,1,2,3,4,5,6,7],continu:7,runtest:[5,0],sponsor:0,meth:4,out:[5,0],facil:7,newli:4,content:0,health:7,difficulti:3,insid:5,advanc:4,migrat:6,tox:[5,0],free:5,standard:[5,0,4,3],orm:[7,0,1,3],dictionari:[7,4],ask:5,care:7,reusabl:[0,3],recod:[],keep:5,filter:[7,0,4],enforc:4,indend:[5,7],lte:[7,4],think:0,south:6,oper:[7,4],mixin:4,directli:7,feel:5,number:5,system:[3,4],hook:5,unlik:7,done:7,"long":5,type:[7,4],stabl:6,installed_app:[7,6],open:5,primari:[7,3],differ:[7,6],start:[0,6],associ:[7,4],licens:0,demostr:5,attach:4,paramt:4,master:5,store:[0,2,3,4,7,6],schema:6,adher:5,djangostorag:[7,2],option:[6,4],part:5,consult:0,necessarili:5,than:[5,3,4,7],provid:[7,0,2,4,3],remov:[7,4],structur:4,exampl:[5,7],project:[5,0,7,3,6],were:4,fork:5,argument:7,packag:[0,6],have:[5,0,7,6],tabl:[7,6],need:[7,6,2,4,3],get_pati:4,name__exact:7,date:[7,4],built:[5,3,7],pep8:5,gte:[7,4],note:[5,6,4,7],also:[5,6,4,7],client:[7,3,4],take:[5,7],which:[5,3,4,7],create_pati:4,singl:[5,0],even:7,link_pati:4,sure:5,temptat:7,though:[7,4],usernam:5,object:7,most:4,plan:6,deploi:7,bsd:0,"class":4,doc:[5,0],request:[5,0,4],doe:4,dummi:[7,2],caktu:[5,0],filter_provid:4,ewheel:3,find:[5,6,4,7],access:[7,0,3],onli:[5,7],locat:7,nosql:4,configur:[7,0,2,6],activ:7,should:[5,7,4],local:7,contribut:[5,0,3,6],get:[5,0,7,6],express:[7,0,4],pypi:6,cannot:[7,4],report:5,requir:[7,0,6],"public":1,remot:5,common:[5,0,7,3],contain:[7,4],where:[7,2],set:[0,2,3,4,7,6],knowledg:3,sex:7,resist:7,see:[0,6],result:4,respons:4,testcas:4,statu:7,still:3,healthcare_storage_backend:[7,0,2,6],databas:[0,4],review:5,tend:3,written:[5,2],between:[7,3],"import":[5,7,4],attribut:4,never:7,extend:4,joe:7,solv:[5,3],addit:[7,0,2,4,3],both:[7,3],last:7,howev:5,equal:[7,4],against:5,etc:4,instanc:[7,0],improv:5,com:[5,3],simpli:4,point:7,guidelin:5,respect:7,guid:[5,0,3,6],assign:7,backend:[0,1,2,3,4,7,6],delete_provid:4,empti:[7,4],interpret:4,interest:[5,0],basic:[7,0],quickli:0,worker:3,ani:5,"case":[5,4],aim:[5,3],defin:4,"while":[0,3,6],suport:1,abov:[5,7,4],canon:3,site:0,sting:4,itself:0,develop:[7,0,4,3],minim:5,make:[5,0],medic:4,same:3,djhealth:[7,6,2],html:5,document:[5,0,3,6],complet:4,http:[5,3],retriv:[7,0,3],rais:7,user:[7,4],extern:[7,3],death_dat:7,appropri:5,entri:7,well:[5,4],person:5,without:[0,3],command:5,thi:[0,6,3,5,4,7],choos:3,model:[7,3,4],identifi:[7,4],just:5,less:[7,4],tip:5,rest:5,birth_dat:7,yet:[],except:7,add:[5,7],overview:[0,3],modul:[7,4],match:[7,4],build:[5,0],earli:3,applic:[7,0,4,3,6],name__lik:7,format:4,read:[5,0],crud:7,piec:7,know:7,field_nam:4,like:[7,6,4],success:7,api:[7,0,4,3,6],necessari:[7,6,4],either:[5,7],popular:4,update_pati:4,manag:[7,0,6],underli:4,interact:4,some:5,born:7,intern:7,syncdb:6,distribut:7,broad:3,deploy:3,larg:5,freem:4,refer:[0,2],core:5,run:[5,0,4],bold:7,usag:[7,0,6],broken:5,step:[0,6],repositori:5,appli:6,stage:3,comparison:4,about:5,actual:7,py26:[5,0],page:5,healthmodel:3,block:5,own:[5,3,4],"float":4,pair:4,ensur:5,storag:[7,0,4,3,6],your:[5,6,4,7],merg:5,git:5,wai:[5,0,7],aren:5,support:[7,0,6],submit:[5,0],custom:[5,6],avail:[7,0],strict:5,includ:[5,6,7],suit:3,jane:7,strictli:7,"function":[5,7],creation:7,tupl:4,dummystorag:[7,2],link:7,"true":4,bug:[5,0,6],pull:[5,0],consist:5,possibl:6,"default":[0,2,3,4,7,6],bugfix:5,record:[7,0,4,3],below:[7,4,2],otherwis:4,problem:[5,3],backendtestmixin:4,similar:7,featur:[5,6],constant:4,creat:[0,6,3,5,4,7],"int":4,cover:4,exist:[5,4],file:0,pip:[0,6],check:[5,0],denot:7,allow:3,when:[5,6,4,7,3],detail:[7,0,4],field:[7,4],other:[7,6],lookup:[7,0,4],futur:[6,3],test:[5,0,4,7],you:[5,0,4,7,6],healthcarestorag:4,intend:3,registri:7,mongodb:4,meaning:4,consid:4,sql:0,name__in:7,appoint:0,sphinx:5,directori:5,descript:7,time:[7,3],source_id:4,unicefuganda:3,stprovid:[]},objtypes:{"0":"py:method","1":"py:class"},titles:["RapidSMS Healthcare","Release History","Full Settings Reference","Project Overview","Storage Backend API","Contributing Guide","Getting Started","Basic Usage"],objnames:{"0":["py","method","Python method"],"1":["py","class","Python class"]},filenames:["index","releases","settings","overview","backends","contributing","quick-start","usage"]})PKêBzB>nœ7G<G<,rapidsms-healthcare-latest/contributing.html Contributing Guide — rapidsms-healthcare 0.1.0 documentation

Contributing Guide¶

There are a number of ways to contribute to rapidsms-healthcare. If you are interested in making rapidsms-healthcare better then this guide will help you find a way to contribute.

Ways to Contribute¶

You can contribute to the project by submitting bug reports, feature requests or documentation updates through the Github issues.

Getting the Source¶

You can clone the repository from Github:

git clone git://github.com/caktus/rapidsms-healthcare.git

However this checkout will be read only. If you want to contribute code you should create a fork and clone your fork. You can then add the main repository as a remote:

git clone git@github.com:<your-username>/rapidsms-healthcare.git
git remote add upstream git://github.com/caktus/rapidsms-healthcare.git
git fetch upstream

Running the Tests¶

When making changes to the code, either fixing bugs or adding features, you’ll want to run the tests to ensure that you have not broken any of the existing functionality. With the code checked out and Django installed you can run the tests via:

python setup.py test

or:

python runtests.py

To test against multiple versions of Django you can use install and use tox>=1.4. The tox command will run the tests against Django 1.3, 1.4 and the current Git master using Python 2.6.:

# Build all environments
tox
# Build a single environment
tox -e py26-1.3.X

Building all environments will also build the documentation. More on that in the next section.

Building the Documentation¶

This project aims to have a minimal core with hooks for customization. That makes documentation an important part of the project. Useful examples and notes on common use cases are a great way to contribute and improve the documentation.

The docs are written in ReST and built using Sphinx. As noted above you can use tox to build the documentation or you can build them on their own via:

tox -e docs

or:

make html

from inside the docs/ directory.

Coding Standards¶

Code contributions should follow the PEP8 and Django contributing style standards. Please note that these are only guidelines. Overall code consistency and readability are more important than strict adherence to these guides.

Submitting a Pull Request¶

The easiest way to contribute code or documentation changes is through a pull request. For information on submitting a pull request you can read the Github help page https://help.github.com/articles/using-pull-requests.

Pull requests are a place for the code to be reviewed before it is merged. This review will go over the coding style as well as if it solves the problem indended and fits in the scope of the project. It may be a long discussion or it might just be a simple thank you.

Not necessarily every request will be merged but you should not take it personally if you change is not accepted. If you want to increase the chances of your change being incorporated then here are some tips.

  • Address a known issue. Preference is given to a request that fixes a currently open issue.
  • Include documentation and tests when appropriate. New features should be tested and documented. Bugfixes should include tests which demostrate the problem.
  • Keep it simple. It’s difficult to review a large block of code so try to keep the scope of the change small.

You should also feel free to ask for help writing tests or writing documentation if you aren’t sure how to go about it.

Project Versions

Table Of Contents

Previous topic

Full Settings Reference

Next topic

Release History

This Page

PKêBzByÕÞýá+á+(rapidsms-healthcare-latest/genindex.html Index — rapidsms-healthcare 0.1.0 documentation

Project Versions

This Page

PKêBzBkŧE3¨3¨%rapidsms-healthcare-latest/usage.html Basic Usage — rapidsms-healthcare 0.1.0 documentation

Basic Usage¶

The primary usage of this application is for other RapidSMS applications to have a common way to store and retrive patient/provider data even though each project which deploy the application may use different methods of actually storing the data.

Applications built with rapidsms-healtcare should use the functionality provided by healthcare.api. The client object in the module is primary entry point for accessing the healthcare data. It provides basic CRUD (Create/Update/Delete) operations for the patient and provider data:

from healthcare.api import client

patient = client.patients.create(name='Joe', sex='M')

Available Backends¶

Where this data is stored configured by the HEALTHCARE_STORAGE_BACKEND setting. Below are all of the available backends included in the rapidsms-healthcare distribution.

DjangoStorage¶

Path: 'healthcare.backends.djhealth.DjangoStorage'

This is the default storage backend. It stores the patient and provider information using the Django ORM. To use this backend you must include 'healthcare.backends.djhealth' in your INSTALLED_APPS setting to create the necessary tables.

Warning

Though the default storage backend uses the Django ORM, developers should resist all temptation to access the models directly (including creating FKs in additional models) as that will break the portability of the application.

DummyStorage¶

Path: 'healthcare.backends.dummy.DummyStorage'

This backend stores the data in local memory. This backend is indended only for testing and should never be used in a production setting.

Patient Information¶

Operations on patient data are done through client.patients. Currently the backend supports create, get, update, filter, delete, link, and unlink:

from healthcare.api import client

# Create new patient
patient = client.patients.create(name='Joe', sex='M')

# Update the patient's name
client.patients.update(patient['id'], name='Jack')

# Refetch the patient record
patient = client.patients.get(patient['id'])

# Get patients with name containing 'Ja'
patients = client.patients.filter(name__like='Ja')

# Delete a patient record
client.patients.delete(patient['id'])

Patient Data Model¶

Patients currently store the following pieces of data [1]:

Name Type Description
id String Globally unique identifier
name String A readable name/identifier
sex String (M/F) Patient’s sex
birth_date Date Date the patient was born
death_date Date Date the patient died
location String Identifier for the patient’s location
created_date Datetime Time when the record was created
updated_date Datetime Time when the record was last updated
status String (A/I) Flag to denote if the record is currently active
[1]Required fields are bold and generated values are in italics.

The location field might store the name of the location or an identifier for another location/facility registry.

patients.create¶

patients.create adds a new patient record to the data store. The arguments for this function are passed to the backend to store on the record. The patient data is returned as a dictionary and contains additional fields which are generated by the backend: id, created_date and updated_date.

patients.update¶

patients.update takes the id of the patient along with arguments to be passed to the backend to update. This returns a boolean to note whether a matching patient was found and updated.

patients.get¶

patients.get returns a patient’s data as dictionary for the given id. If no matching patient was found this will raise a PatientNotFound exception.

Patients can also be associated with external ids using the link method. You can retrieve these users using get by passing the source name of the identifier.:

from healthcare.api import client

# Create new patient
patient = client.patients.create(name='Joe', sex='M')

# Associate patient with an external ID
client.patients.link(patient['id'], '123456789', 'NationalID')

# Refetch the patient record using national id
patient = client.patients.get('123456789', source='NationalID')

patients.filter¶

patients.filter returns a list of matched patient data dictionaries. If there are no matches then it will be an empty list. Additional details on filtering expressions is given below.

patients.delete¶

patients.delete takes the id of the patient and returns a boolean to note whether a matching patient was found and deleted.

Provider Information¶

Operations on patient data are done through client.providers. Currently the backend supports create, get, update, filter and delete:

from healthcare.api import client

# Create new provider
provider = client.providers.create(name='Joe')

# Update the providers's name
client.providers.update(provider['id'], name='Jack')

# Refetch the provider record
provider = client.providers.get(provider['id'])

# Get providers with name containing 'Ja'
providers = client.providers.filter(name__like='Ja')

# Delete a provider record
client.providers.delete(provider['id'])

Provider Data Model¶

Providers currently store the following pieces of data [2]:

Name Type Description
id String Globally unique identifier
name String A readable name/identifier
location String Identifier for the provider’s location
created_date Datetime Time when the record was created
updated_date Datetime Time when the record was last updated
status String (A/I) Flag to denote if the record is currently active
[2]Required fields are bold and generated values are in italics.

As with patients, the location field might store the name of the location or an identifier for another location/facility registry.

providers.create¶

providers.create adds a new provider record to the data store. The arguments for this function are passed to the backend to store on the record. The provider data is returned as a dictionary and contains additional fields which are generated by the backend: id, created_date and updated_date.

providers.update¶

providers.update takes the id of the provider along with arguments to be passed to the backend to update. This returns a boolean to note whether a matching provider was found and updated.

providers.get¶

providers.get returns a provider’s data as dictionary for the given id. If no matching provider was found this will raise a ProviderNotFound exception.

providers.filter¶

providers.filter returns a list of matched provider data dictionaries. If there are no matches then it will be an empty list. Additional details on filtering expressions is given below.

providers.delete¶

providers.delete takes the id of the provider and returns a boolean to note whether a matching provider was found and deleted.

Filter Expressions¶

Both the patient and provider APIs support filtering the data by the fields in their respective models. The lookup expressions are modeled after the lookup types in the ORM. Unlike the Django ORM, there is no support for join-like expressions in the lookups.

exact¶

exact is the default lookup type. As the name implies it requires an exact match between the field and given value.:

patients = client.providers.filter(name='Joe')
providers = client.providers.filter(name__exact='Joe')

like¶

The like lookup is a containment expression for string-type fields. For instance, this would be used to find data with a partial name match.:

patients = client.providers.filter(name__like='J')
providers = client.providers.filter(name__like='J')

in¶

An in expression is an exact match for a list of values. This lookup might be used to find a set of patients where you know all of their names.:

patients = client.providers.filter(name__in=['Joe', 'Jane'])
providers = client.providers.filter(name__in=['Joe', 'Jane'])

lt and lte¶

Similar to the ORM, the lt and lte expressions are inequality expressions. These are used to find data either strictly less than or less than or equal to a given value respectively.:

import datetime

patients = client.providers.filter(updated_date__lt=datetime.datetime.now())
providers = client.providers.filter(updated_date__lte=datetime.datetime.now())

gt and gte¶

gt and gte expressions are inequality expressions. These are used to find data either strictly greater than or greater than or equal to a given value respectively.:

import datetime

patients = client.providers.filter(updated_date__lt=datetime.datetime.now())
providers = client.providers.filter(updated_date__lte=datetime.datetime.now())
PKêBzB"¯{4™ ™ &rapidsms-healthcare-latest/search.html Search — rapidsms-healthcare 0.1.0 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.

Project Versions

This Page

PKêBzB¾zGèf$f$(rapidsms-healthcare-latest/releases.html Release History — rapidsms-healthcare 0.1.0 documentation

Release History¶

Release and change history for rapidsms-healthcare

v0.1.0 (Released 2013-02-21)¶

  • Initial public release
  • Suport for Django ORM and in-memory backends

Project Versions

Table Of Contents

Previous topic

Contributing Guide

This Page

PKêBzB/ü]ëææ%rapidsms-healthcare-latest/.buildinfo# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 270c910454b2c0843d6c974816952636 tags: fbb0d17656682115ca4d033fb2f83ba1 PKêBzBÓ[[(rapidsms-healthcare-latest/backends.html Storage Backend API — rapidsms-healthcare 0.1.0 documentation

Storage Backend API¶

If the existing storage backends do not met your needs then you can write you own backend. You may want to store data using a popular medical record system (OpenMRS, FreeMED) or NoSQL database (CouchDB, MongoDB). Since applications interact with the storages though the client API they will transparently work with your new storage.

Note

This is an advanced use case and not necessary for most users or application developers.

The data passed to the backend will match the data described in the patient and provider data model sections. Backend methods which return data should return dictionaries matching this format as well.

Backend API¶

Additional backends should extend from HealthcareStorage which is defined below:

class HealthcareStorage¶
get_patient(id, source=None)¶

Patient data should be fetched for the given id and returned as a dictionary. If the patient does not exist this method should return None.

source is an optional paramter. If given then the id should be interpreted as the source_id and the source as the source_name to find the patient using the association created by py:meth:HealthcareStorage.link_patient. If the patient cannot be found for this association it should also return None.

create_patient(data)¶

A patient record should be created for given set of data given as a dictionary. The newly created patient record should be returned as a dictionary.

update_patient(id, data)¶

Patient data for the given id should be updated with the data dictionary. data may not be a full set of the patient fields. This method should return True if a patient was found and updated and False otherwise.

delete_patient(id)¶

Patient data for the given id should be deleted. This method should return True if a patient was found and deleted and False otherwise.

filter_patients(*lookups)¶

Returns a list of patients matching the set of lookups. If no patients were found it should return an empty list. If no lookups were passed it should return all patients. The details of the lookup structure is given in the next section. When multiple lookups are passed, the intersection of the results should be returned (default to AND the expressions).

Associates a patient with an addition identifier. The source_id and source_name pair should be enforced as unique. This should return a True value if the association was created. Otherwise it should return False.

Removes an association of a patient with an addition identifier. This should return a True value if the association was found and removed. Otherwise it should return False.

get_provider(id)¶

Provider data should be fetched for the given id and returned as a dictionary. If the provider does not exist this method should return None.

create_provider(data)¶

A provider record should be created for given set of data given as a dictionary. The newly created provider record should be returned as a dictionary.

update_provider(id, data)¶

Provider data for the given id should be updated with the data dictionary. data may not be a full set of the provider fields. This method should return True if a provider was found and updated and False otherwise.

delete_provider(id)¶

Provider data for the given id should be deleted. This method should return True if a provider was found and deleted and False otherwise.

filter_providers(*lookups)¶

Returns a list of providers matching the set of lookups. If no providers were found it should return an empty list. If no lookups were passed it should return all providers. The details of the lookup structure is given in the next section. When multiple lookups are passed, the intersection of the results should be returned (default to AND the expressions).

Backend Lookups¶

The above HealthcareStorage.filter_patients() and py:meth:HealthcareStorage.filter_providers methods are each passed a list of lookups for filtering the underlying records. Each of these lookups is a 3-tuple (field_name, operator, value). The field_name is passed as a string and must match a field name on the corresponding data model. The value is the requested value for comparison which should be a standard Python type (int, float, list, sting, date, datetime, etc). The operator is one of the below constants from the healthcare.backends.comparisons module.

Operator Comparison
EQUAL Field is an exact match to the value
LIKE Field contains the value
IN Field is an exact match to one of the values in the value (list/tuple)
LT Field is less than the value
LTE Field is less than or equal to the value
GT Field is greater than the value
GTE Field is greater than or equal to the value

The backend is responsible for mapping these operators to the meaningful expressions for its storage method.

Testing the Backend¶

There is a testing mixin BackendTestMixin in healthcare.tests.base which runs through a set of compatibility tests for the backends. You simply need to attach the path of the backend to the backend attribute.

from django.test import TestCase

from healthcare.tests.base import BackendTestMixin


class FancyBackendTestCase(BackendTestMixin, TestCase):
    backend = 'path.to.new.backend'

This should not be considered an complete set of tests and the developers should write additional tests to cover edge cases in their backend.

Project Versions

Table Of Contents

Previous topic

Basic Usage

Next topic

Full Settings Reference

This Page

PKêBzBÂ8­&rapidsms-healthcare-latest/objects.inv# Sphinx inventory version 2 # Project: rapidsms-healthcare # Version: 0.1 # The remainder of this file is compressed using zlib. xÚ¥“MoÂ0 †ïý‘¶k¸rë Ó¾pBãµiŠštÿ~ q( &ºìV¹ÏëØ~íT¥|mÄDò HBǤÀè¨4µ¼#Oî;ÙqS2z”·À œ+:Í ðxà(r´Wv;1H‰MÄ'WE£MÓZèWÝ=™¸•ç’ºWšÚíiø}½6¢“pÙ^æv…²µÍW% e¶\Îlv+øUŠ,u,õìcdfc®‰ÞæåyêWX¸NKàÒ”9oá؆ç[Pâ21•*´OÑ«(ªhPͳôe=Ÿ¦ËŒ­ÖïËô1céô9{›õ²U‘;ñÿ£’Æv{S‰œõ¿«ëýûÜ?¾&+µ½ýÖ:×p;ˆ~g•‹…¬ƒœöè™Ñ>têóühŽwÅPn÷uRƒ)AÆíÑ¡azEî&Vîø\r­‡¾vKt±ö~¢µ~;X8(ýç~1£ßÿWãÁäpù±ÍãzÆ >öñ°b±ú0øaúÛq_ßPKêBzBzí+ùÌ2Ì2+rapidsms-healthcare-latest/quick-start.html Getting Started — rapidsms-healthcare 0.1.0 documentation

Getting Started¶

Here you will find the necessary steps to install and initial configure the rapidsms-healthcare application.

Requirements¶

rapidsms-healthcare requires Python 2.6 or 2.7. Python 3 is not currently supported but is planned in the future as Django and RapidSMS support for Python 3 increases. It also requires the following packages:

  • Django >= 1.4
  • RapidSMS >= 0.11.0

Installation¶

Stable releases of rapidsms-healthcare can be found on PyPi and pip is the recommended method for installing the package:

pip install rapidsms-healthcare

Configuration¶

The storage and retrieval of healthcare related data is configured by the HEALTHCARE_STORAGE_BACKEND setting. If you are using the default storage backend you need to change your INSTALLED_APPS to include:

INSTALLED_APPS = (
    # Other apps go here
    'healthcare.backends.djhealth',
)

If you are using a different backend then you can skip this step. The Django backend uses South to manage possible future changes to the schema. While not required if you are using South in your project then you can create the tables needed for the backend via:

python manage.py migrate djhealth

If you are not using South then you can create the tables via:

python manage.py syncdb

Note

While using South is optional, it is highly recommended. If you are not using South then you may need to apply future schema change yourself. When needed these will be noted in the release notes.

Next Steps¶

Project Versions

Table Of Contents

Previous topic

Project Overview

Next topic

Basic Usage

This Page

PKêBzBCÝeÖT.T.(rapidsms-healthcare-latest/overview.html Project Overview — rapidsms-healthcare 0.1.0 documentation

Project Overview¶

As the name implies rapidsms-healthcare aims to solve a problem with storing healthcare related data for RapidSMS deployments. Currently there is no canonical data model for storing patient or healthcare worker data in RapidSMS. This means that each deployment tends to create its own model for this data. Applications that are then built to use this data are tied to the model which hurts the reusability of these applications.

At the same time with development of external electronic medicial record systems such as OpenMRS, future deployments may choose to use these solutions rather than storing data via the Django ORM. So rather than try to create a canonical representation of the data, this project intends to create a seperation between the storage and access of the data. Applications which need to access or store patient data will do so through a common API without knowledge of the storage allowing the same code to be used in a deployment which uses the ORM and another which uses OpenMRS.

Goals¶

The development of rapidsms-healthcare is still in the very early stages but the primary goals for both the current and future work are

  • Client API for storing and retriving patient and provider records
  • Default storage backend using the Django ORM
  • Additional storage backend using OpenMRS
  • Documentation guide/standards for creating additional storage backends
  • Suite of applications known to work with this patient API

Project Versions

Table Of Contents

Previous topic

RapidSMS Healthcare

Next topic

Getting Started

This Page

PKâBzBkuFòpp3rapidsms-healthcare-latest/_static/down-pressed.png‰PNG  IHDRóÿasRGB®ÎébKGDùC» pHYs × ×B(›xtIMEÚ -vF#ðIDAT8ËÍÒ!OAàïÚJ, ++@ I v¢bÿ@Wñ7F’ HNâ±ú# ‚4¡8Ì6¹4×6Tñ’MvvÞ¼7³»êœûöDs¿‡aóxâ1†U îq‚;<¦ˆÏ E¸Â-f)âºj%ßpˆo4xFà78G…>æ)â-ƒ ž ¡ÂEYm4%7YTk-¾–Q¶a–"NWAo-y†eqÒá¾,)â ÓÒYÓÑú´ptŽÐå½\hóq´Îím˜sÔz¦ìG]ÄNñ‡Òa…‡röç߶¨s^lã vh\î2Ù%ðâßãŽ0EeRvØIEND®B`‚PKâBzB4µîî,rapidsms-healthcare-latest/_static/jquery.js/*! * jQuery JavaScript Library v1.4.2 * http://jquery.com/ * * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2010, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Sat Feb 13 22:33:48 2010 -0500 */ (function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\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); PKâBzBšhßÛkk+rapidsms-healthcare-latest/_static/down.png‰PNG  IHDRóÿasRGB®ÎébKGDùC» pHYs × ×B(›xtIMEÚ"ÅíU{ëIDAT8ËÍÒ¡NCAÐóÚJ, ++@ ™4>‡¨â/ÐUü’¤^,†~T&Ô3M^^^ÛPÅM6ÙÙ¹sïÌî*¥ôí‰RJ¿‡a)e¼GñÃ*ƒœàñ¹¡èW¸Å<"®«Fò ‡øFgÜã78G…>q ƒ†ÁOI¨p‘«‰:s“õAÕjñ5GÙ†yDœ®ƒ^+y†U:ép_%G§@D|ašÕ­O“£s„Æ(ïy¡M,"â¨Íím˜sÔx:÷£.b§@D|`–V˜åÙŸÛ²”²ÜÆìиÜe²KàÅ¿Ç/êG!‚ ™IEND®B`‚PKâBzB' 5wú ú 4rapidsms-healthcare-latest/_static/comment-close.png‰PNG  IHDRóÿa OiCCPPhotoshop ICC profilexÚSgTSé=÷ÞôBKˆ€”KoR RB‹€‘&*! Jˆ!¡ÙQÁEEÈ ˆŽŽ€ŒQ, Š Øä!¢Žƒ£ˆŠÊûá{£kÖ¼÷æÍþµ×>ç¬ó³ÏÀ –H3Q5€ ©BàƒÇÄÆáä.@ $p³d!sý#ø~<<+"À¾xÓ ÀM›À0‡ÿêB™\€„Àt‘8K€@zŽB¦@F€˜&S `ËcbãP-`'æÓ€ø™{[”! ‘ eˆDh;¬ÏVŠEX0fKÄ9Ø-0IWfH°·ÀÎ ² 0Qˆ…){`È##x„™FòW<ñ+®ç*x™²<¹$9E[-qWW.(ÎI+6aaš@.Ây™24àóÌ ‘àƒóýxήÎÎ6Ž¶_-ê¿ÿ"bbãþåÏ«p@át~Ñþ,/³€;€mþ¢%îh^  u÷‹f²@µ éÚWópø~<ß5°j>{‘-¨]cöK'XtÀâ÷ò»oÁÔ(€hƒáÏwÿï?ýG %€fI’q^D$.Tʳ?ÇD *°AôÁ,ÀÁÜÁ ü`6„B$ÄÂBB d€r`)¬‚B(†Í°*`/Ô@4ÀQh†“p.ÂU¸=púažÁ(¼ AÈa!ÚˆbŠX#Ž™…ø!ÁH‹$ ɈQ"K‘5H1RŠT UHò=r9‡\Fº‘;È2‚ü†¼G1”²Q=Ô µC¹¨7„F¢ Ðdt1š ›Ðr´=Œ6¡çЫhÚ>CÇ0Àè3Äl0.ÆÃB±8, “c˱"¬ «Æ°V¬»‰õcϱwEÀ 6wB aAHXLXNØH¨ $4Ú 7 „QÂ'"“¨K´&ºùÄb21‡XH,#Ö/{ˆCÄ7$‰C2'¹I±¤TÒÒFÒnR#é,©›4H#“ÉÚdk²9”, +È…ääÃä3ää!ò[ b@q¤øSâ(RÊjJåå4åe˜2AU£šRݨ¡T5ZB­¡¶R¯Q‡¨4uš9̓IK¥­¢•Óhh÷i¯ètºÝ•N—ÐWÒËéGè—èôw †ƒÇˆg(›gw¯˜L¦Ó‹ÇT071ë˜ç™™oUX*¶*|‘Ê •J•&•*/T©ª¦ªÞª UóUËT©^S}®FU3Sã© Ô–«UªPëSSg©;¨‡ªg¨oT?¤~Yý‰YÃLÃOC¤Q ±_ã¼Æ c³x,!k «†u5Ä&±ÍÙ|v*»˜ý»‹=ª©¡9C3J3W³Ró”f?ã˜qøœtN ç(§—ó~ŠÞï)â)¦4L¹1e\kª–—–X«H«Q«Gë½6®í§¦½E»YûAÇJ'\'GgÎçSÙSݧ §M=:õ®.ªk¥¡»Dw¿n§î˜ž¾^€žLo§Þy½çú}/ýTýmú§õG X³ $Û Î<Å5qo</ÇÛñQC]Ã@C¥a•a—á„‘¹Ñ<£ÕFFŒiÆ\ã$ãmÆmÆ£&&!&KMêMîšRM¹¦)¦;L;LÇÍÌÍ¢ÍÖ™5›=1×2ç›ç›×›ß·`ZxZ,¶¨¶¸eI²äZ¦Yn…Z9Y¥XUZ]³F­­%Ö»­»§§¹N“N«žÖgðñ¶É¶©·°åØÛ®¶m¶}agbg·Å®Ã“}º}ý= ‡Ù«Z~s´r:V:ޚΜî?}Åô–é/gXÏÏØ3ã¶Ë)ÄiS›ÓGgg¹sƒóˆ‹‰K‚Ë.—>.›ÆÝȽäJtõq]ázÒõ›³›Âí¨Û¯î6îiî‡ÜŸÌ4Ÿ)žY3sÐÃÈCàQåÑ? Ÿ•0k߬~OCOgµç#/c/‘W­×°·¥wª÷aï>ö>rŸã>ã<7Þ2ÞY_Ì7À·È·ËOÃož_…ßC#ÿdÿzÿѧ€%g‰A[ûøz|!¿Ž?:Ûeö²ÙíAŒ ¹AA‚­‚åÁ­!hÈì­!÷ç˜Î‘Îi…P~èÖÐaæa‹Ã~ '…‡…W†?ŽpˆXÑ1—5wÑÜCsßDúD–DÞ›g1O9¯-J5*>ª.j<Ú7º4º?Æ.fYÌÕXXIlK9.*®6nl¾ßüíó‡ââ ã{˜/È]py¡ÎÂô…§©.,:–@LˆN8”ðA*¨Œ%òw%Ž yÂÂg"/Ñ6шØC\*NòH*Mz’쑼5y$Å3¥,幄'©¼L LÝ›:žšv m2=:½1ƒ’‘qBª!M“¶gêgæfvˬe…²þÅn‹·/•Ék³¬Y- ¶B¦èTZ(×*²geWf¿Í‰Ê9–«ž+Íí̳ÊÛ7œïŸÿíÂá’¶¥†KW-X潬j9²‰Š®Û—Ø(Üxå‡oÊ¿™Ü”´©«Ä¹dÏfÒféæÞ-ž[–ª—æ—n ÙÚ´ ßV´íõöEÛ/—Í(Û»ƒ¶C¹£¿<¸¼e§ÉÎÍ;?T¤TôTúT6îÒݵa×ønÑî{¼ö4ìÕÛ[¼÷ý>ɾÛUUMÕfÕeûIû³÷?®‰ªéø–ûm]­NmqíÇÒý#¶×¹ÔÕÒ=TRÖ+ëGǾþïw- 6 UœÆâ#pDyäé÷ ß÷ :ÚvŒ{¬áÓvg/jBšòšF›Sšû[b[ºOÌ>ÑÖêÞzüGÛœ499â?rýéü§CÏdÏ&žþ¢þË®/~øÕë×Îјѡ—ò—“¿m|¥ýêÀë¯ÛÆÂƾÉx31^ôVûíÁwÜwï£ßOä| (ÿhù±õSЧû“““ÿ˜óüc3-ÛbKGDÿÿÿ ½§“ pHYs  šœtIMEÚ!â›ÈÝ,IDAT8Ëe’_HuÇ?Ïï}ßsŽž3ÍyòË•¶¦‹U2MvQÉÖŠFÔE¬.ŠÑÍÃÅ‚­ÄŠbÑE$DD­‹ËZF5b@QÌ"š:2§›š¦¾ïû{Ÿn.êsõåçû<_ø yî?ô½m÷²ýè·wV™ê@t£R`}Z íÄÐ_£# _=œá_@ÝËý ßw^óRë®·•%6gC-έ(K>ä| $„Éï{¯}