PKsJm$!pyladies-kit-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: tags: PKsJNpyladies-kit-latest/objects.inv# Sphinx inventory version 2 # Project: PyLadies Handbook # Version: 2.1 # The remainder of this file is compressed using zlib. xڵMo0#eJBaq{6 Kl nn|fy867d &sM"NΞ֭C*H R̰qBxTȴ0@HtčX2ou+{3NNU-kՓW̕śƶqVniQ ת-,> NDT#,\sLpA Ǧi\i-»d\. PaKۮyX.!1r)}EDRuy}2g;8[4Ř U™y1)VBpf Ӣ$(7:&)1E@2`lXW}8,=& P5svP _T0:JԠM0}r]$o3PfG1;ע_۳"\6WwC8V=O*`|Es(Q,u LПaljX{ժRkғK BIL^7>u G8b%֙+2_,A:{ЕB8g9$ Y|sA'5Aط [{30^4~>n 8%qnԄWAh~$&ePKsJ8tbbpyladies-kit-latest/index.html PyLadies Organizer Handbook

PyLadies Kit

Release v2.1 (What’s new?)

The pyladies kit gets you up and running with starting a PyLadies local group, including what’s needed, advice, event planning help, and some tools that may be helpful.

The pyladies documentation is licensed under the Creative Commons Attribution 3.0 Unported License. The pyladies code is licensed under the MIT License.

The PyLadies wordmark and logo is trademarked, with the usage policy available here defined PyLadies Trademark Usage Policy.




We are an international mentorship group with a focus on helping more women become active participants and leaders in the Python open-source community. Our mission is to promote, educate and advance a diverse Python community through outreach, education, conferences, events and social gatherings.

PyLadies also aims to provide a friendly support network for women and a bridge to the larger Python world. Anyone with an interest in Python is encouraged to participate!

How to Use this Kit

Copy our model (fork & contribute). Or fork and make it completely different. We don’t mind if you get creative!


Their are a few purposes of this PyLadies kit:

  1. To help those interested in starting their own local PyLadies
  2. To be a guide for current local organizers
  3. To be a guide for members

Currently, you can pip install pyladies (see pip install pyladies) with limited functionality. But we plan on more awesome tools for the PyLadies package.

pip install pyladies

pyladies can be easily installed using:

$ pip install pyladies

You can view the PyLadies docs by running:

$ pyladies handbook

It’s pretty limited functionality. But stay tuned for more

Prospective Organizers

Everything you need to start your own PyLadies location!

Prospective Organizers

So you’ve decided to start your own PyLadies group – YAY!

We’re excited to have people like you join our growing community and want to help you get your group launched as quickly and painlessly as possible. If our experience is any indication, your first major event will galvanize and inspire the Python community in your area and create momentum for subsequent events, so it’s crucial to start things off on the right foot!

To help you get started, we’ve created this open-source kit for starting your own PyLadies group in your city. PyLadies is part social club, part stepping stone toward the Python open-source world.

Things to Think About

Types of Local Groups

A local group can be:

  1. a geographic group: for a city, region, state, or country
  2. a student group: for a university, college, or school
  3. an interest group: for any topic (e.g. PyGame, SciPy, Django)

The larger the local group, the harder it is to meet in person. Large local group’s events will be mostly virtual meetups that occur online, whereas small local group’s events tend to be in-person meetups.

A local group can consist of sub-local-groups, making both the in-person and virtual meetups possible.

Group Size

It’s fine if your local group is small. Having just 2-3 women who meet regularly to exchange Python tips and tricks counts as a local group. What matters most is quality, not quantity.

Larger local groups have more flexibility to organize different types of events, but it’s harder to get everyone together for dinner.

Event Frequency

There are no formal requirements for how often a leader hold events. However, we highly encourage that - at minimum, to try and hold one event a month. This helps keep interest in PyLadies from flagging, and helps people maintain their progress in becoming better developers. You can hold more events with proper support and planning.

Suggestions for event types and event resources can be found under Event Ideas and Event Hosting Resources.

Process Overview

Everything is listed in Checklist, but an overview of the process is:

  1. Think about who you’d like to have help you, if you’d like.
  2. Think about the name of the location. For instance, do you want “PyLadies of Super Awesome City”, or “Super Awesome City PyLadies”, or “SACPyLadies”? We highly encourage to not choose a name that is the whole country or state, e.g. “PyLadies of California”. We do not want to discourage other women from starting a local PyLadies, say “PyLadies of Santa Barbara” when “PyLadies of California” is only focusing on the Bay Area.
  3. Fill out the initial interest form (linked in the checklist).
  4. If you haven’t heard from anyone within a week, please ping us! Once you do, you will be given a PyLadies email address, which is also your Google Apps account.
  5. Sign up for ALL the things with your new PyLadies email address, like, Twitter, Facebook, or anything that’s relevant to your location.
  6. If you have signed up for Meetup, you may request reimbursement of fees paid from the Python Software Foundation. Check out their grant process for more information, as well as a Python Software Foundation Grant Proposal.
  7. Think about how you want to setup your website (e.g. a static HTML/CSS/JS site, or a dynamic site with Django/Flask/etc). More information in Creating your own Local Website
  8. Fill out the PyLadies resource form with all the new accounts (linked in the checklist).
  9. Start hosting events!

Please do not purchase domains or setup email addresses; we do that for you! We need to maintain accounts (both for trademark and administrative purposes).

Process Checklist

Here’s all of what needs to be done to start a PyLadies group locally. You may of course adapt this list to meet your group’s needs.


Fill out the initial PyLadies group interest form to get your namespace setup for your group domain and email. If you haven’t heard anything within a week, please ping us!

Once you have received a confirmation that the the initial PyLadies request form was approved and setup, continue on:


  1. With the new email address, sign up for the following social media/communications accounts (if it makes sense for your local group):

    1. Twitter
    2. Facebook
    3. Google+
    4. GitHub
    5. IRC/Freenode
  2. Whether it’s or another local event/community site, start the local group with the email address.


TIP! Uber-frugal? Get half-price Meetup fees! Complete all of the Meetup forms, but stop when you reach the payment page. In 24 hours, you will receive an e-mail from, with a link to complete the payment process at half price. :)

  1. File for a reimbursement for Meetup fees to the Python Software Foundation by following their grant process. A sample grant request can be found here.


The Python Software Foundation will reimburse fees for PyLadies Meetup groups. However, if your location does not use but a different/similar site that charges, still file a reimbursement!

  1. Sign up for a Heroku account with your email address. This will be used to setup your website, which is documented at Creating your own Local Website once you’re ready.

  2. Fill out the PyLadies resource form for contact information, all group information, etc. This is for administrative purposes (e.g. what social media accounts do we own, where should we send PyLadies stickers to, etc), and will not ever be shared outside of PyLadies.

  3. Request to join the following mailing lists:

    1. PyLadies Global Organizers list - all global organizational communication and coordination is done via this list. You’ll be introduced to the mailing list.
    2. PyLadies Global Members list - a global list for PyLadies (and PyGent allies) members. Feel free to introduce yourself and the new location.
  4. If you’re familiar with IRC, come hang out in the #pyladies channel on Freenode.

  5. Plan your first event! Check out New Organizer Reference for New Organizer information. Start promoting your new group via various local channels, including, local PUGs, related groups, and universities, as well as the global PyLadies Members list!


This FAQs are specifically for prospective or new local PyLadies organizers. If you are a member or just curious in learning more about PyLadies, check out the FAQs here: Frequently Asked Questions.

Can men attend local PyLadies group events?

It’s up to you Generally, it’s good to hold women-only events as well as events for both genders (either women and +1 guests, or anyone who wants to attend). Just be aware that the dynamic of the room tends to change when the male:female ratio becomes lopsided.

A good way to hold a mixed-gender event is to partner with a local Python user group.


Be extra-clear in your event description about whether men are allowed/what the rules are – it will save you a lot of time, and prevent awkward conversations.

Can I use the PyLadies logo and graphics for any purpose?

Yes! But please read our logo usage policy.

TL;DR is that any of the graphics in our PyLadies assets repo can be used for your own group promotion and/or to show your support. You may also alter the PyLadies Wordmark or PyLadies Geek logo to adapt it to your location. Check out examples on our locations site.

Logos used with the intention to sell merchandise, please seek permission from the PyLadies leadership.

There is “official” merchandise sold - with proceeds going towards PyLadies - at our own spreadshirt site.

Can transgender women be PyLadies?

Anyone who considers herself a lady and does Python is a PyLady/Python lady. We support all women, whether female by birth or not.

We encourage you sure to make trans women feel welcome by saying so in your meetup group and event descriptions. Here is an example of a statement you could include:

PyLadies [city] is welcoming to and respectful of trans women. We encourage all women to come out to our meetups.

If the idea of trans people is new to you, you might want to take a look at this fantastic illustrated book about gender, this comic, or any of the many other introductions to trans issues on the internet.

How do I set up reimbursement for Meetup fees?

The PSF will most likely reimburse your organizer fees for a local Pyladies meetup. Please refer to the checklist for more info.

What if my question isn’t answered here?

Ask in IRC #pyladies on freenode if you wish. But feel free to organize your PyLadies group however you wish, and make it completely your own. We’re here to help you, not to limit you or control your plans.

Questions & Contact

If you have any questions or concerns about the process, drop us an email or ping roguelynn or estherbester in the #pyladies channel on Freenode!

Current Organizers

Current Organizers

Event Hosting

Event Ideas

By Barbara Sharette

Ideas for meeting spaces/venues
  • Local tech company spaces - ask people you know who work there, or ask your own employer if there’s a meeting space you can use. Don’t be afraid to find local Python companies and cold-email a public email address!
  • For companies willing to let you use their meeting spaces, offer them the chance to do a hiring spiel to open the meeting.
  • Check with the organizers of other tech meetup groups for venue ideas.
  • Contact local hacker spaces
  • Contact local coworking spaces
  • Contact your local university’s CS department
Meeting ideas
  • Workshops with themes/goals (e.g., one workshop on how to build a small webapp, another one where you try to use python to solve some brainteasers)
  • Hold a small competition for your group where there’s a goal and you split into two teams and try to solve a problem faster, or better (performance, speed, etc.).
  • Beginner Python and Git classes
  • Get involved with hack days with other local user groups
  • Brainstorm ideas for group projects, so that you have a collection of specific projects to work on for hack nights.
  • Leverage Google Hangout to offer support to existing members on matters that hinge more on conversation than on in-person hacking (e.g., PyLadies recently hosted a hangout to chat about the PyCon call for proposals)

More event ideas can be found here!

Getting the word out
  • Email the organizers of other tech meetup groups to ask them to help advertise your event.
  • Put posters up at universities, or contact the CS student society. Ask the department secretary to contact grad students.
  • Partner with other groups for jointly hosted events
  • Get business cards to hand out at events
  • Set up a Twitter account

More details on how to promote your events here!


By Barbara Sharette

Finding Sponsors/Raising Funds

If your group is small, you don’t necessarily need sponsors. Hosting meetups at coffee shops, restaurants, or people’s houses is fine.

However, you may want to organize trips, conferences, and other types of more costly events. If so, you will need to raise local group funds and ask local Python shops to consider sponsoring an event.

Venue Sponsors

Research local companies and approach them. Often, a company that already hosts other meetups will be willing to host your PyLadies group. Ask them if they’ll provide pizza/drinks; if not, charge attendees a fee that covers food (and more, if you want to use the funds for future events).

Fiscal Sponsorship from the PSF

The Python Software Foundation has been very supportive of PyLadies. They have a special donation page, where donors can use PayPal to make donations directly to the PSF that are tax-deductible, which can then be used to reimburse PyLadies organizers who pay for various event costs.

PSF Grant Programs

See our sample PSF grant proposal to raise money for t-shirts, tables, and chairs.

You can apply for a Python Sprints grant to raise money for food, power strips, name tags, and anything else you might need to run a sprint/hackathon, up to $300:

Selling t-shirts/merchandise

Some PyLadies designs and printing instructions are provided with this kit. The cost is roughly $500-750 for 60 shirts. Shirts can be sold for $20 each (you can adjust the price to meet your needs/currency, of course).

See the “T-Shirts, Stickers, and Other Merchandise” section for more details.

Corporate sponsorship

Many companies are looking for ways to give back to the developer community. You’ll want to put together a corporate sponsor info packet.

See our sample info packet at upload sponsorship doc to git repo. Borrow ideas from it, and customize it to fit your group.




