diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 542693a..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -docs/index.html linguist-generated=true diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7653f15..0000000 --- a/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -*.gem -*.rbc -.bundle -.config -coverage -InstalledFiles -lib/bundler/man -pkg -rdoc -spec/reports -test/tmp -test/version_tmp -tmp -*.DS_STORE -build/ -.cache -.vagrant -.sass-cache - -# YARD artifacts -.yardoc -_yardoc -doc/ -.idea/ - -# NodeJS -node_modules/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0d6d210..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -sudo: false - -language: ruby - -rvm: - - 2.3.3 - - 2.4.0 - -cache: bundler -script: bundle exec middleman build diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..960f5ee --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +dev.splitwise.com \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index cc17fd9..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@lord.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/README.md b/README.md deleted file mode 100644 index a02171b..0000000 --- a/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Welcome to the Splitwise API! - -This repo powers the official documentation for the Splitwise API. You can view our official API documentation website at [http://dev.splitwise.com](http://dev.splitwise.com). - -## Questions? Issues? - -If something in the API is confusing you, you can open an [issue](https://github.com/splitwise/api-docs/issues) about it on GitHub. We're a small team, so we may not have an instant fix, but we'll get back to you as soon as we're able. - -If you spot an issue in our API documentation itself, feel free to open a [pull request](https://github.com/splitwise/api-docs/pulls) to update this repo! - -## Powered by OpenAPI + redocly - -These API docs follow the [OpenAPI v3](https://swagger.io/specification/) specification. The website is built with [redoc](https://github.com/Redocly/redoc). - -### Developing -``` -$ npm install -$ npm run serve -``` - -This will start a local HTTP server that serves the documentation and rebuilds whenever any of the OpenAPI source files are modified. - -### Compiling -This will create a zero-dependency HTML file at docs/index.html. - -``` -$ npm run build -``` diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 1abff87..0000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -dev.splitwise.com diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 40fa571..0000000 --- a/docs/index.html +++ /dev/null @@ -1,1424 +0,0 @@ - - - - - - Splitwise API - - - - - - - - - -

Splitwise API (3.0.0)

Download OpenAPI specification:

Introduction

Hey there! We're glad you're interested in the Splitwise API. This documentation will help you to fetch information -on users, expenses, groups, and much more.

-

If something in the API is confusing you, you can open an issue about it on GitHub. -We're a small team, so we may not have an instant fix, but we'll get back to you as soon as we're able. -(If you spot an issue in our API documentation itself, feel free to open a pull request to update this website!)

-

Third-Party SDKs

The development community has built a number of unofficial, third-party SDKs for Splitwise in a variety of different languages.

- -

If you've built a third-party SDK for Splitwise and you'd like to see it included in this list, then please open a pull request to update this section and add a new link. Thank you for your work!

-

Note: These links are provided for convenience. These libraries have not been reviewed or endorsed by Splitwise, and Splitwise -cannot vouch for their quality. If you have questions or bug reports, please direct your feedback to the authors of these libraries.

-

Terms of Use

Overview

Splitwise provides this Self-Serve API to facilitate integrations with third-party applications, as well as open-up functionality for hobbyists and power users to programmatically interact with their own Splitwise account and build plugins or other tools.

-

If you’re interested in integrating your commercial application with Splitwise, we strongly encourage you to contact developers@splitwise.com so our development team can help discuss your use case, provide private APIs and Enterprise support, and offer an appropriate commercial license for the integration. The Self-Serve API documented here may be suitable for internal prototyping and other exploratory work.

-

If you are developing a non-commercial plugin application or personal project, we recommend you make use of the Self-Serve API documented here under the API Terms Of Use. Please be aware that our Self-Serve API has conservative rate and access limits, which are subject to change at any time and not well suited to commercial projects. If this is a problem for your use case, please contact us at developers@splitwise.com to discuss your needs.

-

All Self-Service API users are subject to the API Terms of Use below.

-

TERMS OF USE

These API Terms of Use describe your rights and responsibilities when accessing our publicly available Application Programming Interface (API) and related API documentation. Please review them carefully.

-

Splitwise may modify this Agreement at any time by posting a revised version on our website. The revised version will be effective at the time that it is posted.

-

These API terms form a binding contract between you and us. In these terms "you," and "your," refers to the individual, company or legal entity and/or entities that you represent while accessing the API. “We”, “us”, “our” and “Splitwise” refers to Splitwise Inc. By accepting these API terms, either by accessing or using the API, or authorizing or permitting any individual to access or use the API, you agree to be bound by this contract.

-
    -
  1. - API License: -
      -
    1. - Subject to the restrictions in these terms, we grant you a non-exclusive, revocable, worldwide, non-transferable, non-sublicensable, limited license to access and use (i) our APIs (ii) related API documentation, packages, sample code, software, or materials made available by Splitwise (“API Documentation”), and (iii) any and all access keys or data derived or obtained from Splitwise API responses (“Splitwise Data”). The Splitwise API, Splitwise Data, and API Documentation will be together referred to as the “Splitwise Materials.” You will use Splitwise Materials solely as necessary to develop, test and support a Self-Service integration of your software application (an "Application" or "App") with Splitwise in accordance with this Agreement and any other agreements between You and Splitwise. -
    2. -
    -
  2. -
  3. - API License Restrictions -
      -
    1. - You agree that will you will not, and will not allow any of your partners, subsidiaries and/or affiliates and each of their respective directors, officers, employees, agents, partners, suppliers, service providers, contractors or end users (collectively, “Your Affiliates”) to engage in any Prohibited Activities set forth in section 2f. -
    2. -
    3. - Splitwise reserves the right to block or revoke, with or without notice, your access to any or all of the Splitwise Materials if Splitwise determines in its sole discretion that you are engaging in any of the Prohibited Activities. -
    4. -
    5. - Splitwise may monitor your use of Splitwise Materials to improve our services and ensure compliance with this agreement, and may suspend your access to Splitwise Materials if we believe you are in violation. -
    6. -
    7. - Your use of the Splitwise API is subject to usage limits and other functional restrictions in the sole discretion of Splitwise. You will not use the API in a manner that exceeds rate limits, or constitutes excessive or abusive usage. -
    8. -
    9. - Your use of Splitwise Materials must respect Splitwise user’s privacy choices and settings and the Privacy portion of this agreement. You will obtain explicit consent from end users as a basis for any processing of Splitwise Materials. Your use of Splitwise Materials must comply with all Applicable Data Protection Laws applicable to you, including but not limited to GDPR and CCPA compliance. -
    10. -
    11. - Prohibited Activities: -
        -
      1. - You will not use Splitwise Materials or any part thereof in any manner or for any purpose that violates any law or regulation, or any right of any person, including but not limited to intellectual property rights, rights of privacy and/or publicity, or which otherwise results in liability to Splitwise, or its officers, employees, or end users. -
      2. -
      3. - You will not use Splitwise Materials in a way that poses a security, operational or technical risk to our Services. -
      4. -
      5. - You may not Splitwise Materials to create an application that replicates existing Splitwise functionality or competes with Splitwise and our Services. -
      6. -
      7. - You will not use Splitwise Materials to create an application that encourages or creates functionality for users to violate our Terms of Service. -
      8. -
      9. - You will not use Splitwise Materials to create an application that can be used by anyone under the age of 13. You will not knowingly collect or enable the collection of any personal information from children under the age of 13. -
      10. -
      11. - You will not reverse engineer, decompile, disassemble, or otherwise attempt to derive the source code or underlying ideas, trade secrets, algorithms or structure of the Splitwise Materials, or Splitwise software applications. -
      12. -
      13. - You will not attempt to defeat, avoid, bypass, remove, deactivate or otherwise circumvent any software protection mechanisms in the Splitwise Materials or Application or any part thereof, including without limitation, any such mechanism used to restrict or control the functionality of the API. -
      14. -
      15. - You will not use Splitwise’s name to endorse or promote any product, including a product derived from Splitwise Materials. -
      16. -
      17. - You will not sell, lease, rent, sublicense or in any way otherwise commercialize any Splitwise Data, or dataset derived from Splitwise Data and/or Splitwise Materials. -
      18. -
      19. - You will not use Splitwise Materials in applications that send unsolicited communications to users or include any malware, adware, potentially unwanted programs, or similar applications that could damage or disparage Splitwise’s reputation or services. -
      20. -
      -
    -
  4. -
  5. - Privacy -
      -
    1. - Your Application shall have a lawful privacy policy, accessible with reasonably prominent hyperlinks that does not conflict with or supersede the Splitwise Privacy Policy and that explains how you collect, store, use, and/or transfer any Personal Data via your Applications. Personal Data is data that may be used, either alone or together with other information, to identify an individual user, including, without limitation, a user’s name, address, telephone number, username, email address, city and country, geolocation, unique identifiers, picture, or other similar information and includes personal data as defined in the GDPR. -
    2. -
    3. - You are responsible for maintaining an appropriate legal basis to process any data under all applicable data protection laws (including but not limited to the GDPR, and the CCPA). -
    4. -
    5. - You will use industry standard security measures to protect against and prevent security breaches and any unauthorized disclosure of any personal information you process, including administrative, physical and technical safeguards for protection of the security, confidentiality and integrity of that personal information. -
    6. -
    7. - You must promptly notify us in writing via email to security@splitwise.com of any security deficiencies in, or intrusions to, your Applications or systems that you discover, and of any breaches of your user agreement or privacy policy that impact or may impact Splitwise customers. Please review our Privacy Policy for more information on how we collect and use data relating to the use and performance of our Service. -
    8. -
    9. - You will delete Splitwise Data as requested within a reasonable time, if so requested by either a Splitwise User or Splitwise Inc. -
    10. -
    11. - Any data submitted to Splitwise through your use of the Splitwise API will be governed by the Splitwise Privacy Policy. -
    12. -
    13. - You agree that Splitwise may collect certain use data and information related to your use of the Splitwise Materials, and the Splitwise API in connection with your Application (“Usage Data”), and that Splitwise may use such Usage Data for any business purpose, internal or external, including, without limitation, providing enhancements to the Splitwise Materials or Splitwise Platform, providing developer of user support, or otherwise. You agree to include a statement to this effect in your Application’s Privacy Policy. -
    14. -
    -
  6. - -
  7. - Conditions Of Use -
      -
    1. - Splitwise reserves the right to modify our API at any time, for any reason, without notice. -
    2. -
    3. - Splitwise may use your name, and other contact details to contact you regarding your use of our API or, if we believe you are in violation of this contract. -
    4. -
    5. - You are solely responsible for your use of the Splitwise API and any application you create that uses Splitwise Materials, including but not limited to Customer Support. -
    6. -
    7. - Splitwise reserves the right to develop and extend its products and capabilities without regard to whether those products compete with or invalidate your Splitwise integration or products offered by you. -
    8. -
    9. - Splitwise may limit (i) the number of network calls that your App may make via the API; and (ii) the maximum number of Splitwise users that may connect your Application, or (iii) anything else about the Splitwise API as Splitwise deems appropriate, at Splitwise’s sole discretion. -
    10. -
    11. - Splitwise may impose or modify these limitations without notice. Splitwise may utilize technical measures to prevent over-usage and stop usage of the API by your App after any usage limitations are exceeded or suspend your access to the API with or without notice to you in the event you exceed such limitations. -
    12. -
    13. - You will not issue any press release or other announcement regarding your Application that makes any reference to Splitwise without our prior written consent. -
    14. -
    15. - You will not use our API to distribute unsolicited advertising or promotions, or to send messages, make comments, or initiate any other unsolicited direct communication or contact with Splitwise users or partners. -
    16. -
    -
  8. - -
  9. - Use of Splitwise Marks -
      -
    1. - The rights granted in this Agreement do not include any general right to use the Splitwise name or any Splitwise trademarks, service marks or logos (the “Splitwise Marks”) with respect to your Applications. Subject to your continued compliance with this Agreement, you may use Splitwise Marks for limited purposes related to your Applications only as described in Splitwise Branding Guidelines and/or as provided in written communications with the Splitwise team. -
    2. -
    3. - These rights apply on a non-exclusive, non-transferable, worldwide, royalty-free basis, without any right to sub-license, and may be revoked by Splitwise at any time. -
    4. -
    5. - If Splitwise updates Branding Guidelines or any Splitwise Marks that you are using, you agree to update such Splitwise Marks to reflect the most current versions. You must not use any Splitwise Marks or trade dress, or any confusingly similar mark or trade dress, as the name or part of the name, user interface, or icon of your Applications, or as part of any logo or branding for your Applications. -
    6. -
    -
  10. - -
  11. - Reservation Of Rights. The Splitwise Materials as well as the trademarks, copyrights, trade secrets, patents or other intellectual property (collectively, “Intellectual Property”) contained therein will remain the sole and exclusive property of Splitwise, and you will reasonably assist Splitwise in protecting such ownership. Splitwise reserves to itself all rights to the Splitwise Materials not expressly granted to You. Except as expressly provided in this Agreement, You do not acquire any rights to or interest in the Intellectual Property. You will not utilize Splitwise Intellectual Property except as expressly authorized under this Agreement. -
  12. - -
  13. - Feedback. Splitwise welcomes feedback from developers to improve our API, documentation and Services, and may provide feedback to you as well. We will review any feedback received, however we make no guarantee that suggestions will be implemented. If you choose to provide feedback, suggestions or comments regarding the Splitwise API, documentation, or services, you acknowledge that Splitwise will be free to use your feedback in any way it sees fit. This includes the freedom to copy, modify, create derivative works, distribute, publicly display, publicly perform, grant sublicenses to, and otherwise exploit in any manner such feedback, suggestions or comments, for any and all purposes, with no obligation of any kind to you, in perpetuity. -
  14. - -
  15. - Confidentiality. Any information not generally available to the public that is made available to you should be considered Confidential. You agree to: -
      -
    1. - Protect this information from unauthorized use, access, or disclosure, -
    2. -
    3. - Use this information only as necessary, -
    4. -
    5. - Destroy any copies, or return this information to us when this Contract is terminated, or at any time as requested by Splitwise -
    6. -
    -
  16. - -
  17. - Termination. This Contract shall remain effective until terminated by either party. You may terminate this Contract at any time, by discontinuing your use of our APIs. Splitwise may terminate this Contract at any time with or without cause and without advanced notice to you. Upon termination, all rights and licenses granted under this Contract shall immediately terminate. You must immediately discontinue any use, and destroy any copies of the Splitwise Materials and Confidential Information in your possession. -
  18. -
  19. - Representations and Warranties. You represent and warrant that you have validly entered into the Contract, and that you have the legal power to do so, and that doing so will not violate any law, government regulation, or breach agreement with another third party. -

    THE SPLITWISE API AND DOCUMENTATION IS BEING PROVIDED TO YOU ‘AS IS’ AND ‘AS AVAILABLE’ WITHOUT ANY WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OF MERCHANTABILITY, TITLE, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. YOU ACKNOWLEDGE THAT WE DO NOT WARRANT THAT THE APIS WILL BE UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE. -
  20. -
  21. - Limitation of Liability. -

    TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL SPLITWISE, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, LICENSORS, LICENSEES, ASSIGNS OR SUCCESSORS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO ANY LOSS OF DATA, SERVICE INTERRUPTION, COMPUTER FAILURE, OR PECUNIARY LOSS) HOWEVER CAUSED, WHETHER IN CONTRACT, TORT OR UNDER ANY OTHER THEORY OF LIABILITY, AND WHETHER OR NOT YOU OR THE THIRD PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOUR ONLY RIGHT WITH RESPECT TO ANY PROBLEMS OR DISSATISFACTION WITH THE SPLITWISE SERVICES IS TO STOP USING THE SPLITWISE SERVICES. -

    SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN TYPES OF DAMAGES REFERRED TO ABOVE (INCLUDING INCIDENTAL OR CONSEQUENTIAL DAMAGES). ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS AND EXCLUSIONS MAY NOT APPLY TO YOU. YOU AGREE THAT SPLITWISE’S AGGREGATE LIABILITY UNDER THIS AGREEMENT IS LIMITED TO ONE HUNDRED DOLLARS ($100). -
  22. - -
  23. - Indemnification: You agree to defend, indemnify, and hold harmless Splitwise and its affiliates, directors, and customers, from and against any and all third-party claims, actions, suits, and proceedings (including, but not limited to legal, or investigative fees), arising out of, or related to your use of the Splitwise Services, your violation of this Contract, your violation of your user agreement or privacy policy, or your violation of any laws, regulations, or third party rights. -
  24. - -
  25. - Miscellaneous -
      -
    1. - Applicable Law, Jurisdiction, and Venue: Any dispute arising out of this Agreement shall be governed by Massachusetts law and controlling U.S. federal law, without regard to conflict of law provisions thereof. Any claim or dispute between you and Splitwise that arises in whole or in part from this Contract or your use of the API or our Services shall be decided exclusively by a court of competent jurisdiction located in Massachusetts, and you hereby consent to, and waive all defenses of lack of personal jurisdiction and forum non conveniens with respect to venue and jurisdiction in the state and federal courts of Massachusetts. -
    2. -
    3. - Assignment: You may not assign or delegate any of your rights or obligations hereunder, whether by operation of law or otherwise, without Splitwise’s prior written consent. Splitwise retains the right to assign the Contract in its entirety, without consent of the other party, to a corporate affiliate or in connection with a merger, acquisition, corporate reorganization, or sale of all or substantially all of its assets. Any purported assignment in violation of this section is void. -
    4. -
    5. - Language: This contact was drafted in English. In the event that this contract, or any part thereof, is translated to a language other than English, the English-language version shall control in the event of a conflict. -
    6. -
    7. - Relationship: You and Splitwise are independent contractors. This Contract does not create or imply any partnership, agency, joint venture, fiduciary or employment relationship between the parties. There are no third party beneficiaries to the Contract. -
    8. -
    9. - Severability: The Contract will be enforced to the fullest extent permitted under applicable law. If any provision of the Contract is found to be invalid or unenforceable by a court of competent jurisdiction, the provision will be modified by the court and interpreted so as best to accomplish the objectives of the original provision to the fullest extent permitted by law, and the remaining provisions of the Contract will remain in effect. -
    10. -
    11. - Force Majeure: Neither we nor you will be responsible for any failure to perform obligations under this Contract if such failure is caused by events beyond the reasonable control of a party, which may include denial-of-service attacks, a failure by a third party hosting provider, acts of God, war, strikes, revolutions, lack or failure of transportation facilities, laws or governmental regulations. -
    12. -
    13. - Entire Agreement: These Terms comprise the entire agreement between you and Splitwise with respect to the above subject matter and supersedes and merges all prior proposals, understandings and contemporaneous communications. -
    14. -
    -
  26. -

Users

Resources to access and modify user information.

-

Get information about the current user

Authorizations:
OAuthApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "user": {
    }
}

Get information about another user

Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "user": {
    }
}

Update a user

Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer
Request Body schema: application/json
required
first_name
string
last_name
string
email
string
password
string
locale
string
default_currency
string

Responses

Request samples

Content type
application/json
{
  • "first_name": "string",
  • "last_name": "string",
  • "email": "string",
  • "password": "string",
  • "locale": "string",
  • "default_currency": "string"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "first_name": "Ada",
  • "last_name": "Lovelace",
  • "email": "ada@example.com",
  • "registration_status": "confirmed",
  • "picture": {
    },
  • "custom_picture": false
}

Groups

A Group represents a collection of users who share expenses together. For example, some users use a Group to aggregate expenses related to a home. Others use it to represent a trip. Expenses assigned to a group are split among the users of that group. Importantly, two users in a Group can also have expenses with one another outside of the Group.

-

List the current user's groups

Note: Expenses that are not associated with a group are listed in a group with ID 0.

-
Authorizations:
OAuthApiKeyAuth

Responses

Response samples

Content type
application/json
{}

Get information about a group

Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{}

Create a group

Creates a new group. Adds the current user to the group by default.

-

Note: group user parameters must be flattened into the format users__{index}__{property}, where -property is user_id, first_name, last_name, or email. -The user's email or ID must be provided.

-
Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
name
required
string
group_type
string
Enum: "home" "trip" "couple" "other" "apartment" "house"

What is the group used for?

-

Note: It is recommended to use home in place of house or apartment.

-
simplify_by_default
boolean

Turn on simplify debts?

-
users__{index}__{property}*
additional property
string

Responses

Request samples

Content type
application/json
{
  • "name": "The Brain Trust",
  • "group_type": "trip",
  • "users__0__first_name": "Alan",
  • "users__0__last_name": "Turing",
  • "users__0__email": "alan@example.org",
  • "users__1__id": 5823
}

Response samples

Content type
application/json
{}

Delete a group

Delete an existing group. Destroys all associated records (expenses, etc.)

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "success": true
}

Restore a group

Restores a deleted group.

-

Note: 200 OK does not indicate a successful response. You must check the success value of the response.

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
Example
{
  • "success": true
}

Add a user to a group

Note: 200 OK does not indicate a successful response. You must check the success value of the response.

-
Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
One of
group_id
required
integer
user_id
required
integer

Responses

Request samples

Content type
application/json
Example
{
  • "group_id": 49012,
  • "user_id": 7999632
}

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "user": { },
  • "errors": { }
}

Remove a user from a group

Remove a user from a group. Does not succeed if the user has a non-zero balance.

-

Note: 200 OK does not indicate a successful response. You must check the success value of the response.

-
Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
group_id
required
integer
user_id
required
integer

Responses

Request samples

Content type
application/json
{
  • "group_id": 4012,
  • "user_id": 940142
}

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "errors": { }
}

Friends

List current user's friends

Note: group objects only include group balances with that friend.

-
Authorizations:
OAuthApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "friends": [
    ]
}

Get details about a friend

Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

User ID of the friend

-

Responses

Response samples

Content type
application/json
{
  • "friend": {
    }
}

Add a friend

Adds a friend. If the other user does not exist, you must supply user_first_name. -If the other user exists, user_first_name and user_last_name will be ignored.

-
Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
user_email
string
user_first_name
string
user_last_name
string

Responses

Request samples

Content type
application/json
{
  • "user_email": "ada@example.com",
  • "user_first_name": "Ada",
  • "user_last_name": "Lovelace"
}

Response samples

Content type
application/json
{
  • "friend": {
    }
}

Add friends

Add multiple friends at once.

-

For each user, if the other user does not exist, you must supply users__{index}__first_name.

-

Note: user parameters must be flattened into the format users__{index}__{property}, where -property is first_name, last_name, or email.

-
Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
users__{index}__{property}*
additional property
string

Responses

Request samples

Content type
application/json
{
  • "users__0__first_name": "Alan",
  • "users__0__last_name": "Turing",
  • "users__0__email": "alan@example.org",
  • "users__1__email": "existing_user@example.com"
}

Response samples

Content type
application/json
{
  • "users": [
    ],
  • "errors": {
    }
}

Delete friendship

Given a friend ID, break off the friendship between the current user and the specified user.

-

Note: 200 OK does not indicate a successful response. You must check the success value of the response.

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

User ID of the friend

-

Responses

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "errors": [ ]
}

Expenses

Get expense information

Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "expense": {
    }
}

List the current user's expenses

Authorizations:
OAuthApiKeyAuth
query Parameters
group_id
integer

If provided, only expenses in that group will be returned, and friend_id will be ignored.

-
friend_id
integer

ID of another user. If provided, only expenses between the current and provided user will be returned.

-
dated_after
string <date-time>
dated_before
string <date-time>
updated_after
string <update-time>
updated_before
string <date-time>
limit
integer
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "expenses": [
    ]
}

Create an expense

Creates an expense. You may either split an expense equally (only with group_id provided), -or supply a list of shares.

-

When splitting equally, the authenticated user is assumed to be the payer.

-

When providing a list of shares, each share must include paid_share and owed_share, and must be identified by one of the following:

-
    -
  • email, first_name, and last_name
  • -
  • user_id
  • -
-

Note: 200 OK does not indicate a successful response. The operation was successful only if errors is empty.

-
Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
One of
cost
required
string

A string representation of a decimal value, limited to 2 decimal places

-
description
required
string

A short description of the expense

-
details
string or null

Also known as "notes."

-
date
string <date-time>

The date and time the expense took place. May differ from created_at

-
repeat_interval
string
Enum: "never" "weekly" "fortnightly" "monthly" "yearly"
currency_code
string

A currency code. Must be in the list from get_currencies

-
category_id
integer

A category id from get_categories

-
group_id
required
integer

The group to put this expense in.

-
split_equally
required
boolean
Value: true

Responses

Request samples

Content type
application/json
Example
{
  • "cost": "25",
  • "description": "Grocery run",
  • "details": "string",
  • "date": "2012-05-02T13:00:00Z",
  • "repeat_interval": "never",
  • "currency_code": "USD",
  • "category_id": 15,
  • "group_id": 0,
  • "split_equally": true
}

Response samples

Content type
application/json
{
  • "expenses": [
    ],
  • "errors": { }
}

Update an expense

Updates an expense. Parameters are the same as in create_expense, but you only need to include parameters -that are changing from the previous values. If any values is supplied for users__{index}__{property}, all -shares for the expense will be overwritten with the provided values.

-

Note: 200 OK does not indicate a successful response. The operation was successful only if errors is empty.

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

ID of the expense to update

-
Request Body schema: application/json
required
cost
required
string

A string representation of a decimal value, limited to 2 decimal places

-
description
required
string

A short description of the expense

-
details
string or null

Also known as "notes."

-
date
string <date-time>

The date and time the expense took place. May differ from created_at

-
repeat_interval
string
Enum: "never" "weekly" "fortnightly" "monthly" "yearly"
currency_code
string

A currency code. Must be in the list from get_currencies

-
category_id
integer

A category id from get_categories

-
group_id
required
integer

The group to put this expense in, or 0 to create an expense outside of a group.

-
users__0__user_id
integer
users__0__paid_share
string

Decimal amount as a string with 2 decimal places. The amount this user paid for the expense

-
users__0__owed_share
string

Decimal amount as a string with 2 decimal places. The amount this user owes for the expense

-
users__1__first_name
string
users__1__last_name
string
users__1__email
string
users__1__paid_share
string

Decimal amount as a string with 2 decimal places. The amount this user paid for the expense

-
users__1__owed_share
string

Decimal amount as a string with 2 decimal places. The amount this user owes for the expense

-
users__{index}__{property}*
additional property
string

Responses

Request samples

Content type
application/json
{
  • "cost": "25",
  • "description": "Grocery run",
  • "details": "string",
  • "date": "2012-05-02T13:00:00Z",
  • "repeat_interval": "never",
  • "currency_code": "USD",
  • "category_id": 15,
  • "group_id": 0,
  • "users__0__user_id": 54123,
  • "users__0__paid_share": "25",
  • "users__0__owed_share": "13.55",
  • "users__1__first_name": "Neu",
  • "users__1__last_name": "Yewzer",
  • "users__1__email": "neuyewxyz@example.com",
  • "users__1__paid_share": "0",
  • "users__1__owed_share": "11.45",
  • "users__{index}__{property}1": "string",
  • "users__{index}__{property}2": "string"
}

Response samples

Content type
application/json
{
  • "expenses": [
    ],
  • "errors": { }
}

Delete an expense

Note: 200 OK does not indicate a successful response. The operation was successful only if success is true.

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

ID of the expense to delete

-

Responses

Response samples

Content type
application/json
Example
{
  • "success": true
}

Restore an expense

Note: 200 OK does not indicate a successful response. The operation was successful only if success is true.

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

ID of the expense to restore

-

Responses

Response samples

Content type
application/json
{
  • "success": true
}

Comments

Get expense comments

Authorizations:
OAuthApiKeyAuth
query Parameters
expense_id
required
integer
Example: expense_id=4193

Responses

Response samples

Content type
application/json
{
  • "comments": [
    ]
}

Create a comment

Authorizations:
OAuthApiKeyAuth
Request Body schema: application/json
required
expense_id
integer
content
string

Responses

Request samples

Content type
application/json
{
  • "expense_id": 5123,
  • "content": "Does this include the delivery fee?"
}

Response samples

Content type
application/json
{
  • "comment": {
    }
}

Delete a comment

Deletes a comment. Returns the deleted comment.

-
Authorizations:
OAuthApiKeyAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "comment": {
    }
}

Notifications

Get notifications

Return a list of recent activity on the users account with the most recent items first. -content will be suitable for display in HTML and uses only the <strong>, <strike>, <small>, -<br> and <font color="#FFEE44"> tags.

-

The type value indicates what the notification is about. Notification types may be added in the future -without warning. Below is an incomplete list of notification types.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeMeaning
0Expense added
1Expense updated
2Expense deleted
3Comment added
4Added to group
5Removed from group
6Group deleted
7Group settings changed
8Added as friend
9Removed as friend
10News (a URL should be included)
11Debt simplification
12Group undeleted
13Expense undeleted
14Group currency conversion
15Friend currency conversion
-

Note: While all parameters are optional, the server sets arbitrary (but large) limits -on the number of notifications returned if you set a very old updated_after value or limit of 0 for a -user with many notifications.

-
Authorizations:
OAuthApiKeyAuth
query Parameters
updated_after
string <date-time>
Example: updated_after=2020-07-28T20:46:00Z

If provided, returns only notifications after this time.

-
limit
integer
Default: 0

Omit (or provide 0) to get the maximum number of notifications.

-

Responses

Response samples

Content type
application/json
{
  • "notifications": [
    ]
}

Other

Supported currencies

Returns a list of all currencies allowed by the system. These are mostly ISO 4217 codes, but we do -sometimes use pending codes or unofficial, colloquial codes (like BTC instead of XBT for Bitcoin).

-

Responses

Response samples

Content type
application/json
{
  • "currencies": [
    ]
}

Supported categories

Returns a list of all categories Splitwise allows for expenses. There are parent categories that represent groups of categories with subcategories for more specific categorization. -When creating expenses, you must use a subcategory, not a parent category. -If you intend for an expense to be represented by the parent category and nothing more specific, please use the "Other" subcategory.

-

Responses

Response samples