One benefit of creating a PyLadies local group is having access to a worldwide support network of PyLadies who can help you spread word about your events.

How to promote your events locally

Do the following:

  1. Post an event description on your page or website.
  2. Announce the event via your mailing list.
  3. Create event flyers and distribute them at meetups, Python user group meetings, work, and the local universities. See [upload example or template to git repo] for an example.
  4. Approach the career offices and engineering/science departments of local colleges and universities.
  5. Contact old professors and teachers. Tell them about what you’re doing; they’ll be glad to hear from you. Ask to make an announcement to their current students at the start of their classes, or as an email.
  6. Attend local tech/Python meetups. Be an active part of the local developer community. Show that you care about getting more women into Python development and programming in general. Be humble and ask for help from the group.
How we can help

Email the main point of contact for any of the following channels, and provide text and/or images for us to use:

  1. Global PyLadies Newsletter: Good for announcements about meetups. Subscribers from all over the world. Please keep the text brief and include an image. (
  2. PyLadies blog: we would love for you to contribute posts to our blog! It’s as simple as forking and then making a pull request off

In addition, promote all of your events directly through the following: 6. PyLadies Google group: 7. #pyladies IRC channel (FreeNode)

Whenever you have news of interest to the PyLadies community, all the above channels are available to help you make your announcement. We are always looking for good quotes and photos from Python developer women.

Guidelines for using the PyLadies promotion channels

Anything of interest to women in the Python community can be posted in the various PyLadies channels, provided that it meets these guidelines:

  1. Send us the actual text that you want posted.
  2. For local PyLadies local group events:
    • Send text for as many events as possible to the channels listed above. The more we can promote your events, the better.
  3. For non-local-group events and general postings:
    • Postings should be relevant to women. Mention the women organizing and/or attending the event. Have their names link to their websites or Twitter accounts.
    • Don’t just reuse the same blurb that you use everywhere; customize it to be relevant to the specific audience you’re addressing.
    • We’d love to use the various channels to feature what PyLadies from everywhere are doing. If you know of someone who should be featured, you can write up something interesting for the blog, Twitter stream, etc.
    • If you are hosting a Python community event or conference and need our help getting more women to attend, submit proposals, etc., a heartfelt explanation about why more women should attend and feel welcome goes a long way. A PyLadies discount code also helps: keep in mind that a huge part of our audience are students/those just starting out professionally with Python, who cannot afford to commit to events or submit proposals unless there is a known, guaranteed PyLadies discount.
Event Hosting Resources
Dealing with volunteer/organizer burnout

Organizing a PyLadies group is hard work, and no less for the people who volunteer to help out. burnout is a page to help recognize and deal with signs of burnout.

Dealing with unwelcome people

Some people are jerks. It can be difficult to handle situations in which an unwanted person attends events, or otherwise is not a supporter of PyLadies. Check out Responding to CoC Violations on how to handle people that violate the PyLadies Code of Conduct. Don’t be afraid to ask someone to leave the event (or request the venue host to act as a “bouncer” for you). And if that person refuses, please feel comfortable/empowered to call local authorities requesting for help.

Admin Stuff

Developing on the Global PyLadies Website
Setup your Machine

To make any changes, let’s setup your machine first.

  1. Fork the pyladies/pyladies repository to your own (or your local PyLadies) GitHub account.
  2. Locally clone your fork of the repository.
  3. Create a new virtualenv. Within that virtualenv, run pip install -r requirements.txt.
Adding your Location

Nearly all locations are listed on our locations page. To get listed on there, you must put it there. :-)

  1. Setup your machine following the Setup your Machine instructions above.
  2. Within the www directory, make an edit to the config.yml file. More about the config.yml file structure below.
  3. Optional: If you don’t have a website setup yet, you can make a simple static page within www/locations/. Read Making a Simple Location Page for more information.
  4. Test your changes by running mynt gen -f _site && mynt serve _site (within the www directory).
  5. Commit the code locally, and push it up to your fork.
  6. Make a pull request against the pyladies/pyladies repository.
config.yml File

The config.yml file contains most (if not all) of the configuration for the main PyLadies website.


To make your location show up on our locations page, create an entry under chapters.


Please - maintain alphabetical order of the chapters listing!!

Here are the available configuration items you can set, and what they mean/show up as on the locations page.

A complete example:

- name: Austin, TX
  meetup_id: 5947662
  image: pyladies_atx.jpeg
  twitter: pyladiesATX
  meetup: pyladies-atx
      latitude: 30.2711286
      longitude: -97.7436995

Make sure a tick, - precedes the name: attribute (in yaml syntax, it symbolizes another item in a list).

It shows up on the locations page as its own little “card”:

Complete Example

required The name attribute sets the name to show up on the locations page. You can as verbose or minimal as you’d like:

Config: name

optional The meetup_id actually corresponds to the Meetup Widget on the website. The code for the Meetup Widget can be found here.

Config: meetup_id