Content type
application/json
{}
- - - - diff --git a/fonts/slate.eot b/fonts/slate.eot new file mode 100755 index 0000000..13c4839 Binary files /dev/null and b/fonts/slate.eot differ diff --git a/fonts/slate.svg b/fonts/slate.svg new file mode 100644 index 0000000..5f34982 --- /dev/null +++ b/fonts/slate.svg @@ -0,0 +1,14 @@ + + + +Generated by IcoMoon + + + + + + + + + + diff --git a/fonts/slate.ttf b/fonts/slate.ttf new file mode 100755 index 0000000..ace9a46 Binary files /dev/null and b/fonts/slate.ttf differ diff --git a/fonts/slate.woff b/fonts/slate.woff new file mode 100755 index 0000000..1e72e0e Binary files /dev/null and b/fonts/slate.woff differ diff --git a/fonts/slate.woff2 b/fonts/slate.woff2 new file mode 100755 index 0000000..7c585a7 Binary files /dev/null and b/fonts/slate.woff2 differ diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000..84672b6 Binary files /dev/null and b/images/favicon.ico differ diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 0000000..0d084f6 --- /dev/null +++ b/images/logo.svg @@ -0,0 +1,27 @@ + + + + Artboard Copy 2 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/navbar.png b/images/navbar.png new file mode 100644 index 0000000..df38e90 Binary files /dev/null and b/images/navbar.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..d4969bc --- /dev/null +++ b/index.html @@ -0,0 +1,2232 @@ + + + + + + + + Splitwise API Reference + + + + + + + + + + + + + NAV + + + +
+ +
+ ruby + javascript +
+ + +
+
  • + Introduction +
  • +
  • + Third-party SDKs +
  • +
  • + Authentication + +
  • +
  • + An important note about nested parameters +
  • +
  • + Users + +
  • +
  • + Groups + +
  • +
  • + Friends + +
  • +
  • + Expenses + +
  • +
  • + Comments + +
  • +
  • + Notifications + +
  • +
  • + Other API calls + +
  • +
  • + Errors +
  • +
  • + Terms of Use + +
  • +
    + +
    +
    +
    +
    +

    Introduction

    +

    Hey there! We're glad you're interested in the Splitwise API. This documentation will help you to fetch information on users, expenses, groups, and much more.

    + +

    If something in the API is confusing you, you can open an issue about it on GitHub. We're a small team, so we may not have an instant fix, but we'll get back to you as soon as we're able. (If you spot an issue in our API documentation itself, feel free to open a pull request to update this website!)

    +

    Third-party SDKs

    +

    The development community has built a number of unofficial, third-party SDKs for Splitwise in a variety of different languages.

    + + + +

    If you've built a third-party SDK for Splitwise and you'd like to see it included in this list, then please open a pull request to update this section and add a new link. Thank you for your work!

    + + +

    Authentication

    ###################
    +# OAuth 2 example #
    +###################
    +
    +#!/usr/bin/env ruby
    +require 'oauth2' # gem 'oauth2'
    +require 'pp'
    +
    +CONSUMER_KEY = <fill in your key>
    +CONSUMER_SECRET = <fill in your secret>
    +TOKEN_URL = 'https://secure.splitwise.com/oauth/token'
    +AUTHORIZE_URL = 'https://secure.splitwise.com/oauth/authorize'
    +MY_CALLBACK_URL = 'http://localhost:8080/callback' # Make sure to set the redirect URL that you registered with Splitwise when creating your app so that it matches this URL
    +BASE_SITE = 'https://secure.splitwise.com/'
    +
    +client = OAuth2::Client.new(CONSUMER_KEY, CONSUMER_SECRET, site: BASE_SITE)
    +authorize_url = client.auth_code.authorize_url(redirect_uri: MY_CALLBACK_URL)
    +# => "https://www.splitwise.com/oauth/authorize?response_type=code&client_id=#{CONSUMER_KEY}&redirect_uri=#{MY_CALLBACK_URL}
    +
    +require 'webrick'
    +require 'cgi'
    +
    +server = WEBrick::HTTPServer.new(
    +  Port: 8080,
    +  StartCallback: proc { puts "Opening 'localhost:8080'"; `open 'http://localhost:8080/'` })
    +
    +server.mount_proc "/" do |req, res|
    +  res.body = "<a href=\"#{authorize_url}\"> Get Code </a>"
    +end
    +
    +server.mount_proc "/callback" do |req, res|
    +  authorization_code = CGI.parse(req.query_string)['code']
    +  access_token = client.auth_code.get_token(
    +    authorization_code,
    +    redirect_uri: MY_CALLBACK_URL
    +  )
    +
    +  # This is your actual bearer token! Your bearer token will be printed out to the console.
    +  # You can then use that bearer token to make additional API requests to Splitwise. For example:
    +  # curl -XGET "http://secure.splitwise.com/api/v3.0/get_current_user" -H "Authorization: Bearer YOUR_TOKEN"
    +  puts "***"
    +  puts "Here is your OAuth Bearer token!"
    +  pp access_token.to_hash
    +  puts "***"
    +
    +  response = access_token.get('/api/v3.0/get_current_user')
    +  res.body = response.body
    +end
    +
    +# Triggered by ^C on os x; run `$ stty -a |grep intr` to find appropriate key combination
    +trap('INT') { server.stop }
    +server.start
    +
    +
    +###################
    +# OAuth 1 example #
    +###################
    +
    +#!/usr/bin/env ruby
    +require 'oauth' # gem oauth
    +
    +CONSUMER_KEY = <fill in your key>
    +CONSUMER_SECRET = <fill in your secret>
    +REQUEST_TOKEN_URL ='https://secure.splitwise.com/oauth/request_token'
    +ACCESS_TOKEN_URL = 'https://secure.splitwise.com/oauth/access_token'
    +AUTHORIZE_URL = 'https://secure.splitwise.com/oauth/authorize'
    +MY_CALLBACK_URL = 'http://localhost:8080/callback'
    +
    +consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, site: 'https://www.splitwise.com')
    +request_token = consumer.get_request_token(oauth_callback: MY_CALLBACK_URL)
    +# => "https://www.splitwise.com/oauth/authorize?oauth_token="#{request_token}"
    +
    +require 'webrick'
    +require 'cgi'
    +server = WEBrick::HTTPServer.new(
    +  Port: 8080,
    +  StartCallback: proc { puts "Opening 'localhost:8080'"; `open 'http://localhost:8080/'` })
    +
    +server.mount_proc "/" do |req, res|
    +  res.body = "<a href=\"#{request_token.authorize_url}\"> Get Code </a>"
    +end
    +
    +server.mount_proc "/callback" do |req, res|
    +  oauth_verifier = CGI.parse(req.query_string)['oauth_verifier'].first
    +  access_token = request_token.get_access_token(oauth_verifier: oauth_verifier)
    +  access_token.params.each do |k, v|
    +    puts "  #{k}: #{v}" unless k.is_a?(Symbol)
    +  end
    +  response = access_token.request(:get, '/api/v3.0/get_current_user')
    +  res.body = response.body
    +end
    +
    +# Triggered by ^C on os x; run `$ stty -a |grep intr` to find appropriate key combination
    +trap('INT') { server.stop }
    +server.start
    +
    ###################
    +# OAuth 2 example #
    +###################
    +
    +#!/usr/bin/env node
    +'use strict';
    +
    +const OAuth = require('oauth');
    +const {exec} = require('child_process');
    +const qs = require('querystring');
    +const http = require('http');
    +
    +const CONSUMER_KEY = <fill in your key>;
    +const CONSUMER_SECRET = <fill in your secret>;
    +const TOKEN_URL = '/oauth/token';
    +const AUTHORIZE_URL = '/oauth/authorize';
    +const MY_CALLBACK_URL = 'http://localhost:8080/callback';
    +const BASE_SITE = 'https://www.splitwise.com';
    +
    +var authURL;
    +const client = new OAuth.OAuth2(
    +  CONSUMER_KEY,
    +  CONSUMER_SECRET,
    +  BASE_SITE,
    +  AUTHORIZE_URL,
    +  TOKEN_URL,
    +  null);
    +
    +const server = http.createServer(function(req, res) {
    +  console.log(req.url);
    +  var p = req.url.split('/');
    +  console.log(p);
    +
    +  var pLen = p.length;
    +
    +  authURL = client.getAuthorizeUrl({
    +    redirect_uri: MY_CALLBACK_URL,
    +    response_type: 'code'
    +  });
    +
    +  /**
    +   * Creating an anchor with authURL as href and sending as response
    +   */
    +  var body = '<a href="' + authURL + '"> Get Code </a>';
    +  if (pLen === 2 && p[1] === '') {
    +    res.writeHead(200, {
    +      'Content-Length': body.length,
    +      'Content-Type': 'text/html'
    +    });
    +    res.end(body);
    +  } else if (pLen === 2 && p[1].indexOf('callback') === 0) {
    +    /** To obtain and parse code='...' from code?code='...' */
    +    var qsObj = qs.parse(p[1].split('?')[1]);
    +    console.log(qsObj.code);
    +    /** Obtaining access_token */
    +    client.getOAuthAccessToken(
    +      qsObj.code,
    +      {
    +        'redirect_uri': MY_CALLBACK_URL,
    +        'grant_type': 'authorization_code'
    +      },
    +      function(e, access_token, refresh_token, results) {
    +        if (e) {
    +          console.log(e);
    +          res.end(JSON.stringify(e));
    +        } else if (results.error) {
    +          console.log(results);
    +          res.end(JSON.stringify(results));
    +        }
    +        else {
    +          console.log('Obtained access_token: ', access_token);
    +          client.get('https://secure.splitwise.com/api/v3.0/get_current_user', access_token, function(e, data, response) {
    +            if (e) console.error(e);
    +            res.end(data);
    +          });
    +        }
    +      });
    +
    +  } else {
    +    // Unhandled url
    +  }
    +});
    +server.listen({port: 8080}, serverReady);
    +
    +function serverReady() {
    +  console.log(`Server on port ${server.address().port} is now up`);
    +  exec(`open http://localhost:8080/`, (err, stdout, stderr) => {
    +    if (err) {
    +      // node couldn't execute the command
    +      return;
    +    }
    +
    +    // the *entire* stdout and stderr (buffered)
    +    console.log(`stdout: ${stdout}`);
    +    console.log(`stderr: ${stderr}`);
    +  });
    +}
    +
    +module.exports = client;
    +
    +

    Splitwise uses OAuth for authentication. To connect via OAuth, you'll need to register your app on Splitwise. When you register, you'll be given a consumer key and a consumer secret, which can be used by your application to make requests to the Splitwise server.

    + + + +

    For more information on using OAuth, check out the following resources:

    + + +

    API keys

    GET /api/v3.0/get_current_user HTTP/1.1
    +Host: www.splitwise.com
    +Authorization: Bearer <your_token_here>
    +
    +

    For speed and ease of prototyping, you can generate a personal API key on your app's details page. You should present this key to the server via the Authorization header as a Bearer token. The API key is an access token for your personal account, so keep it as safe as you would a password.

    + +

    If your key becomes compromised or you want to invalidate your existing key for any other reason, you can do so on the app details page by generating a new key.

    +

    An important note about nested parameters

    +

    Due to a quirk in Splitwise's servers, nested parameters (e.g. users[1][first_name]) cannot currently be used when submitting a request. Instead, to indicate nested parameters, use double underscores (e.g. users__1__first_name). We hope to support proper nested parameters in future API versions.

    +

    Users

    + +

    get_current_user

    +
    +

    Example Response:

    +
    +
    {
    +  "user": {
    +    "id": 1,
    +    "first_name": "Ada",
    +    "last_name": "Lovelace",
    +    "picture": {
    +      "small": "image_url",
    +      "medium": "image_url",
    +      "large": "image_url"
    +    },
    +    "email": "ada@example.com",
    +    "registration_status": "confirmed",           //'dummy', 'invited', or 'confirmed'
    +    "default_currency": "USD",
    +    "locale": "en",
    +    "notifications_read": "2017-06-02T20:21:57Z", // the last time notifications were marked as read
    +    "notifications_count": 12,                    // the number of unread notifications
    +    "notifications": {                            // notification preferences
    +      "added_as_friend": true,
    +      // ...
    +    }
    +  }
    +}
    +
    +

    GET https://www.splitwise.com/api/v3.0/get_current_user

    + +

    Retrieve info about the user who is currently logged in.

    +

    get_user/:id

    +
    +

    Example Response:

    +
    +
    {
    +  "user": {
    +    "id": 1,
    +    "first_name": "Ada",
    +    "last_name": "Lovelace",
    +    "picture": {
    +      "small": "image_url",
    +      "medium": "image_url",
    +      "large": "image_url"
    +    },
    +    "email": "ada@example.com",
    +    "registration_status": "confirmed"           //'dummy', 'invited', or 'confirmed'
    +    }
    +  }
    +}
    +
    +

    GET https://www.splitwise.com/api/v3.0/get_user/:id

    + +

    Retrieve info about another user that the current user is acquainted with (e.g. they are friends, or they both belong to the same group).

    +

    update_user/:id

    +

    POST https://www.splitwise.com/api/v3.0/update_user/:id

    + +

    Update a specific user. A user can edit anything about their own account, and may edit the first_name, last_name, and email for any acquaintances who have not logged in yet.

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    first_nameStringUser's first name
    last_nameStringUser's last name
    emailStringUser's email address
    passwordStringUser's password
    localeStringUser's locale (ISO 639-1)
    date_formatStringPreferred Date Format (e.g. MM/DD/YYYY or
    default_currencyStringUser's default currency (ISO 4217)
    default_group_idStringDefault Group ID (set -1 for none)
    notification_settingsObject
    { notification_type: bool, ... }
    Set notification types on or off: added_as_friend, added_to_group, expense_added, expense_updated, bills, payments, monthly_summary, announcements,}
    +

    Groups

    +

    A Group represents a collection of users who share expenses together. For example, some users use a Group to aggregate expenses related to an apartment. Others use it to represent a trip. Expenses assigned to a group are split among the users of that group. Importantly, two users in a Group can also have expenses with one another outside of the Group.

    +

    get_groups

    +
    +

    Example Response:

    +
    +
    {
    +  "groups":[
    +    // Non-group expenses are listed in a group with id 0
    +    {
    +      "id":0,
    +      "name":"Non-group expenses",
    +      "updated_at": "2017-08-30T20:31:51Z", //<current time in UTC>
    +      "members":[
    +        {
    +            "id": 1,
    +            "first_name": "Ada",
    +            "last_name": "Lovelace",
    +            "picture": {
    +              "small": "image_url",
    +              "medium": "image_url",
    +              "large": "image_url"
    +            },
    +            "email": "ada@example.com",
    +            "registration_status": "confirmed",          //'dummy', 'invited', or 'confirmed'
    +            "balance":[
    +               {
    +                  "currency_code":"AED",
    +                  "amount":"0.0"
    +               },
    +               {
    +                  "currency_code":"ALL",
    +                  "amount":"0.0"
    +               },
    +               {
    +                  "currency_code":"EUR",
    +                  "amount":"-5.0"
    +               },
    +               {
    +                  "currency_code":"USD",
    +                  "amount":"3730.5"
    +               } //, ...
    +            ]
    +         } // , ...
    +      ],
    +      "simplify_by_default":false,
    +      "original_debts":[
    +         {
    +            "from": 12345,          // user_id
    +            "to": 54321,            // user_id
    +            "amount":"414.5",       // amount as a decimal string
    +            "currency_code":"USD"   // three-letter currency code
    +         } // , ...
    +      ]
    +    },
    +    {
    +      "id":3018312,
    +      "name":"a test group",
    +      "updated_at":"2017-08-30T20:31:51Z",
    +      "members":[ /* <User object> , <User object>, ... */ ],
    +      "simplify_by_default":false,
    +      "original_debts":[
    +         {
    +            "from": 12345,          // user_id
    +            "to": 54321,            // user_id
    +            "amount":"414.5",       // amount as a decimal string
    +            "currency_code":"USD"   // three-letter currency code
    +         } // , ...
    +      ],
    +      "simplified_debts":[
    +         {
    +            "from": 12345,          // user_id
    +            "to": 54321,            // user_id
    +            "amount":"414.5",       // amount as a decimal string
    +            "currency_code":"USD"   // three-letter currency code
    +         } // , ...
    +      ],
    +      "whiteboard":"a message!",
    +      "group_type":"apartment",
    +      "invite_link":"https://www.splitwise.com/join/abcdef1232456"
    +    } // , ...
    +}
    +
    +

    GET https://www.splitwise.com/api/v3.0/get_groups

    + +

    Returns list of all groups that the current_user belongs to

    +

    get_group/:id

    +
    +

    Example Response:

    +
    +
    {
    +  "group":
    +    {
    +      "id":3018312,
    +      "name":"a test group",
    +      "updated_at":"2017-08-30T20:31:51Z",
    +      "members":[ /* <User object> , <User object>, ... */ ],
    +      "simplify_by_default":false,
    +      "original_debts":[
    +         {
    +            "from": 12345,          // user_id
    +            "to": 54321,            // user_id
    +            "amount":"414.5",       // amount as a decimal string
    +            "currency_code":"USD"   // three-letter currency code
    +         } // , ...
    +      ],
    +      "simplified_debts":[
    +         {
    +            "from": 12345,          // user_id
    +            "to": 54321,            // user_id
    +            "amount":"414.5",       // amount as a decimal string
    +            "currency_code":"USD"   // three-letter currency code
    +         } // , ...
    +      ],
    +      "whiteboard":"a message!",
    +      "group_type":"apartment",
    +      "invite_link":"https://www.splitwise.com/join/abcdef1232456"
    +    }
    +}
    +
    +

    GET https://www.splitwise.com/api/v3.0/get_group/:id

    + +

    Returns information about the specified group (as long as the current user has access)

    +

    create_group

    +
    +

    Example Response:

    +
    +
    {
    +  "group":
    +    {
    +      "id":3018312,
    +      "name":"a test group",
    +      "updated_at":"2017-08-30T20:31:51Z",
    +      "members":[ /* <User object> , <User object>, ... */ ],
    +      "simplify_by_default":false,
    +      "original_debts":[],
    +      "simplified_debts":[],
    +      "whiteboard":"a message!",
    +      "group_type":"apartment",
    +      "invite_link":"https://www.splitwise.com/join/abcdef1232456",
    +      // or if create failed
    +      "errors": ["something went wrong", "with your group"]
    +    }
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/create_group

    + +

    Create a new group. Adds the current user to the group by default.

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    nameStringGroup name
    whiteboardStringText to display on the group whiteboard
    group_typeStringWhat the group is being used for. Must be one of: apartment, house, trip, other.
    simplify_by_defaultBooleanTurn on simplify debts?
    users__0__first_nameStringAdd a user's first name
    users__0__last_nameStringAdd a user's last name
    users__0__emailStringAdd a user's email
    users__1__user_idIntegerAdd an existing user by id
    +

    delete_group/:id

    +
    +

    Example Response:

    +
    +
    {
    +  "success": true, // or false
    +  "errors": ["any errors"]
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/delete_group/:id

    + +

    Delete an existing group. Destroys all associated records (expenses, etc.)

    +

    undelete_group/:id

    +
    +

    Example Response:

    +
    +
    {
    +  "success": true, //or false
    +  "errors": ["any errors"]
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/undelete_group/:id

    +

    add_user_to_group

    +
    +

    Example Response:

    +
    +
    {
    +  "success": true, //or false
    +  "errors": ["any errors"]
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/add_user_to_group

    + +

    Add a user to a group

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    group_idIntegerExisting group to add the user to
    first_nameStringAdd a user's first name
    last_nameStringAdd a user's last name
    emailStringAdd a user's email
    user_idIntegerAdd an existing user by id
    +

    remove_user_from_group

    +
    +

    Example Response:

    +
    +
    {
    +  "success": true, //or false
    +  "errors": ["any errors"]
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/remove_user_from_group

    + +

    Remove a user from a group if their balance is 0

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    group_idIntegerGroup to remove the user from
    user_idIntegerId of user to remove
    +

    Friends

    +

    Friends of a user are other users with whom the user splits expenses. To split expenses with one another, users must be friends. Users in a group together are automatically made friends. Many of the calls containing the word “friend” return objects representing friends of the current user. In addition to containing the user data, these objects contain information about the current user's balance with each friend.

    +

    get_friends

    +
    +

    Example Response:

    +
    +
    {
    +  "friends":[
    +    {
    +      "id": 1,
    +      "first_name": "Ada",
    +      "last_name": "Lovelace",
    +      "picture": {
    +        "small": "image_url",
    +        "medium": "image_url",
    +        "large": "image_url"
    +      },
    +      "balance":[
    +        {
    +          "currency_code":"USD",
    +          "amount":"-1794.5"
    +        },
    +        {
    +          "currency_code":"AED",
    +          "amount":"7.5"
    +        }
    +      ],
    +      "groups":[ // group objects only include group balances with that friend
    +        {
    +          "group_id":3018312,
    +          "balance":[
    +            {
    +              "currency_code":"USD",
    +              "amount":"414.5"
    +            }
    +          ]
    +        },
    +        {
    +          "group_id":2830896,
    +          "balance":[
    +          ]
    +        },
    +        {
    +          "group_id":0,
    +          "balance":[
    +            {
    +              "currency_code":"USD",
    +              "amount":"-2209.0"
    +            },
    +            {
    +              "currency_code":"AED",
    +              "amount":"7.5"
    +            }
    +          ]
    +        }
    +      ],
    +      "updated_at":"2017-11-30T09:41:09Z"
    +    } // , ...
    +  ]
    +}
    +
    +

    GET https://www.splitwise.com/api/v3.0/get_friends

    + +

    Returns a list of the current user's friends.

    +

    get_friend/:id

    +
    +

    Example Response:

    +
    +
    {
    +  "friend":
    +    {
    +      "id": 1,
    +      "first_name": "Ada",
    +      "last_name": "Lovelace",
    +      "picture": {
    +        "small": "image_url",
    +        "medium": "image_url",
    +        "large": "image_url"
    +      },
    +      "registration_status": "confirmed", // or 'dummy' or 'invited'
    +      "balance":[
    +        {
    +          "currency_code":"USD",
    +          "amount":"-1794.5"
    +        },
    +        {
    +          "currency_code":"AED",
    +          "amount":"7.5"
    +        }
    +      ],
    +      "groups":[
    +        {
    +          "group_id":3018312,
    +          "balance":[
    +            {
    +              "currency_code":"USD",
    +              "amount":"414.5"
    +            }
    +          ]
    +        },
    +        {
    +          "group_id":2830896,
    +          "balance":[
    +          ]
    +        },
    +        {
    +          "group_id":0,
    +          "balance":[
    +            {
    +              "currency_code":"USD",
    +              "amount":"-2209.0"
    +            },
    +            {
    +              "currency_code":"AED",
    +              "amount":"7.5"
    +            }
    +          ]
    +        }
    +      ],
    +      "updated_at":"2017-11-30T09:41:09Z"
    +    }
    +  }
    +}
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_friend/:id

    + +

    Get detailed info on one friend of current_user.

    +

    create_friend

    +
    +

    Example Response: same as get_friend response

    +
    + +

    POST https://secure.splitwise.com/api/v3.0/create_friend

    + +

    Makes the current user a friend of a user specified with the url parameters user_email, user_first_name, and, optionally, user_last_name.

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    user_first_nameStringAdd a user's first name
    user_last_nameStringAdd a user's last name
    user_emailStringAdd a user's email (or find an existing user by email)
    +

    create_friends

    +
    +

    Example Response: same as get_friends response

    +
    + +

    POST https://secure.splitwise.com/api/v3.0/create_friends

    + +

    Make the current user a friend of the specified users.

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    friends__0__user_first_nameStringAdd a user's first name
    friends__0__user_last_nameStringAdd a user's last name
    friends__0__user_emailStringAdd a user's email (or find an existing user by email)
    friends__1__user_emailStringFind an existing user by email)
    +

    delete_friend/:id

    +
    +

    Example Response:

    +
    +
    {
    +  "success": true, //or false
    +  "errors": ["any errors"]
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/delete_friend/:id

    + +

    Given a friend ID, break off the friendship between the current user and the specified user.

    +

    Expenses

    get_expense/:id

    +

    Return full details on an expense involving the current user. There are some additional values included in the expense object than shown here but they should be ignored.

    +
    {
    +  "expense": {
    +    "id": 368887,
    +    "group_id": 18417, //or null
    +    "description": "Grocery run",
    +    "repeats": false,
    +    "repeat_interval": "never", //or "weekly", "fortnightly", "monthly", "yearly"
    +    "email_reminder": false,
    +    "email_reminder_in_advance": -1, // or 0, 1, 3, 5, 7, 14
    +    "next_repeat": null,
    +    "details": "Additional notes about the expense",
    +    "comments_count": 0,
    +    "payment": false,
    +    "transaction_confirmed": false,
    +    "cost": "25.0",
    +    "currency_code": "USD",
    +    "repayments": [
    +      {
    +        "from": 6788709,
    +        "to": 270896089,
    +        "amount": "25.0"
    +      }
    +    ],
    +    "date": "2012-07-27T06:17:09Z",
    +    "created_at": "2012-07-27T06:17:09Z",
    +    "created_by": { /* <user object> */ },
    +    "updated_at": "2012-12-23T05:47:02Z",
    +    "updated_by": { /* <user object> */ },
    +    "deleted_at": "2012-12-23T05:47:02Z",
    +    "deleted_by": { /* <user object> */ },
    +    "category": {
    +      "id": 18,
    +      "name": "General"
    +    },
    +    "receipt": {
    +      "large": "https://splitwise.s3.amazonaws.com/uploads/expense/receipt/3678899/large_95f8ecd1-536b-44ce-ad9b-0a9498bb7cf0.png",
    +      "original": "https://splitwise.s3.amazonaws.com/uploads/expense/receipt/3678899/95f8ecd1-536b-44ce-ad9b-0a9498bb7cf0.png"
    +    },
    +    "users": [
    +      {
    +        "user": { /* <user object> */ },
    +        "user_id": 270896089,
    +        "paid_share": "25.0",
    +        "owed_share": "0.0",
    +        "net_balance": "25.0"
    +      },
    +      {
    +        "user": { /* <user object> */ },
    +        "user_id": 6788709,
    +        "paid_share": "0.0",
    +        "owed_share": "25.0",
    +        "net_balance": "-25.0"
    +      }
    +    ],
    +    "comments": [ /* <comment object>, <comment object>,... */ ]
    +  }
    +}
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_expense/:id

    +

    get_expenses

    +

    Return expenses involving the current user, in reverse chronological order

    +
    {
    +  "expenses": [ /* <expense object>, <expense object>, ... */ ],
    +}
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_expenses

    +

    Query parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    group_idIntegerReturn expenses for specific group
    friend_idIntegerReturn expenses for a specific friend that are not in any group
    dated_afterTimeISO 8601 Date time. Return expenses later than this date
    dated_beforeTimeISO 8601 Date time. Return expenses earlier than this date
    updated_afterTimeISO 8601 Date time. Return expenses updated after this date
    updated_beforeTimeISO 8601 Date time. Return expenses updated before this date
    limitIntegerHow many expenses to fetch. Defaults to 20; set to 0 to fetch all
    offsetIntegerReturn expenses starting at limit * offset
    +

    create_expense

    {
    +  "expense": { /* <expense object> */ },
    +  "errors": { }
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/create_expense

    +

    Query parameters

    Required

    + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    costStringA string representation of a decimal value, limited to 2 decimal places
    descriptionStringA short description of the expense
    paymentBooleantrue if this is a payment, false otherwise
    +

    Split configuration

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    group_idIntegerThe group to put this expense in.
    split_equallyBooleanSet this to true if using it
    users__0__user_idIntegerThe user id of a friend for this share
    users__0__paid_shareStringDecimal amount as a string with 2 decimal places. The amount this user paid for the expense
    users__0__owed_shareStringDecimal amount as a string with 2 decimal places. The amount this user owes on the expense
    users__1__first_nameString
    users__1__last_nameString
    users__1__emailStringValid email address for this user
    users__1__paid_shareStringDecimal amount as a string with 2 decimal places. The amount this user paid for the expense
    users__1__owed_shareStringDecimal amount as a string with 2 decimal places. The amount this user owes on the expense
    users__*__key_valueStringAdd additional user shares with indexes 2,3,4,5,...
    +

    Optional parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    group_idIntegerThe group to put the expense in
    detailsStringMore detailed notes
    dateTimeISO 8601 date time
    repeat_intervalStringOne of: never, weekly, fortnightly, monthly, yearly
    currency_codeStringISO 4217 currency code. Must be in the list from get_currencies
    category_idIntegerA category id from get_categories
    +

    update_expense/:id

    {
    +  "expense": { /* <expense object> */ },
    +  "errors": { }
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/update_expense/:id

    +

    Query parameters

    +

    These are the same as for create_expense except you only need to include parameters that are changing from the previous values.

    +

    delete_expense/:id

    {
    +  "success": true, //or false
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/delete_expense/:id

    +

    undelete_expense/:id

    {
    +  "success": true, //or false
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/undelete_expense/:id

    +

    Comments

    get_comments?expense_id=:id

    {
    +  "comments": [
    +    {
    +      "id": 79800950,
    +      "content": "Something about this expense",
    +      "comment_type": "User",
    +      "relation_type": "ExpenseComment",
    +      "relation_id": 855870953,
    +      "created_at": "2020-05-14T04:12:25Z",
    +      "deleted_at": null,
    +      "user": { /* <user object> */ }
    +    }
    +  ]
    +}
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_comments?expense_id=:id

    +

    create_comment

    {
    +  "comment": { /* <comment object> */ },
    +  "errors": {}
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/create_comment

    +

    Query parameters

    + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    expense_idIntegerThe expense the comment is for
    contentStringThe comment contents
    +

    delete_comment

    {
    +  "comment": { /* <comment object> */ },
    +  "errors": {}
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/delete_comment/:id

    +

    Query parameters

    + + + + + + + + + + + + +
    ParameterTypeDescription
    idIntegerThe comment id
    +

    Notifications

    get_notifications

    {
    +  "notifications": [
    +    {
    +      "id": 32514315,
    +      "type": 0,
    +      "created_at": "2020-05-13T20:58:17Z",
    +      "created_by": 2,
    +      "source": {
    +        "type": "Expense",
    +        "id": 865077,
    +        "url": null
    +      },
    +      "image_url": "https://s3.amazonaws.com/splitwise/uploads/notifications/v2/0-venmo.png",
    +      "image_shape": "square",
    +      "content": "<strong>You</strong> paid <strong>Jon H.</strong>.<br><font color=\"#5bc5a7\">You paid $23.45</font>"
    +    } //, ...
    +  ]
    +}
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_notifications

    + +

    Return a list of recent activity on the users account with the most recent items first. content will be suitable for display in HTML and uses only the <strong>, <strike>, <small>, <br> and <font color="#FFEE44"> tags.

    + +

    The type value indicates what the notification is about. Notification types may be added in the future without warning. Below is an incomplete list of notification types.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeMeaning
    0Expense added
    1Expense updated
    2Expense deleted
    3Comment added
    4Added to group
    5Removed from group
    6Group deleted
    7Group settings changed
    8Added as friend
    9Removed as friend
    10News (a URL should be included)
    11Debt simplification
    12Group undeleted
    13Expense undeleted
    14Group currency conversion
    15Friend currency conversion
    +

    Query parameters

    + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    updated_afterTimeISO 8601 Date and time string with timezone offset. Return notifications after this time.
    limitIntegerHow many notifications to fetch. Defaults to 20. 0 for all.
    +

    Other API calls

    get_currencies

    {
    +  "currencies":[
    +    { "currency_code":"USD", "unit":"$" },
    +    { "currency_code":"ARS", "unit":"$" },
    +    { "currency_code":"AUD", "unit":"$" },
    +    { "currency_code":"EUR", "unit":"€" },
    +    { "currency_code":"BRL", "unit":"R$" },
    +    { "currency_code":"CAD", "unit":"$" },
    +    { "currency_code":"CNY", "unit":"¥" },
    +    { "currency_code":"DKK", "unit":"kr" },
    +    { "currency_code":"GBP", "unit":"£" },
    +    { "currency_code":"INR", "unit":"₹" },
    +    { "currency_code":"ILS", "unit":"₪" },
    +    { "currency_code":"JPY", "unit":"¥" },
    +    { "currency_code":"MXN", "unit":"$" },
    +    { "currency_code":"NZD", "unit":"$" },
    +    { "currency_code":"PHP", "unit":"₱" },
    +    { "currency_code":"RUB", "unit":"₽" },
    +    { "currency_code":"SGD", "unit":"$" },
    +    { "currency_code":"SEK", "unit":"kr" },
    +    { "currency_code":"CHF", "unit":"Fr." },
    +    { "currency_code":"MYR", "unit":"RM" },
    +    { "currency_code":"RON", "unit":"RON" },
    +    { "currency_code":"ZAR", "unit":"R" },
    +    { "currency_code":"LKR", "unit":"Rs. " },
    +    { "currency_code":"NAD", "unit":"$" },
    +    { "currency_code":"SAR", "unit":"SR" },
    +    { "currency_code":"AED", "unit":"DH" },
    +    { "currency_code":"PLN", "unit":"PLN" },
    +    { "currency_code":"HRK", "unit":"HRK" },
    +    { "currency_code":"PKR", "unit":"Rs" },
    +    { "currency_code":"TWD", "unit":"NT$" },
    +    { "currency_code":"VEF", "unit":"Bs" },
    +    { "currency_code":"HUF", "unit":"Ft" },
    +    { "currency_code":"CLP", "unit":"$" },
    +    { "currency_code":"BDT", "unit":"Tk" },
    +    { "currency_code":"CZK", "unit":"Kč" },
    +    { "currency_code":"COP", "unit":"$" },
    +    { "currency_code":"TRY", "unit":"TL" },
    +    { "currency_code":"KRW", "unit":"₩" },
    +    { "currency_code":"BOB", "unit":"Bs." },
    +    { "currency_code":"VND", "unit":"₫" },
    +    { "currency_code":"NOK", "unit":"kr" },
    +    { "currency_code":"EGP", "unit":"E£" },
    +    { "currency_code":"HKD", "unit":"$" },
    +    { "currency_code":"THB", "unit":"฿" },
    +    { "currency_code":"KES", "unit":"KSh" },
    +    { "currency_code":"IDR", "unit":"Rp " },
    +    { "currency_code":"ISK", "unit":"kr" },
    +    { "currency_code":"BTC", "unit":"฿" },
    +    { "currency_code":"UAH", "unit":"₴" },
    +    { "currency_code":"MVR", "unit":"MVR" },
    +    { "currency_code":"OMR", "unit":"OMR" },
    +    { "currency_code":"YER", "unit":"YER" },
    +    { "currency_code":"IRR", "unit":"IRR" },
    +    { "currency_code":"QAR", "unit":"QR" },
    +    { "currency_code":"BHD", "unit":"BD" },
    +    { "currency_code":"TZS", "unit":"TZS" },
    +    { "currency_code":"RSD", "unit":"RSD" },
    +    { "currency_code":"ETB", "unit":"Br" },
    +    { "currency_code":"BGN", "unit":"BGN" },
    +    { "currency_code":"FJD", "unit":"$" },
    +    { "currency_code":"JMD", "unit":"J$" },
    +    { "currency_code":"UYU", "unit":"$" },
    +    { "currency_code":"GTQ", "unit":"Q" },
    +    { "currency_code":"NPR", "unit":"Rs. " },
    +    { "currency_code":"PEN", "unit":"S/. " },
    +    { "currency_code":"DJF", "unit":"Fdj " },
    +    { "currency_code":"LTL", "unit":"Lt " },
    +    { "currency_code":"MKW", "unit":"MK" },
    +    { "currency_code":"KWD", "unit":"KWD" },
    +    { "currency_code":"CRC", "unit":"₡" },
    +    { "currency_code":"DOP", "unit":"$" },
    +    { "currency_code":"NGN", "unit":"₦" },
    +    { "currency_code":"JOD", "unit":"JOD" },
    +    { "currency_code":"MAD", "unit":"MAD" },
    +    { "currency_code":"RWF", "unit":"FRw" },
    +    { "currency_code":"UGX", "unit":"USh" },
    +    { "currency_code":"AOA", "unit":"Kz" },
    +    { "currency_code":"XAF", "unit":"CFA" },
    +    { "currency_code":"XOF", "unit":"CFA" },
    +    { "currency_code":"CMG", "unit":"CMg" },
    +    { "currency_code":"ANG", "unit":"NAf" },
    +    { "currency_code":"ALL", "unit":"L" },
    +    { "currency_code":"PYG", "unit":"₲" },
    +    { "currency_code":"KYD", "unit":"CI$" },
    +    { "currency_code":"KZT", "unit":"₸" },
    +    { "currency_code":"BAM", "unit":"KM" },
    +    { "currency_code":"AWG", "unit":"Afl." },
    +    { "currency_code":"BIF", "unit":"FBu" },
    +    { "currency_code":"MKD", "unit":"ден" },
    +    { "currency_code":"XPF", "unit":"F" },
    +    { "currency_code":"GEL", "unit":"GEL" },
    +    { "currency_code":"TND", "unit":"DT" },
    +    { "currency_code":"MZN", "unit":"MT" },
    +    { "currency_code":"BYR", "unit":"BYR" },
    +    { "currency_code":"TTD", "unit":"TT$" },
    +    { "currency_code":"XCD", "unit":"EC$" },
    +    { "currency_code":"LBP", "unit":"ل.ل" },
    +    { "currency_code":"LAK", "unit":"₭" },
    +    { "currency_code":"MOP", "unit":"MOP$" },
    +    { "currency_code":"GHS", "unit":"GH₵" },
    +    { "currency_code":"UZS", "unit":"UZS" },
    +    { "currency_code":"NIO", "unit":"C$" },
    +    { "currency_code":"AZN", "unit":"m." },
    +    { "currency_code":"ZMW", "unit":"ZMW" },
    +    { "currency_code":"SZL", "unit":"E" },
    +    { "currency_code":"BWP", "unit":"P" },
    +    { "currency_code":"MMK", "unit":"K" },
    +    { "currency_code":"CVE", "unit":"$" },
    +    { "currency_code":"MUR", "unit":"₨" },
    +    { "currency_code":"SCR", "unit":"SR" },
    +    { "currency_code":"KHR", "unit":"៛" },
    +    { "currency_code":"CUP", "unit":"$" },
    +    { "currency_code":"CUC", "unit":"CUC$" },
    +    { "currency_code":"STD", "unit":"Db" },
    +    { "currency_code":"HNL", "unit":"L" },
    +    { "currency_code":"AMD", "unit":"AMD" },
    +    { "currency_code":"MDL", "unit":"MDL" },
    +    { "currency_code":"MNT", "unit":"₮" },
    +    { "currency_code":"BYN", "unit":"Br" },
    +    { "currency_code":"MGA", "unit":"Ar" },
    +    { "currency_code":"BBD", "unit":"$" },
    +    { "currency_code":"KMF", "unit":"CF" },
    +    { "currency_code":"IQD", "unit":"IQD" },
    +    { "currency_code":"BZD", "unit":"BZ$" },
    +    { "currency_code":"GYD", "unit":"G$" },
    +    { "currency_code":"SRD", "unit":"$" },
    +    { "currency_code":"KGS", "unit":"KGS" },
    +    { "currency_code":"TJS", "unit":"TJS" },
    +    { "currency_code":"VUV", "unit":"Vt" },
    +    { "currency_code":"BTN", "unit":"Nu." },
    +    { "currency_code":"WST", "unit":"WS$" }
    +  ] }
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_currencies

    + +

    Returns a list of all currencies allowed by the system. These are mostly ISO 4217 codes, but we do sometimes use pending codes or unofficial, colloquial codes (like BTC instead of XBT for Bitcoin)

    +

    get_categories

    {
    +  "categories": [
    +    {
    +      "id": 19,
    +      "name": "Entertainment",
    +      "icon": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square/entertainment/other.png",
    +      "icon_types": {
    +        "slim": {
    +          "small": "https://s3.amazonaws.com/splitwise/uploads/category/icon/slim/entertainment/other.png",
    +          "large": "https://s3.amazonaws.com/splitwise/uploads/category/icon/slim/entertainment/other@2x.png"
    +        },
    +        "square": {
    +          "large": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/entertainment/other@2x.png",
    +          "xlarge": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/entertainment/other@3x.png"
    +        }
    +      },
    +      "subcategories": [
    +        {
    +          "id": 20,
    +          "name": "Games",
    +          "icon": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square/entertainment/games.png",
    +          "icon_types": {
    +            "slim": {
    +              "small": "https://s3.amazonaws.com/splitwise/uploads/category/icon/slim/entertainment/games.png",
    +              "large": "https://s3.amazonaws.com/splitwise/uploads/category/icon/slim/entertainment/games@2x.png"
    +            },
    +            "square": {
    +              "large": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/entertainment/games@2x.png",
    +              "xlarge": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/entertainment/games@3x.png"
    +            }
    +          }
    +        },
    +        {
    +          "id": 21,
    +          "name": "Movies",
    +          "icon": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square/entertainment/movies.png",
    +          "icon_types": {
    +            "slim": {
    +              "small": "https://s3.amazonaws.com/splitwise/uploads/category/icon/slim/entertainment/movies.png",
    +              "large": "https://s3.amazonaws.com/splitwise/uploads/category/icon/slim/entertainment/movies@2x.png"
    +            },
    +            "square": {
    +              "large": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/entertainment/movies@2x.png",
    +              "xlarge": "https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/entertainment/movies@3x.png"
    +            }
    +          }
    +        } //, ...
    +      ]
    +    } //, ...
    +  ]
    +}
    +
    +

    GET https://secure.splitwise.com/api/v3.0/get_categories

    + +

    Returns a list of all categories Splitwise allows for expenses. There are parent categories that represent groups of categories with subcategories for more specific categorization. You may not use the parent categories when creating expenses. If you intend for an expense to be represented by the parent category and nothing more specific, please use the "Other" subcategory.

    +

    parse_sentence

    {
    +  "expense": { /* <Expense object> */ },
    +  "valid": true, //or false
    +  "error": "an error message"
    +}
    +
    +

    POST https://secure.splitwise.com/api/v3.0/parse_sentence

    + +

    Attempts to create an expense from the input as an English natural language phrase like "groceries $20" or "Jon paid me $50". If valid is true, the expense value will be a complete and valid expense. If it is false, the expense value may be missing some values.

    +

    Query Parameters

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    inputStringA natural language sentence describing an expense
    group_idIntegerA group id
    friend_idIntegerA friend id
    autosaveBooleanIf true, will save the resulting expense if valid. Defaults to false.
    +

    Errors

    +

    In general, the Splitwise API returns the following error codes:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Error CodeMeaning
    400Bad Request. Something about the request was invalid, and you will probably need to change your request before trying again.
    401Unauthorized. You are not logged in — your OAuth authentication may not be configured correctly.
    403Forbidden. The current user is not allowed to perform this action.
    404Not Found. The endpoint that you were trying to call does not exist.
    500Internal Server Error. Our server had an unexpected error while trying to process your request. This may be a temporary problem, or there may be a problem with your request that is causing the server to crash.
    503Service Unavailable. We're temporarily offline for maintenance. Please try again later.
    + +

    In addition, even when a call is successful and returns a 200 OK HTTP response, the body of the response may include a key called error or errors. This is usually used to communicate validation errors. For example, if you submit an expense without any cost, we may return an errors key as part of the JSON response.

    + +

    The format of these errors is somewhat inconsistent, unfortunately. We're working on standardizing it, but it's a work in progress.

    +

    Terms of Use

    Overview

    +

    Splitwise provides this Self-Serve API to facilitate integrations with third-party applications, as well as open-up functionality for hobbyists and power users to programmatically interact with their own Splitwise account and build plugins or other tools.

    + +

    If you’re interested in integrating your commercial application with Splitwise, we strongly encourage you to contact developers@splitwise.com so our development team can help discuss your use case, provide private APIs and Enterprise support, and offer an appropriate commercial license for the integration. The Self-Serve API documented here may be suitable for internal prototyping and other exploratory work.

    + +

    If you are developing a non-commercial plugin application or personal project, we recommend you make use of the Self-Serve API documented here under the API Terms Of Use. Please be aware that our Self-Serve API has conservative rate and access limits, which are subject to change at any time and not well suited to commercial projects. If this is a problem for your use case, please contact us at developers@splitwise.com to discuss your needs.

    + +

    All Self-Service API users are subject to the API Terms of Use below.

    +

    TERMS OF USE

    +

    These API Terms of Use describe your rights and responsibilities when accessing our publicly available Application Programming Interface (API) and related API documentation. Please review them carefully.

    + +

    Splitwise may modify this Agreement at any time by posting a revised version on our website. The revised version will be effective at the time that it is posted.

    + +

    These API terms form a binding contract between you and us. In these terms "you," and "your," refers to the individual, company or legal entity and/or entities that you represent while accessing the API. “We”, “us”, “our” and “Splitwise” refers to Splitwise Inc. By accepting these API terms, either by accessing or using the API, or authorizing or permitting any individual to access or use the API, you agree to be bound by this contract.

    + +
      +
    1. + API License: +
        +
      1. + Subject to the restrictions in these terms, we grant you a non-exclusive, revocable, worldwide, non-transferable, non-sublicensable, limited license to access and use (i) our APIs (ii) related API documentation, packages, sample code, software, or materials made available by Splitwise (“API Documentation”), and (iii) any and all access keys or data derived or obtained from Splitwise API responses (“Splitwise Data”). The Splitwise API, Splitwise Data, and API Documentation will be together referred to as the “Splitwise Materials.” You will use Splitwise Materials solely as necessary to develop, test and support a Self-Service integration of your software application (an "Application" or "App") with Splitwise in accordance with this Agreement and any other agreements between You and Splitwise. +
      2. +
      +
    2. +
    3. + API License Restrictions +
        +
      1. + You agree that will you will not, and will not allow any of your partners, subsidiaries and/or affiliates and each of their respective directors, officers, employees, agents, partners, suppliers, service providers, contractors or end users (collectively, “Your Affiliates”) to engage in any Prohibited Activities set forth in section 2f. +
      2. +
      3. + Splitwise reserves the right to block or revoke, with or without notice, your access to any or all of the Splitwise Materials if Splitwise determines in its sole discretion that you are engaging in any of the Prohibited Activities. +
      4. +
      5. + Splitwise may monitor your use of Splitwise Materials to improve our services and ensure compliance with this agreement, and may suspend your access to Splitwise Materials if we believe you are in violation. +
      6. +
      7. + Your use of the Splitwise API is subject to usage limits and other functional restrictions in the sole discretion of Splitwise. You will not use the API in a manner that exceeds rate limits, or constitutes excessive or abusive usage. +
      8. +
      9. + Your use of Splitwise Materials must respect Splitwise user’s privacy choices and settings and the Privacy portion of this agreement. You will obtain explicit consent from end users as a basis for any processing of Splitwise Materials. Your use of Splitwise Materials must comply with all Applicable Data Protection Laws applicable to you, including but not limited to GDPR and CCPA compliance. +
      10. +
      11. + Prohibited Activities: +
          +
        1. + You will not use Splitwise Materials or any part thereof in any manner or for any purpose that violates any law or regulation, or any right of any person, including but not limited to intellectual property rights, rights of privacy and/or publicity, or which otherwise results in liability to Splitwise, or its officers, employees, or end users. +
        2. +
        3. + You will not use Splitwise Materials in a way that poses a security, operational or technical risk to our Services. +
        4. +
        5. + You may not Splitwise Materials to create an application that replicates existing Splitwise functionality or competes with Splitwise and our Services. +
        6. +
        7. + You will not use Splitwise Materials to create an application that encourages or creates functionality for users to violate our Terms of Service. +
        8. +
        9. + You will not use Splitwise Materials to create an application that can be used by anyone under the age of 13. You will not knowingly collect or enable the collection of any personal information from children under the age of 13. +
        10. +
        11. + You will not reverse engineer, decompile, disassemble, or otherwise attempt to derive the source code or underlying ideas, trade secrets, algorithms or structure of the Splitwise Materials, or Splitwise software applications. +
        12. +
        13. + You will not attempt to defeat, avoid, bypass, remove, deactivate or otherwise circumvent any software protection mechanisms in the Splitwise Materials or Application or any part thereof, including without limitation, any such mechanism used to restrict or control the functionality of the API. +
        14. +
        15. + You will not use Splitwise’s name to endorse or promote any product, including a product derived from Splitwise Materials. +
        16. +
        17. + You will not sell, lease, rent, sublicense or in any way otherwise commercialize any Splitwise Data, or dataset derived from Splitwise Data and/or Splitwise Materials. +
        18. +
        19. + You will not use Splitwise Materials in applications that send unsolicited communications to users or include any malware, adware, potentially unwanted programs, or similar applications that could damage or disparage Splitwise’s reputation or services. +
        20. +
        +
      +
    4. +
    5. + Privacy +
        +
      1. + Your Application shall have a lawful privacy policy, accessible with reasonably prominent hyperlinks that does not conflict with or supersede the Splitwise Privacy Policy and that explains how you collect, store, use, and/or transfer any Personal Data via your Applications. Personal Data is data that may be used, either alone or together with other information, to identify an individual user, including, without limitation, a user’s name, address, telephone number, username, email address, city and country, geolocation, unique identifiers, picture, or other similar information and includes personal data as defined in the GDPR. +
      2. +
      3. + You are responsible for maintaining an appropriate legal basis to process any data under all applicable data protection laws (including but not limited to the GDPR, and the CCPA). +
      4. +
      5. + You will use industry standard security measures to protect against and prevent security breaches and any unauthorized disclosure of any personal information you process, including administrative, physical and technical safeguards for protection of the security, confidentiality and integrity of that personal information. +
      6. +
      7. + You must promptly notify us in writing via email to security@splitwise.com of any security deficiencies in, or intrusions to, your Applications or systems that you discover, and of any breaches of your user agreement or privacy policy that impact or may impact Splitwise customers. Please review our Privacy Policy for more information on how we collect and use data relating to the use and performance of our Service. +
      8. +
      9. + You will delete Splitwise Data as requested within a reasonable time, if so requested by either a Splitwise User or Splitwise Inc. +
      10. +
      11. + Any data submitted to Splitwise through your use of the Splitwise API will be governed by the Splitwise Privacy Policy. +
      12. +
      13. + You agree that Splitwise may collect certain use data and information related to your use of the Splitwise Materials, and the Splitwise API in connection with your Application (“Usage Data”), and that Splitwise may use such Usage Data for any business purpose, internal or external, including, without limitation, providing enhancements to the Splitwise Materials or Splitwise Platform, providing developer of user support, or otherwise. You agree to include a statement to this effect in your Application’s Privacy Policy. +
      14. +
      +
    6. + +
    7. + Conditions Of Use +
        +
      1. + Splitwise reserves the right to modify our API at any time, for any reason, without notice. +
      2. +
      3. + Splitwise may use your name, and other contact details to contact you regarding your use of our API or, if we believe you are in violation of this contract. +
      4. +
      5. + You are solely responsible for your use of the Splitwise API and any application you create that uses Splitwise Materials, including but not limited to Customer Support. +
      6. +
      7. + Splitwise reserves the right to develop and extend its products and capabilities without regard to whether those products compete with or invalidate your Splitwise integration or products offered by you. +
      8. +
      9. + Splitwise may limit (i) the number of network calls that your App may make via the API; and (ii) the maximum number of Splitwise users that may connect your Application, or (iii) anything else about the Splitwise API as Splitwise deems appropriate, at Splitwise’s sole discretion. +
      10. +
      11. + Splitwise may impose or modify these limitations without notice. Splitwise may utilize technical measures to prevent over-usage and stop usage of the API by your App after any usage limitations are exceeded or suspend your access to the API with or without notice to you in the event you exceed such limitations. +
      12. +
      13. + You will not issue any press release or other announcement regarding your Application that makes any reference to Splitwise without our prior written consent. +
      14. +
      15. + You will not use our API to distribute unsolicited advertising or promotions, or to send messages, make comments, or initiate any other unsolicited direct communication or contact with Splitwise users or partners. +
      16. +
      +
    8. + +
    9. + Use of Splitwise Marks +
        +
      1. + The rights granted in this Agreement do not include any general right to use the Splitwise name or any Splitwise trademarks, service marks or logos (the “Splitwise Marks”) with respect to your Applications. Subject to your continued compliance with this Agreement, you may use Splitwise Marks for limited purposes related to your Applications only as described in Splitwise Branding Guidelines and/or as provided in written communications with the Splitwise team. +
      2. +
      3. + These rights apply on a non-exclusive, non-transferable, worldwide, royalty-free basis, without any right to sub-license, and may be revoked by Splitwise at any time. +
      4. +
      5. + If Splitwise updates Branding Guidelines or any Splitwise Marks that you are using, you agree to update such Splitwise Marks to reflect the most current versions. You must not use any Splitwise Marks or trade dress, or any confusingly similar mark or trade dress, as the name or part of the name, user interface, or icon of your Applications, or as part of any logo or branding for your Applications. +
      6. +
      +
    10. + +
    11. + Reservation Of Rights. The Splitwise Materials as well as the trademarks, copyrights, trade secrets, patents or other intellectual property (collectively, “Intellectual Property”) contained therein will remain the sole and exclusive property of Splitwise, and you will reasonably assist Splitwise in protecting such ownership. Splitwise reserves to itself all rights to the Splitwise Materials not expressly granted to You. Except as expressly provided in this Agreement, You do not acquire any rights to or interest in the Intellectual Property. You will not utilize Splitwise Intellectual Property except as expressly authorized under this Agreement. +
    12. + +
    13. + Feedback. Splitwise welcomes feedback from developers to improve our API, documentation and Services, and may provide feedback to you as well. We will review any feedback received, however we make no guarantee that suggestions will be implemented. If you choose to provide feedback, suggestions or comments regarding the Splitwise API, documentation, or services, you acknowledge that Splitwise will be free to use your feedback in any way it sees fit. This includes the freedom to copy, modify, create derivative works, distribute, publicly display, publicly perform, grant sublicenses to, and otherwise exploit in any manner such feedback, suggestions or comments, for any and all purposes, with no obligation of any kind to you, in perpetuity. +
    14. + +
    15. + Confidentiality. Any information not generally available to the public that is made available to you should be considered Confidential. You agree to: +
        +
      1. + Protect this information from unauthorized use, access, or disclosure, +
      2. +
      3. + Use this information only as necessary, +
      4. +
      5. + Destroy any copies, or return this information to us when this Contract is terminated, or at any time as requested by Splitwise +
      6. +
      +
    16. + +
    17. + Termination. This Contract shall remain effective until terminated by either party. You may terminate this Contract at any time, by discontinuing your use of our APIs. Splitwise may terminate this Contract at any time with or without cause and without advanced notice to you. Upon termination, all rights and licenses granted under this Contract shall immediately terminate. You must immediately discontinue any use, and destroy any copies of the Splitwise Materials and Confidential Information in your possession. +
    18. +
    19. + Representations and Warranties. You represent and warrant that you have validly entered into the Contract, and that you have the legal power to do so, and that doing so will not violate any law, government regulation, or breach agreement with another third party. +

      THE SPLITWISE API AND DOCUMENTATION IS BEING PROVIDED TO YOU ‘AS IS’ AND ‘AS AVAILABLE’ WITHOUT ANY WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OF MERCHANTABILITY, TITLE, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. YOU ACKNOWLEDGE THAT WE DO NOT WARRANT THAT THE APIS WILL BE UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE. +
    20. +
    21. + Limitation of Liability. +

      TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL SPLITWISE, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, LICENSORS, LICENSEES, ASSIGNS OR SUCCESSORS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO ANY LOSS OF DATA, SERVICE INTERRUPTION, COMPUTER FAILURE, OR PECUNIARY LOSS) HOWEVER CAUSED, WHETHER IN CONTRACT, TORT OR UNDER ANY OTHER THEORY OF LIABILITY, AND WHETHER OR NOT YOU OR THE THIRD PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOUR ONLY RIGHT WITH RESPECT TO ANY PROBLEMS OR DISSATISFACTION WITH THE SPLITWISE SERVICES IS TO STOP USING THE SPLITWISE SERVICES. +

      SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN TYPES OF DAMAGES REFERRED TO ABOVE (INCLUDING INCIDENTAL OR CONSEQUENTIAL DAMAGES). ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS AND EXCLUSIONS MAY NOT APPLY TO YOU. YOU AGREE THAT SPLITWISE’S AGGREGATE LIABILITY UNDER THIS AGREEMENT IS LIMITED TO ONE HUNDRED DOLLARS ($100). +
    22. + +
    23. + Indemnification: You agree to defend, indemnify, and hold harmless Splitwise and its affiliates, directors, and customers, from and against any and all third-party claims, actions, suits, and proceedings (including, but not limited to legal, or investigative fees), arising out of, or related to your use of the Splitwise Services, your violation of this Contract, your violation of your user agreement or privacy policy, or your violation of any laws, regulations, or third party rights. +
    24. + +
    25. + Miscellaneous +
        +
      1. + Applicable Law, Jurisdiction, and Venue: Any dispute arising out of this Agreement shall be governed by Massachusetts law and controlling U.S. federal law, without regard to conflict of law provisions thereof. Any claim or dispute between you and Splitwise that arises in whole or in part from this Contract or your use of the API or our Services shall be decided exclusively by a court of competent jurisdiction located in Massachusetts, and you hereby consent to, and waive all defenses of lack of personal jurisdiction and forum non conveniens with respect to venue and jurisdiction in the state and federal courts of Massachusetts. +
      2. +
      3. + Assignment: You may not assign or delegate any of your rights or obligations hereunder, whether by operation of law or otherwise, without Splitwise’s prior written consent. Splitwise retains the right to assign the Contract in its entirety, without consent of the other party, to a corporate affiliate or in connection with a merger, acquisition, corporate reorganization, or sale of all or substantially all of its assets. Any purported assignment in violation of this section is void. +
      4. +
      5. + Language: This contact was drafted in English. In the event that this contract, or any part thereof, is translated to a language other than English, the English-language version shall control in the event of a conflict. +
      6. +
      7. + Relationship: You and Splitwise are independent contractors. This Contract does not create or imply any partnership, agency, joint venture, fiduciary or employment relationship between the parties. There are no third party beneficiaries to the Contract. +
      8. +
      9. + Severability: The Contract will be enforced to the fullest extent permitted under applicable law. If any provision of the Contract is found to be invalid or unenforceable by a court of competent jurisdiction, the provision will be modified by the court and interpreted so as best to accomplish the objectives of the original provision to the fullest extent permitted by law, and the remaining provisions of the Contract will remain in effect. +
      10. +
      11. + Force Majeure: Neither we nor you will be responsible for any failure to perform obligations under this Contract if such failure is caused by events beyond the reasonable control of a party, which may include denial-of-service attacks, a failure by a third party hosting provider, acts of God, war, strikes, revolutions, lack or failure of transportation facilities, laws or governmental regulations. +
      12. +
      13. + Entire Agreement: These Terms comprise the entire agreement between you and Splitwise with respect to the above subject matter and supersedes and merges all prior proposals, understandings and contemporaneous communications. +
      14. +
      +
    26. +
    + +
    +
    + +
    +
    + + diff --git a/javascripts/all.js b/javascripts/all.js new file mode 100644 index 0000000..3ee955d --- /dev/null +++ b/javascripts/all.js @@ -0,0 +1,131 @@ +!function(){if("ontouchstart"in window){var e,t,n,r,i,o,s={};e=function(e,t){return Math.abs(e[0]-t[0])>5||Math.abs(e[1]-t[1])>5},t=function(e){this.startXY=[e.touches[0].clientX,e.touches[0].clientY],this.threshold=!1},n=function(t){if(this.threshold)return!1;this.threshold=e(this.startXY,[t.touches[0].clientX,t.touches[0].clientY])},r=function(t){if(!this.threshold&&!e(this.startXY,[t.changedTouches[0].clientX,t.changedTouches[0].clientY])){var n=t.changedTouches[0],r=document.createEvent("MouseEvents");r.initMouseEvent("click",!0,!0,window,0,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),r.simulated=!0,t.target.dispatchEvent(r)}},i=function(e){var t=Date.now(),n=t-s.time,r=e.clientX,i=e.clientY,a=[Math.abs(s.x-r),Math.abs(s.y-i)],u=o(e.target,"A")||e.target,c=u.nodeName,l="A"===c,f=window.navigator.standalone&&l&&e.target.getAttribute("href");if(s.time=t,s.x=r,s.y=i,(!e.simulated&&(n<500||n<1500&&a[0]<50&&a[1]<50)||f)&&(e.preventDefault(),e.stopPropagation(),!f))return!1;f&&(window.location=u.getAttribute("href")),u&&u.classList&&(u.classList.add("energize-focus"),window.setTimeout(function(){u.classList.remove("energize-focus")},150))},o=function(e,t){for(var n=e;n!==document.body;){if(!n||n.nodeName===t)return n;n=n.parentNode}return null},document.addEventListener("touchstart",t,!1),document.addEventListener("touchmove",n,!1),document.addEventListener("touchend",r,!1),document.addEventListener("click",i,!0)}}(),/*! + * jQuery JavaScript Library v2.2.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-08T20:02Z + */ +function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&"length"in e&&e.length,n=oe.type(e);return"function"!==n&&!oe.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(oe.isFunction(t))return oe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return oe.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ge.test(t))return oe.filter(t,e,n);t=oe.filter(t,e)}return oe.grep(e,function(e){return Z.call(t,e)>-1!==n})}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(e){var t={};return oe.each(e.match(be)||[],function(e,n){t[n]=!0}),t}function s(){Q.removeEventListener("DOMContentLoaded",s),e.removeEventListener("load",s),oe.ready()}function a(){this.expando=oe.expando+a.uid++}function u(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(Ne,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:ke.test(n)?oe.parseJSON(n):n)}catch(e){}Ee.set(e,t,n)}else n=undefined;return n}function c(e,t,n,r){var i,o=1,s=20,a=r?function(){return r.cur()}:function(){return oe.css(e,t,"")},u=a(),c=n&&n[3]||(oe.cssNumber[t]?"":"px"),l=(oe.cssNumber[t]||"px"!==c&&+u)&&Le.exec(oe.css(e,t));if(l&&l[3]!==c){c=c||l[3],n=n||[],l=+u||1;do{o=o||".5",l/=o,oe.style(e,t,l+c)}while(o!==(o=a()/u)&&1!==o&&--s)}return n&&(l=+l||+u||0,i=n[1]?l+(n[1]+1)*n[2]:+n[2],r&&(r.unit=c,r.start=l,r.end=i)),i}function l(e,t){var n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&oe.nodeName(e,t)?oe.merge([e],n):n}function f(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(c=oe.contains(o.ownerDocument,o),s=l(p.appendChild(o),"script"),c&&f(s),n)for(d=0;o=s[d++];)$e.test(o.type||"")&&n.push(o);return p}function p(){return!0}function h(){return!1}function g(){try{return Q.activeElement}catch(e){}}function m(e,t,n,r,i,o){var s,a;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=undefined);for(a in t)m(e,a,n,r,t[a],o);return e}if(null==r&&null==i?(i=n,r=n=undefined):null==i&&("string"==typeof n?(i=r,r=undefined):(i=r,r=n,n=undefined)),!1===i)i=h;else if(!i)return this;return 1===o&&(s=i,i=function(e){return oe().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=oe.guid++)),e.each(function(){oe.event.add(this,t,i,r,n)})}function v(e,t){return oe.nodeName(e,"table")&&oe.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e:e}function y(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function x(e){var t=Be.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function b(e,t){var n,r,i,o,s,a,u,c;if(1===t.nodeType){if(Ce.hasData(e)&&(o=Ce.access(e),s=Ce.set(t,o),c=o.events)){delete s.handle,s.events={};for(i in c)for(n=0,r=c[i].length;n1&&"string"==typeof g&&!re.checkClone&&We.test(g))return e.each(function(i){var o=e.eq(i);m&&(t[0]=g.call(this,i,o.html())),T(o,t,n,r)});if(p&&(i=d(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(s=oe.map(l(i,"script"),y),a=s.length;f")).appendTo(t.documentElement),t=Xe[0].contentDocument,t.write(),t.close(),n=C(e,t),Xe.detach()),Ve[e]=n),n}function k(e,t,n){var r,i,o,s,a=e.style;return n=n||Qe(e),n&&(s=n.getPropertyValue(t)||n[t],""!==s||oe.contains(e.ownerDocument,e)||(s=oe.style(e,t)),!re.pixelMarginRight()&&Ye.test(s)&&Ue.test(t)&&(r=a.width,i=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=s,s=n.width,a.width=r,a.minWidth=i,a.maxWidth=o)),s!==undefined?s+"":s}function N(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function j(e){if(e in nt)return e;for(var t=e[0].toUpperCase()+e.slice(1),n=tt.length;n--;)if((e=tt[n]+t)in nt)return e}function L(e,t,n){var r=Le.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function A(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;o<4;o+=2)"margin"===n&&(s+=oe.css(e,n+Ae[o],!0,i)),r?("content"===n&&(s-=oe.css(e,"padding"+Ae[o],!0,i)),"margin"!==n&&(s-=oe.css(e,"border"+Ae[o]+"Width",!0,i))):(s+=oe.css(e,"padding"+Ae[o],!0,i),"padding"!==n&&(s+=oe.css(e,"border"+Ae[o]+"Width",!0,i)));return s}function D(t,n,r){var i=!0,o="width"===n?t.offsetWidth:t.offsetHeight,s=Qe(t),a="border-box"===oe.css(t,"boxSizing",!1,s);if(Q.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=k(t,n,s),(o<0||null==o)&&(o=t.style[n]),Ye.test(o))return o;i=a&&(re.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+A(t,n,r||(a?"border":"content"),i,s)+"px"}function O(e,t){for(var n,r,i,o=[],s=0,a=e.length;s=0&&n=0},isPlainObject:function(e){return"object"===oe.type(e)&&!e.nodeType&&!oe.isWindow(e)&&!(e.constructor&&!ne.call(e.constructor.prototype,"isPrototypeOf"))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?ee[te.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;(e=oe.trim(e))&&(1===e.indexOf("use strict")?(t=Q.createElement("script"),t.text=e,Q.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(ae,"ms-").replace(ue,ce)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;iT.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[I]=!0,e}function i(e){var t=O.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)T.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||U)-(~e.sourceIndex||U);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),s=o.length;s--;)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}function l(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r="";t1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i-1&&(r[c]=!(s[c]=f))}}else x=m(x===s?x.splice(h,x.length):x),o?o(null,s,x,u):K.apply(s,x)})}function y(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],s=o||T.relative[" "],a=o?1:0,u=p(function(e){return e===t},s,!0),c=p(function(e){return ee(t,e)>-1},s,!0),l=[function(e,n,r){var i=!o&&(r||n!==j)||((t=n).nodeType?u(e,n,r):c(e,n,r));return t=null,i}];a1&&h(l),a>1&&d(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ae,"$1"),n,a0,o=e.length>0,s=function(r,s,a,u,c){var l,f,d,p=0,h="0",g=r&&[],v=[],y=j,x=r||o&&T.find.TAG("*",c),b=_+=null==y?1:Math.random()||.1,w=x.length;for(c&&(j=s===O||s||c);h!==w&&null!=(l=x[h]);h++){if(o&&l){for(f=0,s||l.ownerDocument===O||(D(l),a=!$);d=e[f++];)if(d(l,s||O,a)){u.push(l);break}c&&(_=b)}i&&((l=!d&&l)&&p--,r&&g.push(l))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,v,s,a);if(r){if(p>0)for(;h--;)g[h]||v[h]||(v[h]=J.call(u));v=m(v)}K.apply(u,v),c&&!r&&v.length>0&&p+n.length>1&&t.uniqueSort(u)}return c&&(_=b,j=y),g};return i?r(s):s}var b,w,T,S,C,E,k,N,j,L,A,D,O,q,$,F,H,P,R,I="sizzle"+1*new Date,M=e.document,_=0,W=0,B=n(),z=n(),X=n(),V=function(e,t){return e===t&&(A=!0),0},U=1<<31,Y={}.hasOwnProperty,Q=[],J=Q.pop,G=Q.push,K=Q.push,Z=Q.slice,ee=function(e,t){for(var n=0,r=e.length;n+~]|"+ne+")"+ne+"*"),le=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(oe),de=new RegExp("^"+re+"$"),pe={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re+"|[*])"),ATTR:new RegExp("^"+ie),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ve=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ye=/[+~]/,xe=/'|\\/g,be=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),we=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){D()};try{K.apply(Q=Z.call(M.childNodes),M.childNodes),Q[M.childNodes.length].nodeType}catch(e){K={apply:Q.length?function(e,t){G.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},C=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},D=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:M;return r!==O&&9===r.nodeType&&r.documentElement?(O=r,q=O.documentElement,$=!C(O),(n=O.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Te,!1):n.attachEvent&&n.attachEvent("onunload",Te)),w.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=i(function(e){return e.appendChild(O.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=me.test(O.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=I,!O.getElementsByName||!O.getElementsByName(I).length}),w.getById?(T.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&$){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute("id")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&$)return t.getElementsByClassName(e)},H=[],F=[],(w.qsa=me.test(O.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&F.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||F.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+I+"-]").length||F.push("~="),e.querySelectorAll(":checked").length||F.push(":checked"),e.querySelectorAll("a#"+I+"+*").length||F.push(".#.+[+~]")}),i(function(e){var t=O.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&F.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||F.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),F.push(",.*:")})),(w.matchesSelector=me.test(P=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=P.call(e,"div"),P.call(e,"[s!='']:x"),H.push("!=",oe)}),F=F.length&&new RegExp(F.join("|")),H=H.length&&new RegExp(H.join("|")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},V=t?function(e,t){if(e===t)return A=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===O||e.ownerDocument===M&&R(M,e)?-1:t===O||t.ownerDocument===M&&R(M,t)?1:L?ee(L,e)-ee(L,t):0:4&n?-1:1)}:function(e,t){if(e===t)return A=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],u=[t];if(!i||!o)return e===O?-1:t===O?1:i?-1:o?1:L?ee(L,e)-ee(L,t):0;if(i===o)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[r]===u[r];)r++;return r?s(a[r],u[r]):a[r]===M?-1:u[r]===M?1:0},O):O},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==O&&D(e),n=n.replace(le,"='$1']"),w.matchesSelector&&$&&!X[n+" "]&&(!H||!H.test(n))&&(!F||!F.test(n)))try{var r=P.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return t(n,O,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==O&&D(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==O&&D(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!$):undefined;return r!==undefined?r:w.attributes||!$?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(A=!w.detectDuplicates,L=!w.sortStable&&e.slice(0),e.sort(V),A){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return L=null,e},S=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=S(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=S(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||"").replace(be,we),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=E(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=B[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&B(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(se," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,d,p,h,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!u&&!a,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(a?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&y){for(d=m,f=d[I]||(d[I]={}),l=f[d.uniqueID]||(f[d.uniqueID]={}),c=l[e]||[],p=c[0]===_&&c[1],x=p&&c[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){l[e]=[_,p,x];break}}else if(y&&(d=t,f=d[I]||(d[I]={}),l=f[d.uniqueID]||(f[d.uniqueID]={}),c=l[e]||[],p=c[0]===_&&c[1],x=p),!1===x)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((a?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++x||(y&&(f=d[I]||(d[I]={}),l=f[d.uniqueID]||(f[d.uniqueID]={}),l[e]=[_,x]),d!==t)););return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[I]?o(n):o.length>1?(i=[e,e,"",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),s=i.length;s--;)r=ee(e,i[s]),e[r]=!(t[r]=i[s])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(ae,"$1"));return i[I]?r(function(e,t,n,r){for(var o,s=i(e,null,r,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||S(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do{if(n=$?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===O.activeElement&&(!O.hasFocus||O.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return!1===e.disabled},disabled:function(e){return!0===e.disabled},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[n<0?n+t:n]}),even:c(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=n<0?n+t:n;++r2&&"ID"===(s=o[0]).type&&w.getById&&9===t.nodeType&&$&&T.relative[o[1].type]){if(!(t=(T.find.ID(s.matches[0].replace(be,we),t)||[])[0]))return n;c&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(s=o[i],!T.relative[a=s.type]);)if((u=T.find[a])&&(r=u(s.matches[0].replace(be,we),ye.test(o[0].type)&&l(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&d(o)))return K.apply(n,r),n;break}}return(c||k(e,f))(r,t,!$,n,!t||ye.test(e)&&l(t.parentNode)||t),n},w.sortStable=I.split("").sort(V).join("")===I,w.detectDuplicates=!!A,D(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(O.createElement("div"))}),i(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(te,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);oe.find=le,oe.expr=le.selectors,oe.expr[":"]=oe.expr.pseudos,oe.uniqueSort=oe.unique=le.uniqueSort,oe.text=le.getText,oe.isXMLDoc=le.isXML,oe.contains=le.contains;var fe=function(e,t,n){for(var r=[],i=n!==undefined;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&oe(e).is(n))break;r.push(e)}return r},de=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},pe=oe.expr.match.needsContext,he=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,ge=/^.[^:#\[\.,]*$/;oe.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?oe.find.matchesSelector(r,e)?[r]:[]:oe.find.matches(e,oe.grep(t,function(e){return 1===e.nodeType}))},oe.fn.extend({find:function(e){var t,n=this.length,r=[],i=this;if("string"!=typeof e)return this.pushStack(oe(e).filter(function(){for(t=0;t1?oe.unique(r):r),r.selector=this.selector?this.selector+" "+e:e,r},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,"string"==typeof e&&pe.test(e)?oe(e):e||[],!1).length}});var me,ve=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;(oe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||me,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:ve.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof oe?t[0]:t,oe.merge(this,oe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:Q,!0)),he.test(r[1])&&oe.isPlainObject(t))for(r in t)oe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=Q.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=Q,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):oe.isFunction(e)?n.ready!==undefined?n.ready(e):e(oe):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),oe.makeArray(e,this))}).prototype=oe.fn,me=oe(Q);var ye=/^(?:parents|prev(?:Until|All))/,xe={children:!0,contents:!0,next:!0,prev:!0};oe.fn.extend({has:function(e){var t=oe(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&oe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?oe.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?Z.call(oe(e),this[0]):Z.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(oe.uniqueSort(oe.merge(this.get(),oe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),oe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return fe(e,"parentNode")},parentsUntil:function(e,t,n){return fe(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return fe(e,"nextSibling")},prevAll:function(e){return fe(e,"previousSibling")},nextUntil:function(e,t,n){return fe(e,"nextSibling",n)},prevUntil:function(e,t,n){return fe(e,"previousSibling",n)},siblings:function(e){return de((e.parentNode||{}).firstChild,e)},children:function(e){return de(e.firstChild)},contents:function(e){return e.contentDocument||oe.merge([],e.childNodes)}},function(e,t){oe.fn[e]=function(n,r){var i=oe.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=oe.filter(r,i)),this.length>1&&(xe[e]||oe.uniqueSort(i),ye.test(e)&&i.reverse()),this.pushStack(i)}});var be=/\S+/g;oe.Callbacks=function(e){e="string"==typeof e?o(e):oe.extend({},e);var t,n,r,i,s=[],a=[],u=-1,c=function(){for(i=e.once,r=t=!0;a.length;u=-1)for(n=a.shift();++u-1;)s.splice(n,1),n<=u&&u--}),this},has:function(e){return e?oe.inArray(e,s)>-1:s.length>0},empty:function(){return s&&(s=[]),this},disable:function(){return i=a=[],s=n="",this},disabled:function(){return!s},lock:function(){return i=a=[],n||(s=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},oe.extend({Deferred:function(e){var t=[["resolve","done",oe.Callbacks("once memory"),"resolved"],["reject","fail",oe.Callbacks("once memory"),"rejected"],["notify","progress",oe.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return oe.Deferred(function(n){oe.each(t,function(t,o){var s=oe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&oe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?oe.extend(e,r):r}},i={};return r.pipe=r.then,oe.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=J.call(arguments),s=o.length,a=1!==s||e&&oe.isFunction(e.promise)?s:0,u=1===a?e:oe.Deferred(),c=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?J.call(arguments):i,r===t?u.notifyWith(n,r):--a||u.resolveWith(n,r)}};if(s>1)for(t=new Array(s),n=new Array(s),r=new Array(s);i0||(we.resolveWith(Q,[oe]),oe.fn.triggerHandler&&(oe(Q).triggerHandler("ready"),oe(Q).off("ready"))))}}),oe.ready.promise=function(t){return we||(we=oe.Deferred(),"complete"===Q.readyState||"loading"!==Q.readyState&&!Q.documentElement.doScroll?e.setTimeout(oe.ready):(Q.addEventListener("DOMContentLoaded",s),e.addEventListener("load",s))),we.promise(t)},oe.ready.promise();var Te=function(e,t,n,r,i,o,s){var a=0,u=e.length,c=null==n;if("object"===oe.type(n)){i=!0;for(a in n)Te(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,oe.isFunction(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(oe(e),n)})),t))for(;a-1&&n!==undefined&&Ee.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){Ee.remove(this,e)})}}),oe.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Ce.get(e,t),n&&(!r||oe.isArray(n)?r=Ce.access(e,t,oe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=oe.queue(e,t),r=n.length,i=n.shift(),o=oe._queueHooks(e,t),s=function(){oe.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Ce.get(e,n)||Ce.access(e,n,{empty:oe.Callbacks("once memory").add(function(){Ce.remove(e,[t+"queue",n])})})}}),oe.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length",""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};Fe.optgroup=Fe.option,Fe.tbody=Fe.tfoot=Fe.colgroup=Fe.caption=Fe.thead,Fe.th=Fe.td;var He=/<|&#?\w+;/;!function(){var e=Q.createDocumentFragment(),t=e.appendChild(Q.createElement("div")),n=Q.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),re.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",re.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var Pe=/^key/,Re=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ie=/^([^.]*)(?:\.(.+)|)/;oe.event={global:{},add:function(e,t,n,r,i){var o,s,a,u,c,l,f,d,p,h,g,m=Ce.get(e);if(m)for(n.handler&&(o=n,n=o.handler,i=o.selector),n.guid||(n.guid=oe.guid++),(u=m.events)||(u=m.events={}),(s=m.handle)||(s=m.handle=function(t){return void 0!==oe&&oe.event.triggered!==t.type?oe.event.dispatch.apply(e,arguments):undefined}),t=(t||"").match(be)||[""],c=t.length;c--;)a=Ie.exec(t[c])||[],p=g=a[1],h=(a[2]||"").split(".").sort(),p&&(f=oe.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,f=oe.event.special[p]||{},l=oe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&oe.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=u[p])||(d=u[p]=[],d.delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,s)||e.addEventListener&&e.addEventListener(p,s)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,l):d.push(l),oe.event.global[p]=!0)},remove:function(e,t,n,r,i){var o,s,a,u,c,l,f,d,p,h,g,m=Ce.hasData(e)&&Ce.get(e);if(m&&(u=m.events)){for(t=(t||"").match(be)||[""],c=t.length;c--;)if(a=Ie.exec(t[c])||[],p=g=a[1],h=(a[2]||"").split(".").sort(),p){for(f=oe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=u[p]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=d.length;o--;)l=d[o],!i&&g!==l.origType||n&&n.guid!==l.guid||a&&!a.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(d.splice(o,1),l.selector&&d.delegateCount--,f.remove&&f.remove.call(e,l));s&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,m.handle)||oe.removeEvent(e,p,m.handle),delete u[p])}else for(p in u)oe.event.remove(e,p+t[c],n,r,!0);oe.isEmptyObject(u)&&Ce.remove(e,"handle events")}},dispatch:function(e){e=oe.event.fix(e);var t,n,r,i,o,s=[],a=J.call(arguments),u=(Ce.get(this,"events")||{})[e.type]||[],c=oe.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,e)){for(s=oe.event.handlers.call(this,e,u),t=0;(i=s[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem, +n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,(r=((oe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a))!==undefined&&!1===(e.result=r)&&(e.preventDefault(),e.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&(!0!==u.disabled||"click"!==e.type)){for(r=[],n=0;n-1:oe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return a]*)\/>/gi,_e=/\s*$/g;oe.extend({htmlPrefilter:function(e){return e.replace(Me,"<$1>")},clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=oe.contains(e.ownerDocument,e);if(!(re.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||oe.isXMLDoc(e)))for(s=l(a),o=l(e),r=0,i=o.length;r0&&f(s,!u&&l(e,"script")),a},cleanData:function(e){for(var t,n,r,i=oe.event.special,o=0;(n=e[o])!==undefined;o++)if(Se(n)){if(t=n[Ce.expando]){if(t.events)for(r in t.events)i[r]?oe.event.remove(n,r):oe.removeEvent(n,r,t.handle);n[Ce.expando]=undefined}n[Ee.expando]&&(n[Ee.expando]=undefined)}}}),oe.fn.extend({domManip:T,detach:function(e){return S(this,e,!0)},remove:function(e){return S(this,e)},text:function(e){return Te(this,function(e){return e===undefined?oe.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return T(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){v(this,e).appendChild(e)}})},prepend:function(){return T(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=v(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return T(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return T(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(oe.cleanData(l(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return oe.clone(this,e,t)})},html:function(e){return Te(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!_e.test(e)&&!Fe[(qe.exec(e)||["",""])[1].toLowerCase()]){e=oe.htmlPrefilter(e);try{for(;n1)},show:function(){return O(this,!0)},hide:function(){return O(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){De(this)?oe(this).show():oe(this).hide()})}}),oe.Tween=q,q.prototype={constructor:q,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||oe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(oe.cssNumber[n]?"":"px")},cur:function(){var e=q.propHooks[this.prop];return e&&e.get?e.get(this):q.propHooks._default.get(this)},run:function(e){var t,n=q.propHooks[this.prop];return this.options.duration?this.pos=t=oe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):q.propHooks._default.set(this),this}},q.prototype.init.prototype=q.prototype,q.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=oe.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){oe.fx.step[e.prop]?oe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[oe.cssProps[e.prop]]&&!oe.cssHooks[e.prop]?e.elem[e.prop]=e.now:oe.style(e.elem,e.prop,e.now+e.unit)}}},q.propHooks.scrollTop=q.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},oe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},oe.fx=q.prototype.init,oe.fx.step={};var rt,it,ot=/^(?:toggle|show|hide)$/,st=/queueHooks$/;oe.Animation=oe.extend(I,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return c(n.elem,e,Le.exec(t),n),n}]},tweener:function(e,t){oe.isFunction(e)?(t=e,e=["*"]):e=e.match(be);for(var n,r=0,i=e.length;r1)},removeAttr:function(e){return this.each(function(){oe.removeAttr(this,e)})}}),oe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?oe.prop(e,t,n):(1===o&&oe.isXMLDoc(e)||(t=t.toLowerCase(),i=oe.attrHooks[t]||(oe.expr.match.bool.test(t)?at:undefined)),n!==undefined?null===n?void oe.removeAttr(e,t):i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=oe.find.attr(e,t),null==r?undefined:r))},attrHooks:{type:{set:function(e,t){if(!re.radioValue&&"radio"===t&&oe.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(be);if(o&&1===e.nodeType)for(;n=o[i++];)r=oe.propFix[n]||n,oe.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)}}),at={set:function(e,t,n){return!1===t?oe.removeAttr(e,n):e.setAttribute(n,n),n}},oe.each(oe.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ut[t]||oe.find.attr;ut[t]=function(e,t,r){var i,o;return r||(o=ut[t],ut[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,ut[t]=o),i}});var ct=/^(?:input|select|textarea|button)$/i,lt=/^(?:a|area)$/i;oe.fn.extend({prop:function(e,t){return Te(this,oe.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[oe.propFix[e]||e]})}}),oe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&oe.isXMLDoc(e)||(t=oe.propFix[t]||t,i=oe.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=oe.find.attr(e,"tabindex");return t?parseInt(t,10):ct.test(e.nodeName)||lt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),re.optSelected||(oe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),oe.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){oe.propFix[this.toLowerCase()]=this});var ft=/[\t\r\n\f]/g;oe.fn.extend({addClass:function(e){var t,n,r,i,o,s,a,u=0;if(oe.isFunction(e))return this.each(function(t){oe(this).addClass(e.call(this,t,M(this)))});if("string"==typeof e&&e)for(t=e.match(be)||[];n=this[u++];)if(i=M(n),r=1===n.nodeType&&(" "+i+" ").replace(ft," ")){for(s=0;o=t[s++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");a=oe.trim(r),i!==a&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,r,i,o,s,a,u=0;if(oe.isFunction(e))return this.each(function(t){oe(this).removeClass(e.call(this,t,M(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(be)||[];n=this[u++];)if(i=M(n),r=1===n.nodeType&&(" "+i+" ").replace(ft," ")){for(s=0;o=t[s++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");a=oe.trim(r),i!==a&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):oe.isFunction(e)?this.each(function(n){oe(this).toggleClass(e.call(this,n,M(this),t),t)}):this.each(function(){var t,r,i,o;if("string"===n)for(r=0,i=oe(this),o=e.match(be)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else e!==undefined&&"boolean"!==n||(t=M(this),t&&Ce.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":Ce.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+M(n)+" ").replace(ft," ").indexOf(t)>-1)return!0;return!1}});var dt=/\r/g;oe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=oe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,oe(this).val()):e,null==i?i="":"number"==typeof i?i+="":oe.isArray(i)&&(i=oe.map(i,function(e){return null==e?"":e+""})),(t=oe.valHooks[this.type]||oe.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return(t=oe.valHooks[i.type]||oe.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace(dt,""):null==n?"":n)}}}),oe.extend({valHooks:{option:{get:function(e){return oe.trim(e.value)}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||i<0,s=o?null:[],a=o?i+1:r.length,u=i<0?a:o?i:0;u-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),oe.each(["radio","checkbox"],function(){oe.valHooks[this]={set:function(e,t){if(oe.isArray(t))return e.checked=oe.inArray(oe(e).val(),t)>-1}},re.checkOn||(oe.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var pt=/^(?:focusinfocus|focusoutblur)$/;oe.extend(oe.event,{trigger:function(t,n,r,i){var o,s,a,u,c,l,f,d=[r||Q],p=ne.call(t,"type")?t.type:t,h=ne.call(t,"namespace")?t.namespace.split("."):[];if(s=a=r=r||Q,3!==r.nodeType&&8!==r.nodeType&&!pt.test(p+oe.event.triggered)&&(p.indexOf(".")>-1&&(h=p.split("."),p=h.shift(),h.sort()),c=p.indexOf(":")<0&&"on"+p,t=t[oe.expando]?t:new oe.Event(p,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:oe.makeArray(n,[t]),f=oe.event.special[p]||{},i||!f.trigger||!1!==f.trigger.apply(r,n))){if(!i&&!f.noBubble&&!oe.isWindow(r)){for(u=f.delegateType||p,pt.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),a=s;a===(r.ownerDocument||Q)&&d.push(a.defaultView||a.parentWindow||e)}for(o=0;(s=d[o++])&&!t.isPropagationStopped();)t.type=o>1?u:f.bindType||p,l=(Ce.get(s,"events")||{})[t.type]&&Ce.get(s,"handle"),l&&l.apply(s,n),(l=c&&s[c])&&l.apply&&Se(s)&&(t.result=l.apply(s,n),!1===t.result&&t.preventDefault());return t.type=p,i||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(d.pop(),n)||!Se(r)||c&&oe.isFunction(r[p])&&!oe.isWindow(r)&&(a=r[c],a&&(r[c]=null),oe.event.triggered=p,r[p](),oe.event.triggered=undefined,a&&(r[c]=a)),t.result}},simulate:function(e,t,n){var r=oe.extend(new oe.Event,n,{type:e,isSimulated:!0});oe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}}),oe.fn.extend({trigger:function(e,t){return this.each(function(){oe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return oe.event.trigger(e,t,n,!0)}}),oe.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){oe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),oe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),re.focusin="onfocusin"in e,re.focusin||oe.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){oe.event.simulate(t,e.target,oe.event.fix(e))};oe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=Ce.access(r,t);i||r.addEventListener(e,n,!0),Ce.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=Ce.access(r,t)-1;i?Ce.access(r,t,i):(r.removeEventListener(e,n,!0),Ce.remove(r,t))}}});var ht=e.location,gt=oe.now(),mt=/\?/;oe.parseJSON=function(e){return JSON.parse(e+"")},oe.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=undefined}return n&&!n.getElementsByTagName("parsererror").length||oe.error("Invalid XML: "+t),n};var vt=/#.*$/,yt=/([?&])_=[^&]*/,xt=/^(.*?):[ \t]*([^\r\n]*)$/gm,bt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,wt=/^(?:GET|HEAD)$/,Tt=/^\/\//,St={},Ct={},Et="*/".concat("*"),kt=Q.createElement("a");kt.href=ht.href,oe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ht.href,type:"GET",isLocal:bt.test(ht.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Et,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":oe.parseJSON,"text xml":oe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?B(B(e,oe.ajaxSettings),t):B(oe.ajaxSettings,e)},ajaxPrefilter:_(St),ajaxTransport:_(Ct),ajax:function(t,n){function r(t,n,r,a){var c,f,y,x,w,S=n;2!==b&&(b=2,u&&e.clearTimeout(u),i=undefined,s=a||"",T.readyState=t>0?4:0,c=t>=200&&t<300||304===t,r&&(x=z(d,T,r)),x=X(d,x,T,c),c?(d.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(oe.lastModified[o]=w),(w=T.getResponseHeader("etag"))&&(oe.etag[o]=w)),204===t||"HEAD"===d.type?S="nocontent":304===t?S="notmodified":(S=x.state,f=x.data,y=x.error,c=!y)):(y=S,!t&&S||(S="error",t<0&&(t=0))),T.status=t,T.statusText=(n||S)+"",c?g.resolveWith(p,[f,S,T]):g.rejectWith(p,[T,S,y]),T.statusCode(v),v=undefined,l&&h.trigger(c?"ajaxSuccess":"ajaxError",[T,d,c?f:y]),m.fireWith(p,[T,S]),l&&(h.trigger("ajaxComplete",[T,d]),--oe.active||oe.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=undefined),n=n||{};var i,o,s,a,u,c,l,f,d=oe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?oe(p):oe.event,g=oe.Deferred(),m=oe.Callbacks("once memory"),v=d.statusCode||{},y={},x={},b=0,w="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!a)for(a={};t=xt.exec(s);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)v[t]=[v[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return i&&i.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||ht.href)+"").replace(vt,"").replace(Tt,ht.protocol+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=oe.trim(d.dataType||"*").toLowerCase().match(be)||[""],null==d.crossDomain){c=Q.createElement("a");try{c.href=d.url,c.href=c.href,d.crossDomain=kt.protocol+"//"+kt.host!=c.protocol+"//"+c.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=oe.param(d.data,d.traditional)),W(St,d,n,T),2===b)return T;l=oe.event&&d.global,l&&0==oe.active++&&oe.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!wt.test(d.type),o=d.url,d.hasContent||(d.data&&(o=d.url+=(mt.test(o)?"&":"?")+d.data,delete d.data),!1===d.cache&&(d.url=yt.test(o)?o.replace(yt,"$1_="+gt++):o+(mt.test(o)?"&":"?")+"_="+gt++)),d.ifModified&&(oe.lastModified[o]&&T.setRequestHeader("If-Modified-Since",oe.lastModified[o]),oe.etag[o]&&T.setRequestHeader("If-None-Match",oe.etag[o])),(d.data&&d.hasContent&&!1!==d.contentType||n.contentType)&&T.setRequestHeader("Content-Type",d.contentType),T.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Et+"; q=0.01":""):d.accepts["*"]);for(f in d.headers)T.setRequestHeader(f,d.headers[f]);if(d.beforeSend&&(!1===d.beforeSend.call(p,T,d)||2===b))return T.abort();w="abort";for(f in{success:1,error:1,complete:1})T[f](d[f]);if(i=W(Ct,d,n,T)){if(T.readyState=1,l&&h.trigger("ajaxSend",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort("timeout")},d.timeout));try{b=1,i.send(y,r)}catch(e){if(!(b<2))throw e;r(-1,e)}}else r(-1,"No Transport");return T},getJSON:function(e,t,n){return oe.get(e,t,n,"json")},getScript:function(e,t){return oe.get(e,undefined,t,"script")}}),oe.each(["get","post"],function(e,t){oe[t]=function(e,n,r,i){return oe.isFunction(n)&&(i=i||r,r=n,n=undefined),oe.ajax(oe.extend({url:e,type:t,dataType:i,data:n,success:r},oe.isPlainObject(e)&&e))}}),oe._evalUrl=function(e){return oe.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},oe.fn.extend({wrapAll:function(e){var t;return oe.isFunction(e)?this.each(function(t){oe(this).wrapAll(e.call(this,t))}):(this[0]&&(t=oe(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return oe.isFunction(e)?this.each(function(t){oe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=oe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=oe.isFunction(e);return this.each(function(n){oe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){oe.nodeName(this,"body")||oe(this).replaceWith(this.childNodes)}).end()}}),oe.expr.filters.hidden=function(e){return!oe.expr.filters.visible(e)},oe.expr.filters.visible=function(e){return e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0};var Nt=/%20/g,jt=/\[\]$/,Lt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Dt=/^(?:input|select|textarea|keygen)/i;oe.param=function(e,t){var n,r=[],i=function(e,t){t=oe.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(t===undefined&&(t=oe.ajaxSettings&&oe.ajaxSettings.traditional),oe.isArray(e)||e.jquery&&!oe.isPlainObject(e))oe.each(e,function(){i(this.name,this.value)});else for(n in e)V(n,e[n],t,i);return r.join("&").replace(Nt,"+")},oe.fn.extend({serialize:function(){return oe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=oe.prop(this,"elements");return e?oe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!oe(this).is(":disabled")&&Dt.test(this.nodeName)&&!At.test(e)&&(this.checked||!Oe.test(e))}).map(function(e,t){var n=oe(this).val();return null==n?null:oe.isArray(n)?oe.map(n,function(e){return{name:t.name,value:e.replace(Lt,"\r\n")}}):{name:t.name,value:n.replace(Lt,"\r\n")}}).get()}}),oe.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Ot={0:200,1223:204},qt=oe.ajaxSettings.xhr();re.cors=!!qt&&"withCredentials"in qt,re.ajax=qt=!!qt,oe.ajaxTransport(function(t){var n,r;if(re.cors||qt&&!t.crossDomain)return{send:function(i,o){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(s in i)a.setRequestHeader(s,i[s]);n=function(e){return function(){n&&(n=r=a.onload=a.onerror=a.onabort=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(Ot[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),r=a.onerror=n("error"),a.onabort!==undefined?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),oe.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return oe.globalEval(e),e}}}),oe.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),oe.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=oe("