optional The website attribute is the absolute URL for the location’s website, or the relative URL for your location’s page (e.g. atx for


If it is an absolute URL - e.g. it is not relative to the domain (e.g. but is a subdomain (e.g., the external_website attribute needs to be set to True.

Config: website

required if location has a subdomain A boolean flag (if not set, will default to False) for when the location has a subdomain.


required The image attribute is the filename of the location’s image that should be placed in the www/_assets/images/ directory. You can use a standard one that’s already in the repository, or adapt the logo to your location (see Logos).

Config: image

required The email attribute is the location’s email address.

Config: email

optional The twitter, facebook, google_plus, and github attributes are links to the location’s handle/account. You may set as many as you’d like, or none. If your group uses other social media accounts that you want to publish, please read Adding New Link Types.

Config: twitter

optional The meetup is the Meetup group’s URL name - the string that comes after If your group uses a different service than for event publishing (other than your own location’s website), please read Adding New Link Types.

Config: meetup

required The location attribute is a map of latitude and longitude. If this is set, it will add a pinpoint to the map at the top of the page. It will automatically pull in all the information, too.

Config: location
Making a Simple Location Page

Don’t have time to make your Creating your own Local Website? Not a problem - if you have a few minutes, you can make a simple “place holder” page.

For the sake of having an example, let’s say our new location is “Foo City”

  1. Create a directory within www/locations named after your location (this will be your URL path - e.g.
  2. Create a new index.html within the directory you just created.
  3. Copy & edit the following HTML/Jinja template to the index.html file.
{% extends "site.html" %}
{% block title %}PyLadies Foo City{% endblock %}
{% block content %}
    <section id="archive">
        <h1>PyLadies Foo City</h1>
                <ul class="social">
                        <h4><a href="{{ get_url("locations/foo") }}">Foo City</a> | <a class="social icon vcard" data-icon="&#59170;" href="" title"Contact"></a><a class="social icon twitter" data-icon="&#62217;" title="Twitter" href=""></a><a class="social icon location" data-icon="&#59172;" title="Meetup Link" href=""></a></h4>

{% endblock %}

Once your done, test how it looks (refer to Using mynt to see how). Then commit your code, push to your fork of the repository, then open a pull request! You can see what others have done within the www/locations directory as well.

Blogging or Writing a Resource for the Main Website

Want to write a blog post, or cross-post from your blog to PyLadies? Or perhaps you wrote an awesome resource about how to get the most out of your favorite text editor, or how to setup your development environment for Django? Fantastic!

Making a Blog Post

We accept posts (from anyone!) for the PyLadies blog. Here is a guest post that you should read as samples of what we’re looking for: Get the Most Out of Your Conference-Going Experience.


We’re looking for posts about Python and the ladies doing cool things with it. Our audience includes both experts and newer programmers. If you’re writing a more expert level post, consider pointing newer programmers to resources to get started with.


We reserve the right to decline posts, or work to improve the work of the post.


Cite your sources! Either link to them in your post, or the old-fashioned academic Chicago MLA style of “quoting someone’s work”(FooPyLady) with an entry for “FooPyLady” at the bottom of your post (or any other MLA styling).

Also Please include whether:

  1. You want to be noted as the author
  2. If so, what name you want to use
  3. If we can link to you somehow, either through Twitter handle, email, or website.

Anonymous submissions are fine.


Posts should be 500 words in length. If your post is much longer (thousands of words), consider whether it could be broken into two connected posts.


If you wish to include images, they must be 500 pixels wide or less. You must own the images you’re submitting, or they must be available under a Creative Commons license.

The Markdown syntax is a bit limiting when wanting to add style to the image. Therefore, if you want to add style to it (e.g. different alignment than default, add a border, rounded corners, etc.) then just write plain HTML inside your Markdown document.

<img src="{{ get_asset('images/foo.png') }}" width="400" class="my-foo-image" style="any extra styling"/>
Formatting the Blog Post File
  1. Write your guest post in Markdown and save it in the www/_posts directory.

    • Suggestion #1: for mac is created for Markdown - gives you a preview while you write
    • Suggestion #2: dillinger is a web app that provides a live preview when you’re writing in Markdown.
    • A cheatsheet for Markdown commands.
  2. The very top of the blog post needs the following (including the three dashes before and after the layout/title/tags):

layout: post.html
title: "Your title here"
tags: [list, of relevant, tags]
author: Name, or blank/none
author_link: Twitter/Blog/etc or blank/none
  1. Setup your machine by following the Setup your Machine instructions .
  2. Save the file in www/_posts.
  3. Test your changes locally. Start up mynt as per the instructions below.
  4. Make sure that your changes look good, and that there are no errors or formatting issues. If you find problems, stop mynt, make the changes, restart, and check the site again.
  5. Commit your changes, and push to your fork of the pyladies/pyladies repository.
  6. Create a pull request against the pyladies/pyladies repo.

When you submit a pull request, everyone with commit access for Pyladies will see it. You may also ping the organizers list for more eyes to review.

Writing a Resource

If you want to write your own resources, like Barbara’s beginner workshop notes or Juliana’s Mac setup, in addition to the headers for blogging, you will need to add more items in the header portion, like so:

layout: post.html
title: "Your title here"
tags: [list, of relevant, tags]
author: Name, or blank/none
author_link: Twitter/Blog/etc or blank/none
category: [resources, pyladies]

Notice that pyladies and resources are required in for category.

Once done, save it in www/_posts/ with the date and title in the name of the file, like so: The title portion of the filename, lynns-awesome-resource, will end up being the URL of the post, e.g.

Developing the Main Website

Is there some CSS inconsistency that’s bugging you? Is the site missing some accessibility? Want to add a new page or content? Cool! Here’s how to get started.


When changing the website or adding content - beyond adding your location information - it is a good idea to email the organizers list to ask for others’ feedback on your ideas, either before you start developing, or when you make the pull request.

Current Layout

The website lives in the pyladies/pyladies, as well as many locations’ websites, where www is the main website, and the other directories map to subdomains, more or less.

The website consists of just static HTML, CSS, and some client-side JavaScript. We use mynt to convert Markdown files into HTML files (using Jinja2 templates).

The general layout for the www directory:

├── _assets        # JavaScript, images/logos, fonts, and CSS stuff goes here
├── _posts         # these are the blog posts written in markdown
├── _templates     # these are the base templates that other things use.
├── about/         # any directory maps to a URL path, e.g.,
├── archives/      #     and contains its HTML Jinja template
├── blog/
├── CodeOfConduct/
├── config.yml     # configuration for the overall site
├── feed.xml       # RSS feed that is automatically generated
├── index.html     # HTML Jinja template for the main page,
├── locations/
├── resources/
└── sponsor/

When you first run mynt (detailed below), it will also create a _site directory, where the complete site will be living. This _site directory is not committed within the repository.


The HTML files here are just templates. You must first run mynt gen -f _site (detailed below) to generate the HTML to see what will be on the website.

Using mynt

mynt is a simple static site generator written in Python.

When you’ve added or edited content in any way, you can check out your changes by running the website locally. To do so:

  1. Set up your machine following the Setup your Machine instructions.

  2. With the activated virtualenv, make sure you’re in the www directory, then run:

    (env) $ mynt gen -f _site
    (env) $ mynt serve _site
  3. Copy the IP address provided once mynt has completed building the site. (It will say something like >> Serving at, then paste the IP address into the URL bar of a browser window and load it to view the site.

  4. To view any changes you make to the site code, type ctrl``+``c in the terminal to stop the local server, then run the two mynt commands from Step 2 again and refresh the browser window.


If you wish to run the mynt server (aka mynt serve _site) on a different port, use the -p option: mynt serve _site -p 5050.

The mynt gen -f _site “compiles” the Markdown files into the Jinja2 template files (and does some other linking magic for CSS, JavaScript, images, fonts, etc) and spits out the output into the _site directory. This is actually what gets deployed (but is not committed to the repo!).

The mynt serve _site command runs a simple HTTP server for you to view local changes.


TIP! If you are having to stop the server, make your changes, run the two mynt commands many times, try the following:

  1. Have two terminal windows/spaces open.

  2. In one terminal window/space:

    1. Move to the www directory, and then run mynt gen -f _site (with your activated virtualenv) just once.
    2. Then run mynt watch -f _site - mynt will then watch for any changes saved to the file and re-run mynt gen -f _site for you.
  3. In the other terminal window/space:

    1. Move into the www/_site directory.
    2. If running Python 2.x, run python -m SimpleHTTPServer 8080 (or whatever port you’d like)
    3. If running Python 3.x - to be honest, not sure if mynt supports running on Python 3, but if it does - run python -m http.server 8080
  4. Now whatever changes you make & save, you’ll just have to refresh your browser.

Creating your own Local Website

Ready to setup your location’s website? Great!

Domain Setup

Domain admins: currently Esther Nam and Lynn Root


Please DO NOT purchase your own separate domain!

We will easily setup a subdomain on the site for you (e.g. It’s also possible if you’d prefer to use the namespace (e.g. We can also do or too. Your choice!

If you are in a location that frequently uses other TLDs, e.g., please contact our domain administrators listed above.

Developing the Website

You have two options: a Static Website website, or a Dynamic Website website. Whichever you prefer! And you can switch over any time. It may be easier/quicker for you to start with a static website - then create a dynamic website when you have more time.

Static Website

A static website is just HTML, CSS, and client-side JavaScript (exactly like the current site is set up). It’s great if you don’t want a database or server-side logic; it’s really easy to maintain.

Current Examples

There are plenty of PyLadies locations that have simple static websites. Here are a couple:


If you’re interested in the various static website tools out there, check out Tools.

To setup your static website:

  1. Fork the pyladies/pyladies repository to your own (or your local PyLadies) GitHub account.
  2. Locally clone your fork of the repository.
  3. Create a directory within the main pyladies folder of the repository (on the same directory level as www and the other subdomains.)
  4. Develop the website within your new directory.
  5. Be sure to add a file that explains how to create the HTML files if you are using a static site generator (like here).
  6. Commit the code locally, and push it up to your fork.
  7. Make a pull request against the pyladies/pyladies repository.


When making a pull request, please squash all your commits into one commit! We like a clean history! Here’s a good how-to on git rebase to squash commits.


In your pull request - please include the desired subdomain namespace - e.g.


Be sure that the subdomain information in www/config.yml within the pyladies/pyladies repository matches the subdomain of your website! Lots of linking-magic goes on.


You can hand-write all your HTML files, but that’s a bit of a pain. Here are a list of tools that can help create your static website for you:


mynt is a static site generator written in Python. This is the tool that the main PyLadies site - uses.

You write the content of your site in Markdown format, design the layout and organization of the site (e.g. how the content will be presented) using Jinja2 templates (another Python library), and edit/create your own themes with CSS. Running mynt gen over your Markdown & CSS files and Jinja2 templates will create static HTML files that you can then view via the mynt serve command.


Extremely similar to mynt, pelican is another static site generator written in Python. It’s the same process - write in Markdown, organize via Jinja2 tempaltes, and edit your theme with CSS.

Pelican does offer a bigger user base than mynt, and therefore has many plugins and themes already setup to use.

Other Python Static Site Generators

Some others if you’re curious:

  • nikola
  • hyde
  • Frozen Flask
  • Sphinx (generally used for project documentation but can easily be used for this)
  • mkdocs (similar to Sphinx - generally used for project docs but easily used for this)
Other Non-Python Static Site Generators

It’s totally okay to use a non-Python package(s) to help make your website. Here’s a list of common & widely-used ones:

Dynamic Website

A dynamic website goes beyond simple HTML/CSS/JavaScript. A website written with Django or Flask is a dynamic website (and it’s okay if you want to use a non-Python web framework, so long as it’s supported by Heroku).

Current Examples

There are a few PyLadies locations that have built their own dynamic websites. Here are a couple:


If you’re interested in the various dynamic website frameworks out there, check out Frameworks.

To setup your dynamic website:

  1. Create your own git repository (ideally under your local PyLadies GitHub account, registered under your email address).
  2. Create your website.
  3. Create a free Heroku account with your PyLadies email address, if you haven’t already. Be sure to download the Heroku toolbelt for easy application setup and deployment.
  4. When you’re ready to deploy, ping the domain admins (above). They will set up your PyLadies email address to an admin-managed Heroku app (which will give your PyLadies complete access for deployment) as well as setup all the DNS records needed.
  5. Log into your Heroku account and follow the instructions for deploying (available under newly-created application that the admins made).


Global Organization

Global PyLadies Community

The global PyLadies community has no formal organization behind it; no board of directors, no appointed leadership. We found that PyLadies growth and success stems from being decentralized and non-bureaucratic.

We do have a few point people that can answer and address general, or non-location specific PyLadies questions. If you are not a local PyLadies leader, you may do so via our general email. If you are a local PyLadies leader, you may email our organizers list (must be added to the mailing list first).

Mailing List

We have a global mailing list in which anyone can join. Be sure to fill out the one request:

To be approved, please give a 1-5 sentence bio about yourself, how you heard about PyLadies, and/or how you use Python.

The mailing list is subject to the PyLadies Code of Conduct.


The Pyladies global newsletter is sent out as regularly as we can make it; all work is voluntary, and all information is volunteered! Everyone who subscribes via the email form on will receive the newsletter.


The editor of an upcoming issue of the PyLadies global newsletter might make an effort to gather info about all the local groups via a message to the organizers mailing list, but the onus is on each group’s organizer(s) to send any updates about a group to the editor if they want to be included.


If you’d like to volunteer to edit the next issue, all you have to do is shoot an email to the organizers mailing list! Warning: it’s a lot of work! We use Mailchimp.

PyLadies @ PyCon



We try not to have too many rules and regulations (everything else in this kit has been nothing more than advice we offer to make things easier for you, given that we learned much of it the hard way). Generally, local group organizers are free to do whatever they want, as long as it’s in the best interest of their local group and/or PyLadies in general.

The following policies have been written up so that you may simply copy and paste them into email responses, to help you deal with awkward or tricky situations.


PyLadies and the PyLadies logo are trademarks of the Python Software Foundation. For usage guidelines, please read PyLadies Logo Usage.

Code of Conduct

All PyLadies events (Meetups, conference lunches, etc), online spaces (IRC, Facebook, etc) are beholden to the PyLadies Code of Conduct.

Every PyLadies location is required to make Code of Conduct public in some way. For instance, PyLadies SF has a dedicated page on their Meetup space. The #pyladies IRC channel on Freenode has a link to the main website’s Code of Conduct in the topic of the channel.

Please read Responding to CoC Violations for how to appropriately deal with CoC violations.

Guest Policy

(If anyone asks to stay with you in the future other than a trusted friend, say something like “I wish we could accommodate you, but PyLadies has a strict policy of not allowing members to host out-of-town guests” and then paste this, minus the parenthetical note.)

In the interest of safety and security of our members, PyLadies organizers, volunteers, and members are not permitted to host overnight out-of-town guests who wish to visit town for PyLadies events.

This is a strict formal policy, chosen to ensure that the PyLadies organization continues to be taken seriously and treated with complete respect by the professional software and tech communities.

Controversial Issues

As a PyLadies local group organizer, you may be asked for PyLadies’ position on controversial issues. Often, these are diversity-related issues.

PyLadies’ policy is to have no official position on controversial issues. By choosing this policy, we allow ourselves to be a group full of diverse ideas and differing viewpoints.

Miscellaneous Helpful Stuff


Please read our logo usage policy, but in general, we want the logo to be used as widely as possible to indicate the support of or involvement with PyLadies. If you are a local PyLadies leader, you are free to adapt the logo to your location. (Non-leaders, please ask first when using a derived version of the logo or when in doubt).

TL;DR is that any of the graphics in our PyLadies assets repo can be used for your own group promotion and/or to show your support. You may also alter the PyLadies Wordmark or PyLadies Geek logo to adapt it to your location. Check out examples on our locations site.

Logos used with the intention to sell merchandise, please seek permission from the PyLadies leadership to help setup.

There is “official” merchandise sold - with proceeds going towards PyLadies - at our own spreadshirt site. It’s probably better to go with a bulk t-shirt printer if buying more than a few t-shirts though. You’re free to choose a printer that you like or that may be local. We’ve had good luck with Elegant Stitches (who printed the PyCon 2015 t-shirt) and Custom Ink.

Swag: T-Shirts, Stickers, and Other Merchandise

Currently, T-shirts are available via Spreadshirt. Proceeds from the shop benefit the PyLadies organization and go toward things like nonprofit corporation setup, helping new local groups, servers, etc.

Sometimes we also create limited runs of T-shirts, stickers, etc. Check the blog or ask around in IRC #pyladies if you’re interested in seeing what we have.

Local group merchandise

If you’d like to create merchandise for your own local group, you can create a shop on Spreadshirt, Zazzle, or any other print-on-demand site and have the proceeds go toward your local group.

Or you can have a local print shop print a small run.

Difficult Stuff

Code of Conduct

All PyLadies events (Meetups, conference lunches, etc), online spaces (IRC, Facebook, etc) are beholden to the PyLadies Code of Conduct.

Every PyLadies location is required to make Code of Conduct public in some way. For instance, PyLadies SF has a dedicated page on their Meetup space. The #pyladies IRC channel on Freenode has a link to the main website’s Code of Conduct in the topic of the channel.

Please read Responding to CoC Violations for how to appropriately deal with CoC violations.

Responding to CoC Violations

As a PyLadies organizer, you may get reports of harassment or other Code of Conduct Policy violations. It can be confusing and stressful to deal with. But have no fear! Adapted from Geek Feminism, we have some guidelines.


You and any co-organizers should be prepared in case someone wants to report harassment that they’ve face. Here are some suggestions to help you prepare for the process if a report ever happens, however feel free to adapt them as you wish.

List of emergency resources

This is good for both you/organizers in case a incident is beyond your capability to appropriately deal with, and for the reporter of harassment to use if they wish. Suggested resources include:

  • Local emergency services (police, ambulance, etc). It’s good to have both emergency phone numbers and non-emergency phone numbers.
  • Local mental health services
  • Sexual assault hotlines
Record Keeping

You have the ability to use Google Drive with your account (please don’t polute your personal Google drive!). Just log into with your PyLadies email login information. With that,

  • Create a form (e.g. with Google Forms) that allows someone to report the incident online. See Receiving a Complaint for what details to collect. An example form can be found here.
  • Publish the form within your location’s page (e.g. local Meetup page, website, Facebook) as well as emailed out when it initially is published.
  • Publish contact information (e.g. your location’s email) in case they wish to not fill out the form or want talk to someone directly.
  • Set up email notifications for any form response so you don’t miss anything
  • Create documents for any notes that you/the organizers take, write down any actions took and the resolve, any email conversations. Anything that is done in relation to the incident should be documented.
  • It may be a good setup to create folders per incident. Then you can just upload PDF printouts of email conversations, or quickly write notes about conversations.

The purpose of maintaining a “paper trail” is:

  • If you step down as an organizer, or another organizer receives a complaint regarding a previous offender, it can be dealt with in a more appropriate manner, and
  • Maintain a record in case local authorities ever get involved.
Informing PyLadies Global

If an incident happens in your local PyLadies community, you must report it to the global organization via our CoC reporting form. The purpose is very similar to Record Keeping - for the global organization to be aware of what’s going on in case of any legal or PR action is needed/taken, as well as look for a pattern of behavior (e.g. a repeat harasser moves locations, if a community is particularly unwelcoming and may need more help).

You are of course welcome and invited to request help from the global PyLadies organization. We are here for resources, advice, or just to talk to.

The global organization is also responsible for complaints of local organizers. If you received or witnessed unwanted behavior in any way that breaks our Code of Conduct Policy by another organizer, please do not hesitate to contact us. You may report any violations via our global report form, or contact us at

The following people maintain any Code of Conduct Policy reports:

If you do not feel comfortable with anyone above when sending a report (e.g. the report is against someone above), please reach out to someone else on the above list.

Receiving a Complaint

Ask the reporter to write down what happened to the best of their ability. If the report was given verbally or does not want to, then please write down the complaint yourself (see Record Keeping).

We suggest the following:

  • Identifying information of the participant doing the harassing
  • The behavior that was in violation
  • The approximate time of the behavior (if different than the time of the report was made)
  • Any circumstances surrounding the incident
  • Other people involved in the incident
  • If they wish to remain anonymous in any way
  • How you can contact them for follow up

We suggest to have a designated person (not the whole group of organizers) to handle the conversation between the involved parties and the local group. This is to avoid the “group against one” environment, as well as “interviewing” or otherwise “evidence gathering”.

Make it known to the parties involved about who is a part of the group that addresses these complaints (if it’s just you, or other organizers will be brought in to discuss how to handle the complaint), and that you will be documenting the report and the response

Responding to a Complaint

There are various levels of responses depending on the incident. Please follow accordingly:

Threats to Physical Wellbeing

Most harassment complaints aren’t of this nature, but if someone reports that an attendee has committed or is threatening violence towards another attendee, or other safety issues:

  • If there is any general threat to attendees or the safety of anyone including conference staff is in doubt, summon security or police.
  • Offer the victim a private place to sit
  • Ask “is there a friend or trusted person who you would like to be with you?” (if so, arrange for someone to fetch this person)
  • Ask them “how can I help?”
  • Provide them with your List of emergency resources if they need help later
Law Enforcement

If everyone is presently physically safe, involve law enforcement or security only at a victim’s request.

In many cases, reporting harassment to law enforcement is very unpleasant and may result in further harassment. Forcing victims to go to law enforcement will reduce reports of harassment (but not actual harassment). For more information, see Why Didn’t You Report It?

An organizer can provide the List of emergency resources and say something like “if you want any help reporting this incident, please let us know” and leave it at that.

Reports of Harassment that were Widely Witnessed

These include things like harassing content in talks, or harassment that took place in a crowded space.

Simply say “Thanks, this sounds like a breach of our Code of Conduct Policy. I am going to convene a meeting of a small group of people and figure out what our response will be.”

Reports of more private harassment

Offer the reporter/victim a chance to decide if any further action is taken: “OK, this sounds like a breach of our Code of Conduct Policy policy. If you’re OK with it I am going to convene a meeting of a small group of people and figure out what our response will be.” Pause, and see if they say they do not want this. Otherwise, go ahead.

Things not to do
  • Do not overtly invite them to withdraw the complaint or mention that withdrawal is OK: this suggests that you want them to do so, and is therefore coercive. “If you’re OK with it [pursuing the complaint]” suggests that you are by default pursuing it and is not coercive.
  • Do not ask for their advice on how to deal with the complaint: this is the staff’s responsibility
  • Do not offer them input into penalties: this is the staff’s responsibility
  • Do not share details of the people involved or incident without specific permission from the victim. This includes sharing with other organizers (unless they are a part of your group to respond to incidents.
Forming a Response

You should aim to take action as soon as reasonably possible. During the event, a response within the next half-day is usually an appropriate timeframe. After the event you may need more time to gather sufficient decision makers, but ideally responding within the same week or sooner is good.


Available co-organizers should meet as soon as possible after a report to discuss:

  • What happened?
  • Are we doing anything about it?
  • Who is doing those things?
  • When are they doing them?

Neither the complainant nor the alleged harasser should attend. (If the event was very widely witnessed, such as a harassing talk, this may be an exception to this guideline.) People with a conflict of interest should exclude themselves or if necessary be excluded by others.

Communicate with the alleged harasser about the complaint

As soon as possible, either before or during the above meeting, let the alleged harasser know that there is a complaint about them, let them tell someone their side of the story and that person takes it into the meeting.

Communicate with the harasser about the response

As soon as possible after that meeting, let the harasser know what action is being taken. Give them a place to appeal to if there is one, but in the meantime the action stands. “If you’d like to discuss this further, please contact XYZ, but in the meantime, you must <something something>”

Possible sanctions

Your guiding principle should be the safety of your community members from harassment and you should evaluate sanctions in light of whether they provide the safety needed. You and your event are the only people who can judge appropriate sanctions in your community based on the nature of the incident and the responses of the people involved, but some possibilities are:

  • Warning the harasser to cease their behaviour and that any further reports will result in sanctions
  • Requiring that the harasser avoid any interaction with, and physical proximity to, their victim for the remainder of the event
  • Ending a talk that violates the policy early
  • Not publishing the video or slides of a talk that violated the policy
  • Not allowing a speaker who violated the policy to give (further) talks at the event
  • Immediately ending any event volunteer responsibilities and privileges the harasser holds
  • Requiring that the harasser not volunteer for future events your organization runs (either indefinitely or for a certain time period)
  • Requiring that the harasser refund any travel grants and similar they received (this would need to be a condition of the grant at the time of being awarded)
  • Requiring that the harasser immediately leave the event and not return
  • Banning the harasser from future events (either indefinitely or for a certain time period)
  • Removing a harasser from membership of relevant organizations
  • Publishing an account of the harassment and calling for the resignation of the harasser from their responsibilities (usually pursued by people without formal authority: may be called for if the harasser is the event leader, or refuses to stand aside from the conflict of interest, or similar, typically event staff have sufficient governing rights over their space that this isn’t as useful)
Employer reports

If someone harassed someone else while in an official employee capacity, such as while working as paid event staff, while giving a talk about their employer’s product, while staffing a sponsor booth, while wearing their employer’s branded merchandise, while attempting to recruit someone for a job, or while claiming to represent their employer’s views, it may be appropriate to provide a short report of their conduct to their employer.

Don’t require or encourage apologies

We do not suggest asking for an apology to the victim. You have no responsibility to enforce friendship, reconciliation, or anything beyond lack of harassment between any two given attendees, and in fact doing so can contribute to someone’s lack of safety at your event.

Forcing a victim of harassment to acknowledge an apology from their harasser forces further contact with their harasser. It also creates a social expectation that they will accept the apology, forgive their harasser, and return their social connection to its previous status. A person who has been harassed will often prefer to ignore or avoid their harasser entirely. Bringing them together with a third party mediator and other attempts to “repair” the situation which require further interaction between them should likewise be avoided.

If the harasser offers to apologize to the victim (especially in person), we suggest strongly discouraging it. If a staff member relays an apology to the victim, it should be brief and not require a response. (“X apologizes and agrees to have no further contact with you” is brief. “X is very sorry that their attempts to woo you were not received in the manner that was intended and will try to do better next time, they’re really really sorry and hope that you can find it in your heart to forgive them” is emphatically not.)

If the harasser attempts to press an apology on someone who would clearly prefer to avoid them, or attempts to recruit others to relay messages on their behalf, this may constitute continued harassment.

Data retention

Build a data retention policy for various information related to harassment policies. In particular, an anti-harassment policy that states that sufficiently bad offenses can earn a lifetime ban from the event should have a data retention plan that includes how to store and communicate offenses from past events to the staff of future events, for the lifetime of the organization.

Things to think about:

  • What gets stored?

  • How is it stored? (Paper is less searchable than electronic records.)

  • Who has access to it?

    • Who is allowed to have access?
    • How is that access controlled?
  • How is it communicated to future staff?

  • How long are the stored records kept?

    • Is there a difference in how long different types of records need to be kept?
  • At what point in the registration process does someone check against records of banned attendees?

Communicating with your community

Your community may need to see the policy enforced because:

  • you want to be transparent to your community and not have secret policies and sanctions that you aren’t accountable for
  • the actions of the harasser, or reports of multiple harassment, show that your policy may not be well understood
  • you wish to reassure people that you are serious about anti-harassment
Level of detail

When discussing the incident with others, it is good to keep the individuals anonymous, generally. (An exception may be if the harasser is very central to the community, such as a core conference staffer.) However, it is useful to:

  • offer some idea of the nature of the incident eg “a sexual slide was shown in a talk” or “an attendee physically threatened another attendee” or “an attendee repeatedly harassed another attendee despite multiple requests to cease” or whatever.
  • briefly mention the sanction
  • (briefly! neutrally!) convey any apologies from the harasser, especially if they were backed by actions, for example “the [attendee/speaker/staffer] has agreed that their actions were inappropriate and has voluntarily left the conference”

This helps your community understand the reality of the policy: how and when it gets enforced.

Informing attendees

If the event has been dealt with at the conference, it may be appropriate for the conference to make a short announcement at the next plenary, something like:

“<thing> happened. This was a violation of our policy. We apologise for this. We have taken <action>. This is a good time for all attendees to review our policy at <location>. If anyone would like to discuss this further they can <contact us somehow>.”

And then move on with the program.

Dealing with upset attendees

People may be upset and wish to express their concerns to conference staff. Conference staff should be in “making the person feel heard” mode, it’s important not to cross into education mode. Hear them out, take notes as approriate, thank them for their thoughts.

Conference staff should not share additional details of the incident with uninvolved parties.

If an attendee are upset and a staff member agrees that a wrong was done to them, it helps a lot to just say simply “I’m so sorry.” (Rather than “but we tried really hard” or “no one told us” or etc, even if that was true. “I’m so sorry” goes a long way to defusing many people’s anger.)

Whether or not a staffer agree that a wrong was done to them them, they should be armed with an authority they can appeal to if talking wasn’t enough. “Please email our conference director.” “Please email our committee.” etc.

Public response

Some incidents of harassment will need a public response after the conference in order to protect the reputation of your awesome, friendly, professional conference. Be prepared and willing to distance your conference from actions of participants that reflect badly on your conference, and to defend your action or inaction in response. Nobody likes being the bad guy, but even fewer people like going to a conference when the organizers seem to condone bad behavior, whether the reputation is for punishing the people reporting it, ignoring it, or enforcing an existing policy unevenly (someone with no connections getting the harshest possible penalty, someone with intimate connections to the organizers getting off lighter than the stated policy).

Timing is important. Try to respond quickly to harassment incidents. A late response looks a lot like no response at all and can harm your conference’s reputation and future attendance. A simple and relatively uncontroversial response with few legal concerns is to issue a general statement about the kind of behavior involved:

“PyLadies does not condone $BEHAVIOR. $BEHAVIOR violates the anti-harassment policy of PyLadies, which specifies that participants engaging in $BEHAVIOR will be expelled from the conference. We take harassment seriously and respond to reports of it quickly and firmly.”

After you have had a chance to observe how the anti-harassment policy works in the real situations presented by your conference, you may wish to change the policy to better address them. Did anything unforseen happen that there should be a rule about? Sometimes an unacceptable behavior does not warrant a whole new rule, but should be listed as a specific example of unacceptable behavior under an existing rule.

For consistency, it is wise to deal with situations that came up at this year’s conference under this year’s rules, and only apply any changes going forward to the next conference.

Resources for dealing with volunteer burnout

Organizing a PyLadies group is hard work, and often under-appreciated. Here are some ways to recognize the signs of burnout, and ways to prevent, deal with, or otherwise alleviate it.

Causes of Burnout
  • Your group may be growing faster than anticipated.
  • Your passion for the community comes with an inability to say no when asked to do things.
  • It’s exhausting to be “on” for so long – from the preparation leading up to an event, to organizing and interacting with all the people who come to the event, to following up with folks afterward.
Signs of burnout
  • You begin dropping the ball here and there because you’ve overcommitted to things.
  • You begin to dread planning or attending events.
  • Relationships between organizers deteriorate.
  • Your initial feeling of goodwill toward attendees begins to sour.
Ways to prevent burnout
Running your Group
  • Find co-organizers to help shoulder the burden. We all have different skills, strengths, and weaknesses.
  • Ask participants to be mentors to beginners. Even beginners can step up to deal with non-technical aspects of an event. This can also make things more fun, and helps build community.
  • If people demand even more of you than what they’re getting, politely remind them that we don’t get paid for this, and that organizers lead very busy lives. Suggest that person step up and organize something themselves.
  • Scale back your involvement to a level you find sustainable over the long term.
  • Take a break altogether.
Taking a break

It’s completely okay to stop your involvement for a time. Everyone would prefer that you take a breather if it meant you could come back refreshed and ready to pick things up again.

  • Have variety! Try different speakers, different topics, difference venues. Intersperse large events with simpler, informal ones. Lightning talks help break things up.
  • Work with other groups in your community, ask them to lend a hand with things from time to time.
Coping with burnout
If you notice someone seems to be burning out
  • Meet with them, outside of an official event, in a relaxed environment. Learn how they are feeling, work with them to determine how to deal with it if they are burning out.
  • Let them take a breather and leave them the option to leave permanently without guilt.
If you are feeling burnt out
  • Know that you are not alone. This stuff is hard, and it’s hard to do for a long time.
  • It’s ok to ask people to step up and help more.
  • Reach out to other PyLadies group organizers.
  • Again: It’s ok to take a break.
Why are you here?
  • Think about your personal goals and how your work is helpign you achieve them. Also think about how your goals might be better achieved if, in the long term, you maanged to avoid burning out.
  • It’s really rewarding to help women both learn Python and find their place in the larger community, but it’s really hard work.
  • There’s more support in your group than you might guess. People will want to help you out if they can.
  • Self care is important, perhaps most important.

    In particular, in times of stress, illness, or sleep-deprivation, remember to take the time to show compassion and care for yourself.

  • People are human.

    We all get sick, overwhelmed, forgetful, and make mistakes at times. Try to remember and embrace these as the “oh, goodness” moments of volunteering.

  • “Hello, Murphy. Welcome.”

    Murphy’s Law (Source: Wikipedia. an adage or epigram that is typically stated as: Anything that can go wrong will go wrong.) pops up in the most unexpected times and places. Accept Murphy works in mysterious, unpredictable ways. A sense of humor, humility, and resourcefulness are crucial to effective community organizing.

PyLadies Members

Member Reference


About PyLadies

We are an international mentorship group with a focus on helping more women become active participants and leaders in the Python open-source community. Our mission is to promote, educate and advance a diverse Python community through outreach, education, conferences, events and social gatherings.

PyLadies also aims to provide a friendly support network for women and a bridge to the larger Python world. Anyone with an interest in Python is encouraged to participate!

Joining PyLadies

Want to join PyLadies? Fantastic! But I hate to break it to you, you already are one ;-).

Finding your local PyLadies

We (try to) maintain a list of PyLadies locations, but it may not be complete or up-to-date as every location is reponsible for updating & maintaining their location’s information.


If you believe that there is a location not shown on our locations page, please feel free to ping the organizer (if you know them), file an issue or submit a pull request with the relevant information!

Once you find your location, go ahead and join their group (if they have one), and join/follow any social media accounts they have.

Remote PyLadies

We can’t be everywhere. But we’re trying! For those who do not have a PyLadies group within a reasonable distance (or even if you do!) we have an online PyLadies group called Remote PyLadies! Events are held by local organizers through online streaming/coding/etc tools and posted on the Remote PyLadies site.

Want to volunteer?

Often times, our organizers - both local & remote - need help. Whether it’s mentorship for events, logistic help (e.g. a door woman). Don’t be shy in reaching out to them! Their contact information should be listed on our locations page. But if you’re having trouble, please feel free to ping us for introductions.

Difficult Stuff

While we all strive to be awesome, sh*t happens. Please have a read of the following resources:

PyLadies Code of Conduct

All PyLadies events (Meetups, conference lunches, etc), online spaces (IRC, Facebook, etc) are beholden to the PyLadies Code of Conduct Policy.

Every PyLadies location is required to make Code of Conduct Policy public in some way. For instance, PyLadies SF has a dedicated page on their Meetup space. The #pyladies IRC channel on Freenode has a link to the main website’s Code of Conduct in the topic of the channel.

If you can not find the following Code of Coduct posted somewhere (e.g. wherever they post events), please reach out to your locations’ organizers.

Code of Conduct Policy

Pyladies is dedicated to providing a respectful, harassment-free community for everyone. We do not tolerate harassment or bullying of any community member in any form. This does not only extend to members to local PyLadies communities, but to anyone who chooses to become involved in the larger PyLadies community of users, developers and integrators through events or interactions.

Harassment includes offensive verbal/electronic comments related to personal characteristics or choices, sexual images or comments in public or online spaces, deliberate intimidation, bullying, stalking, following, harassing photography or recording, sustained disruption of talks, IRC chats, electronic meetings, physical meetings or other events, inappropriate physical contact, or unwelcome sexual attention. Participants asked to stop any harassing or bullying behavior are expected to comply immediately.

If a participant engages in harassing behavior, representatives of the community may take reasonable action they deem appropriate, including warning the offender, expulsion from any PyLadies event, or expulsion from mailing lists, IRC chats, discussion boards and other electronic communications channels to resolve the issue. This may include expulsion from PyLadies Meetup group membership.

If you are being harassed, notice that someone else is being harassed, or have any other concerns, please act to intercede or ask for help from any member of the PyLadies community, IRC chat admins, website admins, or organizers/representatives of any physical events put on under the auspices of PyLadies.

This Code of Conduct has been adapted from the Plone Foundation and is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported license.

Reporting Harassment

People can be jerks. Sh*t can happen. PyLadies wants to provide a safe space for its members, so we’ve written this document to help those who experience harassment within the PyLadies community.


You are not obligated to report harassment that you’ve faced, or witnessed! But we hope to provide mediums in which you feel comfortable doing so.

Who to Talk to

If you’ve faced harassment or witness an event attendee or someone within a PyLadies chatroom, we encourage you to report what you saw to an organizer, chat operator, or whomever is in charge of the space. For instance, if the incident was during a local PyLadies Meetup event, reach out to the organizer(s) of that specific event. If the incident was within the #pyladies IRC channel, please privately message the operator of the channel, currently @roguelynn (a.k.a. Lynn Root). You can also hop into the #pyladies-support channel for “live” discussion too.

If you can not find whomever is in charge with the PyLadies space, do not feel comfortable talking to them, or you wish to report a leader: please feel welcome to email us. The following PyLadies organizers are behind the Code of Coduct contact:

If you are not comfortable with one or more of the leaders above, please feel welcome to reach out to an individual above that you are comfortable with.

Harasser has relationship with venue/sponsor

If the harasser is an employee - or has an established relationship in some way - of the venue host or event sponsor, in addition to contacting a PyLadies leader above in some form, please feel empowered to reach out to the employer or whomever is responsible for the harasser.


The following is adapted from the Geek Feminism Wiki (such a great resource!).

How to Report

We suggest that your report have two key things:

  1. a clear description of the harassment
  2. a statement of what it is you want the contact to do about the harassment

This makes it less likely that they will not understand, or pretend to not understand, that you want action taken. It also creates some evidence that they were asked to act, so that they cannot claim later that there was no specific thing they were supposed to do. Occasionally also someone is under specific instructions to not do anything about complaints without a specific call to action.

Other useful things to include:

  1. evidence, such as copies of harassing emails or letters, dates of phone calls or in-person actions

You may wish to store both copies/records of harassing contact and of complaints you made.

Sample Written Report

Dear <NAME>,

I wish to report that I was harassed by <NAME/EMAIL/HANDLE>, who <MANNER OF HARASSMENT>. [Optional: This harassment has had <EFFECT ON ME>.] Since you have <RELATIONSHIP WITH HARASSER>, I request that you take the following action:


[Optional: I request that you treat this complaint in confidence and not reveal identifying information about me to <HARASSER> or <SOME OTHER PEOPLE>.]

[Optional: I have already separately reported this harassment to <OTHER AUTHORITY> and they have taken <ACTION>.]

[Optional: a fuller account of their harassment/emails with full headers follows.]


Example Actions to Request

When reporting the incident, depending on your level of comfort and the level of severity, some example actions you may want to ask of us:

Meetup/In person organzied event
  • develop and enforce anti-harassment policy for your event
  • confirm whether or not <HARASSER>‘s behaviour violates existing anti-harassment policy
  • tell <HARASSER> to stop harassing people at this event
  • ask <HARASSER> to cease attempting to interact with me at this event/
  • record <HARASSER'S> behavior for monitoring
  • remove <HARASSER> from their position among the event organizers/staff/volunteers
  • ask <HARASSER> to leave the event
  • ban <HARASSER> from future events
  • assist me in referring <HARASSER>‘s actions to law enforcement
Online services (IRC, forums, etc)

PyLadies has an official IRC channel (#pyladies on Freenode), a Reddit subreddit (/r/pyladies), and a Google+ community. For those, you may contact the admin(s) or moderator(s) of such services, or reach out directly to us. There are many online groups that PyLadies organizers have for location-specific groups, in which contacting the admin(s)/moderator(s) or the contact email listed on our locations page may be best (you are still free to contact the main email as well!)

Example actions:

  • develop and enforce anti-harassment policy on your service
  • confirm whether or not <HARASSER>‘s behaviour violates existing anti-harassment policy
  • tell <HARASSER> to stop using this service to harass people
  • make <HARASSER> invisible to me, so that I cannot see their messages, whether public or private
  • monitor <HARASSER>‘s postings for threats
  • deregister/block <HARASSER> from using my part of this service, or give me instructions on how to do so (a particular forum or chat room, say)
  • deregister/block <HARASSER> from using this service
  • provide me/law enforcement with identifying information about <HARASSER>‘s account
  • assist me in referring <HARASSER>‘s actions to law enforcement
Other Avenues

PyLadies can only do so much, but there are other people and avenues to talk to where PyLadies may fall short. We also encourage our leaders to reach out to our contacts (e.g. an event host) to work towards making a better environment for our event space.


If the harrasser is an employee of a PyLadies venue host or sponsor, please feel comfortable in reaching out to their employer. You might consider reporting to the harasser’s employer if:

  • you are being harassed using company resources, such as from a work email address, fax machine or telephone number
  • the harasser claims that their actions were encouraged by their employer, such as being a marketing ploy or a customer outreach activity
  • you are being harassed by someone acting as a representative of their company, such as someone who is attending an event and wearing badges or distributing business cards with the company’s name on it or soliciting business for the company
  • you are being harassed privately by someone whose job requires them to maintain good public standing or who wields a great deal of authority in their job, such as an employee of a feminist organisation, a politician, a police officer, a doctor or a lawyer. For many professions you may be able to look up their professional ethics standard and find out if their behaviour outside of work is governed by their professional affiliation.

Possible actions to request:

  • tell me whether or not the actions of <HARASSER> were authorised or approved by your organisation
  • confirm whether or not <COMPANY> has policy that prohibits <HARASSER>‘s behavior
  • confirm for me that you will speak with <HARASSER> and make it clear to them that their behaviour is unacceptable and must stop immediately
  • immediately provide me with a new contact/account manager at <COMPANY>, as I cannot do business with <HARASSER> any longer
  • terminate my account with <COMPANY> effective immediately (obviously, this will depend on contracts you have in place)
  • do not allow <HARASSER> to represent <COMPANY> in this capacity again as <HARASSER> is harming your company’s image
  • re-consider <HARASSER>‘s employment with your company
  • assist me in referring <HARASSER>‘s actions to law enforcement
Professional Body

This might be, for example, a medical registration board, or the bar organisation for lawyers. You might consider this if your harasser is an individual who has a professional membership that governs their private behaviour. You may possibly also do this if your harasser is about to join such a profession (eg. they are a medical student).

Possible actions to request:

  • confirm whether or not <HARASSER>‘s behaviour violates your ethical code
  • confirm for me that you will sanction <HARASSER> according to your profession’s standards (you might make specific reference to their ethics code if you have read them)
  • open disciplinary proceedings against <HARASSER> to consider their deregistration from <PROFESSION>
  • do not allow <HARASSER> to register as a practising member of <PROFESSION>
  • assist me in referring <HARASSER>‘s actions to law enforcement
Educational Institution

Much as in the case of an employer, in some circumstances you might choose not to involve an educational institution in a student’s external activities. But again there are some circumstances where you might consider it:

  • you are being harassed using institutional resources, such as a institutional email address, fax machine or telephone number
  • the harasser claims that their actions were encouraged by their institution, such as claiming that the actions are part of a research study or project for assessment
  • you are being harassed by someone acting as a representative of their institution, such as someone attending or speaking at a conference in their role as a researcher

Possible actions to request:

  • tell me whether or not the actions of <HARASSER> were authorised or approved by your organisation
  • confirm whether or not <HARASSER> has ethics approval for this research [or assessment]
  • give me the contact details of the project’s chief investigator [or the course’s teacher] and <INSTITUTION>‘s ethics review board so that I can ask that <HARASSER>‘s project be reviewed
  • confirm whether or not <INSTITUTION> has policy that prohibits <HARASSER>‘s behaviour
  • confirm for me that you will speak with <HARASSER> and make it clear to them that their behaviour is unacceptable and must stop immediately
  • do not allow <HARASSER> to represent <INSTITUTION> in this capacity again as <HARASSER> is harming your institution’s image
  • re-consider <HARASSER>‘s enrolment with your institution
  • assist me in referring <HARASSER>‘s actions to law enforcement
Internet Service Provider

In the case where the harassment is occurring online service, you may be able to trace the harasser via email address or IP address to a particular ISP.

ISPs typically do not heavily police the actions of their users and may refuse to assist you unless law enforcement is also involved, but at the very least, you have a recorded complaint that may be useful if the person’s behaviour is systemic.

Possible actions to request

  • tell <HARASSER> to stop using this service to harass people
  • monitor <HARASSER>‘s Internet activity for threats
  • deregister/block <HARASSER> from using this service
  • provide me/law enforcement with identifying information about <HARASSER>‘s account
  • assist me in referring <HARASSER>‘s actions to law enforcement

Global Organization

Global PyLadies Organization

The global PyLadies community has no formal organization behind it; no board of directors, no appointed leadership. We found that PyLadies growth and success stems from being decentralized and non-bureaucratic.


We do have a few point people that can answer and address general, or non-location specific PyLadies questions. If you are not a local PyLadies leader, please check out Contact. If you are a local PyLadies leader, please take a look at Global PyLadies Community.

Points of Contact

Our general email is the best place to shoot any questions you may have.

If you have more casual questions, IRC is one of the best places to start. You can usually find several of the main PyLadies points of contact in #pyladies.

Online Community

Whether or not you’re part of a local group, the PyLadies community online welcomes you the IRC.


We have an IRC channel #pyladies that is on Instructions on how to chat in #pyladies IRC are here.

Quite a few well-known men and women in the Python community participate there and try to keep it a friendly place. Ask Python questions there, talk about what your local group is up to, or just say hi.

Anyone can plan and host virtual meetups in IRC #pyladies. You should host one! Just tell one of the ops to update the topic with info about your meetup. See the “Promotion” section for further details about how we can help spread word.

You can also create #pyladies-whatever IRC channels for your country, language, interest group, etc. Ask sandpy for help registering your channel under the #pyladies namespace.

Social Media

We have a Facebook Community page and Google+ Community page as well were all PyLadies and PyLadies-allies are welcome to post and participate in discussions. We also tweet from the official PyLadies Twitter handle.

Frequently Asked Questions
Can men attend local PyLadies group events?

It’s up to the local organizer, and usually explicitly stated within an event’s description Generally, groups will hold some women-only events as well as events for both genders (either women and +1 guests, or anyone who wants to attend).

Is there anything like PyLadies specifically for men?

There doesn’t seem to be a burning need for a PyLadies for Men ;) That said, you’re welcome to start any group that fits your needs or concerns.

One enterprising gent has printed “PyLaddies” shirts, and there is an IRC channel on Freenode, #pygents, for the men who love PyLadies =)

Can I use the PyLadies logo and graphics for any purpose?

Yes! But please read our logo usage policy.

TL;DR is that any of the graphics in our PyLadies assets repo can be used for local group promotion and/or to show your support.

Logos used with the intention to sell merchandise, please seek permission from the PyLadies leadership.

There is “official” merchandise sold - with proceeds going towards PyLadies - at our own spreadshirt site.

Can transgender women be PyLadies?

Anyone who considers herself a woman and does Python is a PyLady/Python lady. We support all women, whether female by birth or not.

If the idea of trans people is new to you, you might want to take a look at this fantastic illustrated book about gender, this comic, or any of the many other introductions to trans issues on the internet.

Is your goal to segregate by gender?

No! PyLadies and local PyLadies groups are about making the Python community explicitly welcoming and accessible to women.

Women who wouldn’t otherwise attend a Python user group meeting often attend local PyLadies group events, as a gateway to getting involved with Python programming as a beginner, or getting more involved in the Python community as an intermediate/advanced developer.

What if my question isn’t answered here?

Ask in IRC in the official #pyladies channel on freenode or send an email.


For policies from a local organizer’s prospective, please check out Policies.


PyLadies and the PyLadies logo are trademarks of the Python Software Foundation. For logo usage guidelines, please read PyLadies Logo Usage, and for trademark usage, please read PyLadies Trademark Usage Policy.

Code of Conduct

All PyLadies events (Meetups, conference lunches, etc), online spaces (IRC, Facebook, etc) are beholden to the PyLadies Code of Conduct (the CoC).

Please read Reporting Harassment for how to appropriately report any CoC violations you may have encountered.



PyLadies Logo Usage

PyLadies and the PyLadies logo are trademarks of the Python Software Foundation. The full trademark usage policy can be read here: PyLadies Trademark Usage Policy.

In general, we want the logo to be used as widely as possible to indicate the support of or involvement with PyLadies. If you are a local PyLadies leader, you are free to adapt the logo to your location. However, non-leaders, please ask first when using a derived version of the logo or when in doubt.

T-Shirts & Other Merchandise

PyLadies T-Shirts and other merchandise featuring the Python logo can be purchased at Cafepress (sales benefit the PyLadies organization). Making your own shirts is OK too, but please seek permission from the PyLadies leadership if you are planning to sell merchandise that shows the PyLadies logo.

Derivitive Work

If you are a local PyLadies leader, you are free to adapt the logo to your location. Some examples are below, and more can be found on our locations page.

PyLadies Australia

PyLadies LA

PyLadies PDX

PyLadies Trademark Usage Policy

Version 1.0.0


This document outlines the policy of PyLadies regarding the use of its trademarks. Any use of any PyLadies trademark must be in accordance with this policy.

“PyLadies” is a registered trademark of the Python Software Foundation (PSF). The PyLadies logos (in several variants) are use trademarks of the PSF as well.

All trademarks, even those that apply to open source software, must be used according to certain legal requirements. If these requirements are not met, the trademark may be endangered or lost. One of these requirements is for the trademark owner (in this case, the PSF) to maintain standards for using its trademarks, and to enforce acceptable use of the trademarks by taking action against parties that violate those standards.

Trademark law is mainly a way to protect the public, rather than the trademark holder. This means that uses of trademarks that confuse consumers – which in our case would include our developer and user community, or anyone else who might be likely be involved with or support PyLadies – are not permitted under law. As the owner of the trademark, the PSF must be sure the mark is used properly, so the community is not confused. That is what the PSF means when it’s said that an unpoliced trademark may be endangered or lost. When the trademark no longer represents a certain level of quality to the community, or no longer indicates that the PSF are the source of the products that bear the trademark, the trademark loses its value.

Underlying PSF’s trademark policy is a set of guidelines for what is – and is not – acceptable use of PSF’s trademarks, specifically the word mark “PyLadies”, the PyLadies logos, and variations of those marks. This policy describes the uses generally approved by PSF for its trademarks. However, if you violate this policy, or otherwise take actions that may compromise the goodwill or trademarks of PSF, or expose PSF to liability, PSF may require you to cease all use of any PSF trademark, regardless of the uses allowed in this policy.

General Goals

In general, we want the word mark “PyLadies” and the PyLadies logos to be used with minimal restriction to refer to the PyLadies community group.

We do not want these trademarks to be used:

  • to refer to any other community group
  • in a way that is misleading or may imply association of unrelated groups, communities, tools, documentation, or other resources with PyLadies
Uses that Never Require Approval

All trademarks are subject to “nominative use rules” that allow use of the trademark to name the trademarked entity in a way that is minimal and does not imply a sponsorship relationship with the trademark holder.

As such, stating accurately that local meetup group is put together by PyLadies organizers, that resource materials were put together by PyLadies member or organizer, or that software was written by PyLadies, is always allowed. In those cases, you may use the word “PyLadies” or the unaltered logos to indicate this, without our prior approval. This is true both for non-commercial and commercial uses.

This clause overrides other clauses of this policy. However, if you have any doubts about your intended use of the trademarks, please contact the PyLadies leadership.

Uses that Always Require Approval

Any commercial use of the PyLadies trademarks in product or company names must be approved first by PyLadies and/or the PSF. Some uses, like calling a company “The PyLadies Company,” or a product “PyLadies Software” or “PyLadies IDE” will be refused. This is because they are overly broad, or confusing as to whether the Python programming language is open source or commercial, or whether your product or organization is affiliated with or sponsored by PyLadies.

Any use of a derived (modified) logo for any commercial purpose must also be approved first by PyLadies. We will generally be unable to do this, because of the confusion it may cause.

How to Use the Trademarks

Although many uses of PyLadies’s trademarks are governed by more specific rules, which appear in the examples below, the following basic guidelines apply to almost any use of PyLadies’s trademarks.

  1. If the trademark is registered with the U.S. Patent and Trademark Office, it is referred to as a registered mark. The first or most prominent mention of a PyLadies trademark should be immediately followed by a symbol for registered trademark: “®” or “(r)”. For example “PyLadies® ...” This requirement is waived in all contexts where such marks are not normally included: email, online discussion, non-graphical advertisements (when permitted), and academic papers. We encourage the use of the symbol whenever possible, but recognize that many non-commercial and informal uses will omit it.
  2. The PyLadies logos are not currently registered. (We will post an update to this policy if they are registered later.) These logos should be used in the form provided by PyLadies, and should be accompanied by a symbol for unregistered trademarks: “(TM)” or a small TM “™”. This may not be removed or obscured and must always be included with the logo.
  3. Try to give the word “PyLadies” distinctive graphic treatment wherever possible. The trademark should be set apart from surrounding text by using ALLCAPS, italics, emphasized or underlined fonts.
  4. If the word “PyLadies” or the PyLadies logos are used in certain contexts, the following statement should accompany its use: “PyLadies” and the PyLadies logos are trademarks or registered trademarks of the PyLadies Software Foundation, used by ___________ with permission from the Python Software Foundation.
  5. For websites and documentation this can be on a “legal statements” page. For brochures and published articles, this statement is optional. We encourage use of this statement, particularly for published materials, but recognize some non-commercial and informal uses will omit it.
  6. Always use any trademark as an adjective only, with a capitalized “P” and capitalized “L”. For instance, it is correct to refer to the community as “PyLadies community” (adjective) but not pyladies (all lowercase), Pyladies (lowercase “L”), pyLadies (lowercase “P”), or “the PyLadies” (noun). Don’t use the trademark as a verb (“PyLadies your community today!”).

We have specific rules for the following uses:

  • Use of the word “PyLadies” in text, or as text in 3rd party logos and trademarks.
  • Use of one of the PyLadies-provided logo variants in unaltered form.
  • Use of a logo derived from the PyLadies logos. For example, use of a localized PyLadies geek girl.
  • Combined with different text, or with no text, or in combination with other graphic elements.

The following rules apply to the use of trademarks in each of these three classes.

The word “PyLadies”
  • Use of the word “PyLadies” in the names of user groups like NYC PyLadies, PyLadies of San Francisco, PyLadies Remote, etc. – Allowed when referring to sponsoring, attending, or starting up a local group. For commercial products, contact PyLadies leadership for permission.
  • Use of the word “PyLadies” in company names – Allowed only by prior written permission from PyLadies leadership.
  • Use of the word “PyLadies” when distributing software as part of a freely distributed learning resource, like “PyLadies Kit” – Allowed when released under PyLadies accounts (e.g. GitHub or PyPI). Please ask for assistance with distribution. For commercial distributions, contact PyLadies leadership for permission if your use is not covered by the nominative use rules described in the section “Uses that Never Require Approval” above.
  • Use of the word “PyLadies” in the name of books, tutorial resources or publications like “PyLadies Tutorial Cookbook” and “PyLadies Beginner Resources” – Allowed if for PyLadies.
  • Use of the word “PyLadies” on websites, brochures, documentation, and product packaging – Allowed if referring to PyLadies. Please follow the rules above about the use of the circle-R symbol.
  • Use of the word “PyLadies” in advertisements – Allowed in most cases by the nominative use rules described in the section “Uses that Never Require Approval” above. Other uses in ads only with prior permission.
  • Use of the word “PyLadies” in email and informally – Allowed without the circle-R symbol.
  • Use of the word “PyLadies” in academic papers, theses, and books – Allowed without the circle-R symbol. Books should include the symbol.
  • Use of the word “PyLadies” in another trademark – Not allowed without prior written permission from PyLadies leadership, except as described above.
Unaltered Logos
  • Use of unaltered PSF- and PyLadies-provided logos on T-shirts, mugs, etc. – Again, non-commercial uses to promote the PyLadies community are allowed. Commercial uses (which includes any use where you sell these items for money) require permission from the PyLadies leadership. Please reproduce our logos with the right colors and fonts; if you need help, let us know.
  • Use of unaltered PSF-provided logos on websites, brochures, and product packaging. The “PyLadies geek” and the “PyLadies wordmark” graphics alone is an unaltered version, whether or not accompanied by the words in PyLadies-provided logos. Non-commercial uses to promote the PyLadies community are allowed, as are all nominative uses as described in the section “Uses that Never Require Approval”. Any other commercial uses require prior written permission from PSF.
Derived Logos
  • Derived logos must always be sufficiently different from the PyLadies logos to allow the community to tell the difference. For example, if you want to create a derived logo for a local user group, you might be able to insert an unaltered PyLadies logo graphic into the local group’s name in a way that does not cause confusion. But confusingly similar derived logos are not allowed. This includes entwining PyLadies logos with other logos, or connecting them together in a confusing manner. Logos that simply change the colors or fonts do not require permission from PyLadies leadership. However, permission is required for any alteration to the shape of the “PyLadies wordmark” or the “PyLadies geek”.
  • Use of freely distributable derived logos as icons for files and executables – Allowed if used to refer to the PyLadies community. Commercial users should obtain permission before using derived logos as icons for proprietary file formats.
  • Use of derived logos for user groups and conferences – Allowed if used to refer to the PyLadies community. Commercial user groups and for-profit conferences require permission from the PSF.
  • Use of derived logos for freely distributed software or tools – Allowed when released under official PyLadies accounts (e.g. GitHub or PyPI). Please ask for assistance with distribution. Use of derived logos for commercial modules and tools requires permission from the PyLadies leadership.
  • We recommend contacting the PyLadies leadership for permission for all derived logos to avoid placing a confusing logo into wide-spread use. Contacting us is not a requirement for the specific non-commercial uses listed above, or when using freely distributable derived logos that have already been approved by the PyLadies leadership. However, obtaining permission from the PyLadies Leadership is required in all other uses of a derived logo.

The word mark “PyLadies” is a registered trademark in the United States of America. See

PyLadies sponsors, organizers, and members do not receive any preferential treatment under this policy.

Commercial trademark uses that predate this policy (prior to August 2015) do not require permission from the PSF if the use is consistent with this policy. However, if you think you may have used the PSF trademarks in the past in ways that would violate this policy, we recommend seeking permission. Although we are not generally in the business of suing for past infringement of our trademarks, the PSF does reserve the right to deny trademark use that violates this policy. Past use in violation of this policy does not confer a right to continue that use. (Please note: We are not currently aware of any prior commercial uses of the trademarks that do violate this policy.)

Helping Out

As a member of the PyLadies community, please keep an eye out for questionable uses of the PyLadies logo and “PyLadies” word mark. You can report potential misuse to the PyLadies Leadership. We will evaluate each case and take appropriate action.

Please do not approach users of the trademarks with a complaint. That should be left to the PyLadies leadership and its representatives.


License for this Policy

This policy has been adapted from the Python Software Foundation‘s Trademark Use Policy. Interested parties may adapt this policy document freely under the Creative Commons CC0 license.

What’s new?


  • Added:

    • Trademark Usage Policy
    • Logo Usage Guidelines
    • Guidelines to responding to a Code of Conduct incident
    • [TODO] Resources on how to make a local PyLadies website
    • [TODO] Logos/assets
  • Updated:

    • Reorganized doc location/flow


  • Removed the use of the word “chapter”

v2.0 PyPI Release

  • Released on PyPI
  • Added:
    • Checklists on group and event setup
    • More advice on events and group organization
    • Setup for pip installation
    • Included CoC
  • Updated:
    • Sphinx
    • Sphinx/RTD theme
    • Reorganized information from original pyladies kit

v1.0 Initial Release

Initial release of the pyladies-kit.

Read the Docs v: latest
On Read the Docs
Project Home

Free document hosting provided by Read the Docs.
PKsJDUkk"pyladies-kit-latest/_static/up.pngPNG  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`PKsJkuFpp,pyladies-kit-latest/_static/down-pressed.pngPNG  IHDRasRGBbKGDC pHYs B(xtIME -vF#IDAT8!OAJ, ++@I vbÿ@W7F HN#48646TMvv޼7Dsax1U q;< E-f)j%po4xF78G>)- EYm4%7YTk-Qa"NWAo-yeq,) Ypt\hqmszG]Nar߶s^l vh\2%0EeRvIENDB`PKsJ<>+pyladies-kit-latest/_static/ajax-loader.gifGIF89aU|NU|l!Created with! ! NETSCAPE2.0,30Ikc:Nf E1º.`q-[9ݦ9 JkH! ,4N!  DqBQT`1 `LE[|ua C%$*! ,62#+AȐ̔V/cNIBap ̳ƨ+Y2d! ,3b%+2V_ ! 1DaFbR]=08,Ȥr9L! ,2r'+JdL &v`\bThYB)@<&,ȤR! ,3 9tڞ0!.BW1  sa50 m)J! ,2 ٜU]qp`a4AF0` @1Α! ,20IeBԜ) q10ʰPaVڥ ub[;PKsJhkk$pyladies-kit-latest/_static/down.pngPNG  IHDRasRGBbKGDC pHYs B(xtIME"U{IDAT8ҡNCAJ, ++@4>/U^,~T&3M^^^PM6ٹs*RJa)eG*W<"F Fg78G>q OIp:sAj5GنyD^+yU:p_%G@D|aOs(yM,"msx:.b@D|`Vٟ۲иeKſ/G!IENDB`PKsJH'pyladies-kit-latest/_static/doctools.js/* * doctools.js * ~~~~~~~~~~~ * * Sphinx JavaScript utilities for all documentation. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * select a different prefix for underscore */ $u = _.noConflict(); /** * make the code below compatible with browsers without * an installed firebug like debugger if (!window.console || !console.firebug) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; } */ /** * small helper function to urldecode strings */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); }; /** * small helper function to urlencode strings */ jQuery.urlencode = encodeURIComponent; /** * This function returns the parsed url parameters of the * current request. Multiple values per key are supported, * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { if (typeof s == 'undefined') s =; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; for (var i = 0; i < parts.length; i++) { var tmp = parts[i].split('=', 2); var key = jQuery.urldecode(tmp[0]); var value = jQuery.urldecode(tmp[1]); if (key in result) result[key].push(value); else result[key] = [value]; } return result; }; /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { function highlight(node) { if (node.nodeType == 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { var span = document.createElement("span"); span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this); }); } } return this.each(function() { highlight(this); }); }; /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated == 'undefined') return string; return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('\u00B6'). attr('href', '#' + attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); if (!body.length) { body = $('body'); } window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('' + idnum).toggle(); if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {; } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); PKsJ՞bb)pyladies-kit-latest/_static/websupport.js/* * websupport.js * ~~~~~~~~~~~~~ * * sphinx.websupport utilties for all documentation. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ (function($) { $.fn.autogrow = function() { return this.each(function() { var textarea = this; $.fn.autogrow.resize(textarea); $(textarea) .focus(function() { textarea.interval = setInterval(function() { $.fn.autogrow.resize(textarea); }, 500); }) .blur(function() { clearInterval(textarea.interval); }); }); }; $.fn.autogrow.resize = function(textarea) { var lineHeight = parseInt($(textarea).css('line-height'), 10); var lines = textarea.value.split('\n'); var columns = textarea.cols; var lineCount = 0; $.each(lines, function() { lineCount += Math.ceil(this.length / columns) || 1; }); var height = lineHeight * (lineCount + 1); $(textarea).css('height', height); }; })(jQuery); (function($) { var comp, by; function init() { initEvents(); initComparator(); } function initEvents() { $('a.comment-close').live("click", function(event) { event.preventDefault(); hide($(this).attr('id').substring(2)); }); $('').live("click", function(event) { event.preventDefault(); handleVote($(this)); }); $('a.reply').live("click", function(event) { event.preventDefault(); openReply($(this).attr('id').substring(2)); }); $('a.close-reply').live("click", function(event) { event.preventDefault(); closeReply($(this).attr('id').substring(2)); }); $('a.sort-option').live("click", function(event) { event.preventDefault(); handleReSort($(this)); }); $('').live("click", function(event) { event.preventDefault(); showProposal($(this).attr('id').substring(2)); }); $('a.hide-proposal').live("click", function(event) { event.preventDefault(); hideProposal($(this).attr('id').substring(2)); }); $('').live("click", function(event) { event.preventDefault(); showProposeChange($(this).attr('id').substring(2)); }); $('a.hide-propose-change').live("click", function(event) { event.preventDefault(); hideProposeChange($(this).attr('id').substring(2)); }); $('a.accept-comment').live("click", function(event) { event.preventDefault(); acceptComment($(this).attr('id').substring(2)); }); $('a.delete-comment').live("click", function(event) { event.preventDefault(); deleteComment($(this).attr('id').substring(2)); }); $('a.comment-markup').live("click", function(event) { event.preventDefault(); toggleCommentMarkupBox($(this).attr('id').substring(2)); }); } /** * Set comp, which is a comparator function used for sorting and * inserting comments into the list. */ function setComparator() { // If the first three letters are "asc", sort in ascending order // and remove the prefix. if (by.substring(0,3) == 'asc') { var i = by.substring(3); comp = function(a, b) { return a[i] - b[i]; }; } else { // Otherwise sort in descending order. comp = function(a, b) { return b[by] - a[by]; }; } // Reset link styles and format the selected sort option. $('a.sel').attr('href', '#').removeClass('sel'); $('' + by).removeAttr('href').addClass('sel'); } /** * Create a comp function. If the user has preferences stored in * the sortBy cookie, use those, otherwise use the default. */ function initComparator() { by = 'rating'; // Default to sort by rating. // If the sortBy cookie is set, use that instead. if (document.cookie.length > 0) { var start = document.cookie.indexOf('sortBy='); if (start != -1) { start = start + 7; var end = document.cookie.indexOf(";", start); if (end == -1) { end = document.cookie.length; by = unescape(document.cookie.substring(start, end)); } } } setComparator(); } /** * Show a comment div. */ function show(id) { $('#ao' + id).hide(); $('#ah' + id).show(); var context = $.extend({id: id}, opts); var popup = $(renderTemplate(popupTemplate, context)).hide(); popup.find('textarea[name="proposal"]').hide(); popup.find('' + by).addClass('sel'); var form = popup.find('#cf' + id); form.submit(function(event) { event.preventDefault(); addComment(form); }); $('#s' + id).after(popup); popup.slideDown('fast', function() { getComments(id); }); } /** * Hide a comment div. */ function hide(id) { $('#ah' + id).hide(); $('#ao' + id).show(); var div = $('#sc' + id); div.slideUp('fast', function() { div.remove(); }); } /** * Perform an ajax request to get comments for a node * and insert the comments into the comments tree. */ function getComments(id) { $.ajax({ type: 'GET', url: opts.getCommentsURL, data: {node: id}, success: function(data, textStatus, request) { var ul = $('#cl' + id); var speed = 100; $('#cf' + id) .find('textarea[name="proposal"]') .data('source', data.source); if (data.comments.length === 0) { ul.html('
  • No comments yet.
  • ');'empty', true); } else { // If there are comments, sort them and put them in the list. var comments = sortComments(data.comments); speed = data.comments.length * 100; appendComments(comments, ul);'empty', false); } $('#cn' + id).slideUp(speed + 200); ul.slideDown(speed); }, error: function(request, textStatus, error) { showError('Oops, there was a problem retrieving the comments.'); }, dataType: 'json' }); } /** * Add a comment via ajax and insert the comment into the comment tree. */ function addComment(form) { var node_id = form.find('input[name="node"]').val(); var parent_id = form.find('input[name="parent"]').val(); var text = form.find('textarea[name="comment"]').val(); var proposal = form.find('textarea[name="proposal"]').val(); if (text == '') { showError('Please enter a comment.'); return; } // Disable the form that is being submitted. form.find('textarea,input').attr('disabled', 'disabled'); // Send the comment to the server. $.ajax({ type: "POST", url: opts.addCommentURL, dataType: 'json', data: { node: node_id, parent: parent_id, text: text, proposal: proposal }, success: function(data, textStatus, error) { // Reset the form. if (node_id) { hideProposeChange(node_id); } form.find('textarea') .val('') .add(form.find('input')) .removeAttr('disabled'); var ul = $('#cl' + (node_id || parent_id)); if ('empty')) { $(ul).empty();'empty', false); } insertComment(data.comment); var ao = $('#ao' + node_id); ao.find('img').attr({'src': opts.commentBrightImage}); if (node_id) { // if this was a "root" comment, remove the commenting box // (the user can get it back by reopening the comment popup) $('#ca' + node_id).slideUp(); } }, error: function(request, textStatus, error) { form.find('textarea,input').removeAttr('disabled'); showError('Oops, there was a problem adding the comment.'); } }); } /** * Recursively append comments to the main comment list and children * lists, creating the comment tree. */ function appendComments(comments, ul) { $.each(comments, function() { var div = createCommentDiv(this); ul.append($(document.createElement('li')).html(div)); appendComments(this.children, div.find('ul.comment-children')); // To avoid stagnating data, don't store the comments children in data. this.children = null;'comment', this); }); } /** * After adding a new comment, it must be inserted in the correct * location in the comment tree. */ function insertComment(comment) { var div = createCommentDiv(comment); // To avoid stagnating data, don't store the comments children in data. comment.children = null;'comment', comment); var ul = $('#cl' + (comment.node || comment.parent)); var siblings = getChildren(ul); var li = $(document.createElement('li')); li.hide(); // Determine where in the parents children list to insert this comment. for(i=0; i < siblings.length; i++) { if (comp(comment, siblings[i]) <= 0) { $('#cd' + siblings[i].id) .parent() .before(li.html(div)); li.slideDown('fast'); return; } } // If we get here, this comment rates lower than all the others, // or it is the only comment in the list. ul.append(li.html(div)); li.slideDown('fast'); } function acceptComment(id) { $.ajax({ type: 'POST', url: opts.acceptCommentURL, data: {id: id}, success: function(data, textStatus, request) { $('#cm' + id).fadeOut('fast'); $('#cd' + id).removeClass('moderate'); }, error: function(request, textStatus, error) { showError('Oops, there was a problem accepting the comment.'); } }); } function deleteComment(id) { $.ajax({ type: 'POST', url: opts.deleteCommentURL, data: {id: id}, success: function(data, textStatus, request) { var div = $('#cd' + id); if (data == 'delete') { // Moderator mode: remove the comment and all children immediately div.slideUp('fast', function() { div.remove(); }); return; } // User mode: only mark the comment as deleted div .find('span.user-id:first') .text('[deleted]').end() .find('div.comment-text:first') .text('[deleted]').end() .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id + ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id) .remove(); var comment ='comment'); comment.username = '[deleted]'; comment.text = '[deleted]';'comment', comment); }, error: function(request, textStatus, error) { showError('Oops, there was a problem deleting the comment.'); } }); } function showProposal(id) { $('#sp' + id).hide(); $('#hp' + id).show(); $('#pr' + id).slideDown('fast'); } function hideProposal(id) { $('#hp' + id).hide(); $('#sp' + id).show(); $('#pr' + id).slideUp('fast'); } function showProposeChange(id) { $('#pc' + id).hide(); $('#hc' + id).show(); var textarea = $('#pt' + id); textarea.val('source')); $.fn.autogrow.resize(textarea[0]); textarea.slideDown('fast'); } function hideProposeChange(id) { $('#hc' + id).hide(); $('#pc' + id).show(); var textarea = $('#pt' + id); textarea.val('').removeAttr('disabled'); textarea.slideUp('fast'); } function toggleCommentMarkupBox(id) { $('#mb' + id).toggle(); } /** Handle when the user clicks on a sort by link. */ function handleReSort(link) { var classes = link.attr('class').split(/\s+/); for (var i=0; iThank you! Your comment will show up ' + 'once it is has been approved by a moderator.'); } // Prettify the comment rating. comment.pretty_rating = comment.rating + ' point' + (comment.rating == 1 ? '' : 's'); // Make a class (for displaying not yet moderated comments differently) comment.css_class = comment.displayed ? '' : ' moderate'; // Create a div for this comment. var context = $.extend({}, opts, comment); var div = $(renderTemplate(commentTemplate, context)); // If the user has voted on this comment, highlight the correct arrow. if ( { var direction = ( == 1) ? 'u' : 'd'; div.find('#' + direction + 'v' +; div.find('#' + direction + 'u' +; } if (opts.moderator || comment.text != '[deleted]') { div.find('a.reply').show(); if (comment.proposal_diff) div.find('#sp' +; if (opts.moderator && !comment.displayed) div.find('#cm' +; if (opts.moderator || (opts.username == comment.username)) div.find('#dc' +; } return div; } /** * A simple template renderer. Placeholders such as <%id%> are replaced * by context['id'] with items being escaped. Placeholders such as <#id#> * are not escaped. */ function renderTemplate(template, context) { var esc = $(document.createElement('div')); function handle(ph, escape) { var cur = context; $.each(ph.split('.'), function() { cur = cur[this]; }); return escape ? esc.text(cur || "").html() : cur; } return template.replace(/<([%#])([\w\.]*)\1>/g, function() { return handle(arguments[2], arguments[1] == '%' ? true : false); }); } /** Flash an error message briefly. */ function showError(message) { $(document.createElement('div')).attr({'class': 'popup-error'}) .append($(document.createElement('div')) .attr({'class': 'error-message'}).text(message)) .appendTo('body') .fadeIn("slow") .delay(2000) .fadeOut("slow"); } /** Add a link the user uses to open the comments popup. */ $.fn.comment = function() { return this.each(function() { var id = $(this).attr('id').substring(1); var count = COMMENT_METADATA[id]; var title = count + ' comment' + (count == 1 ? '' : 's'); var image = count > 0 ? opts.commentBrightImage : opts.commentImage; var addcls = count == 0 ? ' nocomment' : ''; $(this) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-open' + addcls, id: 'ao' + id }) .append($(document.createElement('img')).attr({ src: image, alt: 'comment', title: title })) .click(function(event) { event.preventDefault(); show($(this).attr('id').substring(2)); }) ) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-close hidden', id: 'ah' + id }) .append($(document.createElement('img')).attr({ src: opts.closeCommentImage, alt: 'close', title: 'close' })) .click(function(event) { event.preventDefault(); hide($(this).attr('id').substring(2)); }) ); }); }; var opts = { processVoteURL: '/_process_vote', addCommentURL: '/_add_comment', getCommentsURL: '/_get_comments', acceptCommentURL: '/_accept_comment', deleteCommentURL: '/_delete_comment', commentImage: '/static/_static/comment.png', closeCommentImage: '/static/_static/comment-close.png', loadingImage: '/static/_static/ajax-loader.gif', commentBrightImage: '/static/_static/comment-bright.png', upArrow: '/static/_static/up.png', downArrow: '/static/_static/down.png', upArrowPressed: '/static/_static/up-pressed.png', downArrowPressed: '/static/_static/down-pressed.png', voting: false, moderator: false }; if (typeof COMMENT_OPTIONS != "undefined") { opts = jQuery.extend(opts, COMMENT_OPTIONS); } var popupTemplate = '\

    \ Sort by:\ best rated\ newest\ oldest\

    \ loading comments...

      Add a comment\ (markup):

      \ reStructured text markup: *emph*, **strong**, \ ``code``, \ code blocks: :: and an indented block after blank line
      \ \

      \ \ Propose a change ▹\ \ \ Propose a change ▿\ \

      \ \ \ \ \
      '; var commentTemplate = '\
      \ \ \ \ \ \ \
      \ \ \ \ \ \ \

      \ <%username%>\ <%pretty_rating%>\ <>\


      \ \ reply ▿\ proposal ▹\ proposal ▿\ \ \

        \ '; var replyTemplate = '\
      • \
        \ \ \ \ \ \
      • '; $(document).ready(function() { init(); }); })(jQuery); $(document).ready(function() { // add comment anchors for all paragraphs that are commentable $('.sphinx-has-comment').comment(); // highlight search words in search results $("div.context").each(function() { var params = $.getQueryParameters(); var terms = (params.q) ? params.q[0].split(/\s+/) : []; var result = $(this); $.each(terms, function() { result.highlightText(this.toLowerCase(), 'highlighted'); }); }); // directly open comment window if requested var anchor = document.location.hash; if (anchor.substring(0, 9) == '#comment-') { $('#ao' + anchor.substring(9)).click(); document.location.hash = '#s' + anchor.substring(9); } }); PKsJM "mm%pyladies-kit-latest/_static/jquery.js/*! jQuery v1.8.3 | */ (function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){},n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),;if(u){delete o.handle,{};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",","))},map:function(e){return this.pushStack(,function(t,n){return,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!,"constructor")&&!,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]],i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&,i),i},when:function(e){var t=0,,r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
        a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],"top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(,cssFloat:!!,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),"visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
        ","5px",t.shrinkWrapBlocks=r.offsetWidth!==3,,a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(||({}),,r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,,o,s)),!r&&s&&},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),,a||({}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&![y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,||(,r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if( n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&& n.push(s),n}else{if(i[2])return S.apply(n,,0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,,0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w];m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){,e.innerHTML="
        ",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--),s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

        ",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,,0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){,"div");try{,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
        "]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),{var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,{return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(||!wt.test(e))&&(||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0],i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!||!||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!{h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}![0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if( in[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float""cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!;var s,o,u,a=v.camelCase(n),;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i][i],[i]=t[i];;for(i in t)[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,,"boxSizing")==="border-box"):0)}}}),||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return{return this.elements?v.makeArray(this.elements):this}).filter(function(){return!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?,function(e,n){return{,value:e.replace(on,"\r\n")}}):{,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
        ").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),!="string"&&(,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&"ajaxStart");if(!c.hasContent){"&":"?"),delete,r=c.url;if(c.cache===!1){var,C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,;v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),{if(!n.crossDomain||{var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?,n.url,n.async,n.username,n.password),n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(,n,s)),!=null&&(,t.left!=null&&(f.left=t.left-s.left+h),"using"in t?,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{,left:n.left-r.left}},offsetParent:function(){return{var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u),r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);PKsJ' 5w -pyladies-kit-latest/_static/comment-close.pngPNG  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>| ${} 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 1;VIDAT8ukU?sg4h`G1 RQܸp%Bn"bЍXJ .4V iZ##T;m!4bP~7r>ιbwc;m;oӍAΆ ζZ^/|s{;yR=9(rtVoG1w#_ө{*E&!(LVuoᲵ‘D PG4 :&~*ݳreu: S-,U^E&JY[P!RB ŖޞʖR@_ȐdBfNvHf"2T]R j'B1ddAak/DIJD D2H&L`&L $Ex,6|~_\P $MH`I=@Z||ttvgcЕWTZ'3rje"ܵx9W> mb|byfFRx{w%DZC$wdցHmWnta(M<~;9]C/_;Տ#}o`zSڷ_>:;x컓?yݩ|}~wam-/7=0S5RP"*֯ IENDB`PKsJa$pyladies-kit-latest/_static/plus.pngPNG  IHDR &q pHYs  tIME 1l9tEXtComment̖RIDATcz(BpipPc |IENDB`PKsJ;l/l/)pyladies-kit-latest/_static/underscore.js// Underscore.js 1.3.1 // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the MIT license. // Portions of Underscore are inspired or borrowed from Prototype, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: // (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var;if(e! false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== c.source&&}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= function(a,c,b){var e;E(a,function(a,g,h){if(,a,g,h))return e=a,true});return e};,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= e&&,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var,2);return,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= function(a,c){return,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(,1));return b.filter(a,function(a){return!b.include(c,a)})};{for(var,c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(, 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return"[object Array]"};b.isObject=function(a){return a===Object(a)}; b.isArguments=function(a){return"[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return"[object Function]"};b.isString=function(a){return"[object String]"};b.isNumber=function(a){return"[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||"[object Boolean]"};b.isDate=function(a){return"[object Date]"}; b.isRegExp=function(a){return"[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= function(){var;,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); PKsJy&55(pyladies-kit-latest/_static/pygments.css.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 .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ .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: #333333 } /* 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: #0044DD } /* 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 .mb { color: #208050 } /* Literal.Number.Bin */ .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 */PKsJEE*pyladies-kit-latest/_static/searchtools.js/* * searchtools.js_t * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilties for the full-text search. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * 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; } } /** * Simple result scoring code. */ var Scorer = { // Implement the following function to further tweak the score for each result // The function takes a result array [filename, title, anchor, descr, score] // and returns the new score. /* score: function(result) { return result[4]; }, */ // query matches the full name of an object objNameMatch: 11, // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object objPrio: {0: 15, // used to be importantResults 1: 5, // used to be objectResults 2: -5}, // used to be unimportantResults // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, // query found in terms term: 5 }; /** * 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, dataType: "script", cache: true, complete: function(jqxhr, textstatus) { if (textstatus != "success") { document.getElementById("searchindexloader").src = url; } }}); }, 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() { var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (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 (or wait until index is loaded) */ 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 = $('