├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── config └── config.exs ├── doc ├── BitPay.ArgumentError.html ├── BitPay.BitPayError.html ├── BitPay.KeyUtils.html ├── BitPay.WebClient.html ├── BitPay.html ├── css │ ├── elixir.css │ ├── full_list.css │ └── style.css ├── exceptions_list.html ├── index.html ├── js │ ├── app.js │ ├── full_list.js │ ├── highlight.pack.js │ └── jquery.js ├── modules_list.html ├── overview.html └── protocols_list.html ├── lib ├── bitpay.ex └── bitpay │ ├── errors.ex │ ├── key-utils.ex │ └── webclient.ex ├── mix.exs ├── mix.lock └── test ├── features └── pairing_test.exs ├── key_utils_test.exs ├── set_constants.sh ├── test_helper.exs └── webclient_test.exs /.gitignore: -------------------------------------------------------------------------------- 1 | /_build 2 | /deps 3 | erl_crash.dump 4 | *.ez 5 | *.swp 6 | temp/* 7 | cacert.pem 8 | *.beam 9 | .pem.data 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: elixir 3 | otp_release: 4 | - 17.4 5 | after_success: 6 | - mix compile 7 | - mix coveralls.travis 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015 BitPay 2 | 3 | The MIT License (MIT) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/bitpay/elixir-client/master/LICENSE.md) 2 | [![Travis](https://img.shields.io/travis/bitpay/elixir-client.svg?style=flat-square)](https://travis-ci.org/bitpay/elixir-client) 3 | [![Hex.pm](https://img.shields.io/hexpm/v/bitpay.svg?style=flat-square)](https://hex.pm/packages/bitpay) 4 | [![Coveralls](https://img.shields.io/coveralls/bitpay/elixir-client.svg?style=flat-square)](https://coveralls.io/r/bitpay/elixir-client) 5 | 6 | # BitPay Library for Elixir or Erlang 7 | Powerful, flexible, lightweight interface to the BitPay Bitcoin Payment Gateway API. Can be used in an Elixir project or directly in an Erlang project as described in the [Elixir Crash Course](http://elixir-lang.org/crash-course.html). This document assumes that you are using Elixir. 8 | 9 | ## Installation 10 | 11 | using hex, add to mixfile: 12 | { :bitpay, "~> 0.2.4" } 13 | 14 | otherwise: 15 | { :bitpay, github: "bitpay/elixir-client", tag: "v0.2.4" } 16 | 17 | ## Basic Usage 18 | 19 | The bitpay library allows authenticating with BitPay, creating invoices, and retrieving invoices. 20 | 21 | ### Pairing with Bitpay.com 22 | 23 | Before pairing with BitPay.com, you'll need to log in to your BitPay account and navigate to /api-tokens. Generate a new pairing code and use it in the next step. If you want to test against 24 | 25 | > pem = BitPay.KeyUtils.generate_pem 26 | > webclient = %BitPay.WebClient{pem: pem} #or %BitPay.WebClient{pem: pem, uri: "https://test.bitpay.com"} 27 | > token = BitPay.WebClient.pair_pos_client(pairingcode, webclient) 28 | 29 | You'll need to know the pem file and the token in order to create invoices. 30 | 31 | ### To create an invoice with a paired client: 32 | 33 | Assuming that you have both a token object and a webclient as shown in the last step: 34 | 35 | > webclient = %BitPay.WebClient{pem: pem, uri: "https://test.bitpay.com"} 36 | > params = %{price: 100, currency: "USD", token: token.pos} 37 | > invoice = BitPay.WebClient.create_invoice(params, webclient) 38 | 39 | That will return a map representing the invoice, and create an invoice on BitPays servers. Other parameters can be sent, see the [BitPay REST API documentation](https://bitpay.com/api#resource-Invoices) for details. 40 | 41 | ## Testnet Usage 42 | 43 | To use testnet, add a uri parameter when creating the webclient struct `%BitPay.WebClient{uri: "https://test.bitpay.com"}` 44 | 45 | 46 | ## API Documentation 47 | 48 | API Documentation is available on the [BitPay site](https://bitpay.com/api). 49 | 50 | ## Running the Tests 51 | 52 | The tests depend on a custom fork of elixir-webdriver and require that you have phantomjs installed. 53 | 54 | Before running the tests, get a test.bitpay.com account. After this, you'll need to use the shell to approve a merchant token. Using `iex -S mix`: 55 | ```iex 56 | (iex 1)> pem = BitPay.KeyUtils.generate_pem 57 | (iex 2)> api = "https://test.bitpay.com" 58 | (iex 3)> client = %BitPay.WebClient{pem: pem, uri: api} 59 | (iex 4)> {:ok, pairingCode} = BitPay.WebClient.get_pairing_code(client) 60 | ``` 61 | 62 | Then log in to your dashboard and use the pairing code to create a "merchant" token. Once this is set, you'll need to create two environment variables, BITPAYPEM and BITPAYAPI, set to the values you used in the shell session. It's a good idea to save the pem to a file so that you can retrieve it later, the tests don't take care of that for you. 63 | 64 | Once that's done you should be able to run: `mix test` and see the tests run. 65 | 66 | ## Found a bug? 67 | Let us know! Send a pull request or a patch. Questions? Ask! We're here to help. We will respond to all filed issues. 68 | 69 | ## Contributors 70 | [Click here](https://github.com/philosodad/bitpay-elixir/graphs/contributors) to see a list of the contributors to this library. 71 | -------------------------------------------------------------------------------- /config/config.exs: -------------------------------------------------------------------------------- 1 | # This file is responsible for configuring your application 2 | # and its dependencies with the aid of the Mix.Config module. 3 | use Mix.Config 4 | # This configuration is loaded before any dependency and is restricted 5 | # to this project. If another project depends on this project, this 6 | # file won't be loaded nor affect the parent project. For this reason, 7 | # if you want to provide default values for your application for third- 8 | # party users, it should be done in your mix.exs file. 9 | 10 | # Sample configuration: 11 | # 12 | # config :logger, 13 | # level: :info, 14 | # format: "$time $metadata[$level] $levelpad$message\n" 15 | 16 | # It is also possible to import configuration files, relative to this 17 | # directory. For example, you can emulate configuration per environment 18 | # by uncommenting the line below and defining dev.exs, test.exs and such. 19 | # Configuration from the imported file will override the ones defined 20 | # here (which is why it is important to import them last). 21 | # 22 | # import_config "#{Mix.env}.exs" 23 | -------------------------------------------------------------------------------- /doc/BitPay.ArgumentError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BitPay.ArgumentError 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 26 | 27 |
28 | 29 |

30 | BitPay.ArgumentError 31 | 32 | exception 33 | 34 |

35 | 36 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |

Summary

54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | 67 | 68 | 69 | 70 |
exception(args)

Callback implementation of Exception.exception/1

59 |
message(exception)

Callback implementation of Exception.message/1

66 |
71 | 72 | 73 | 74 | 75 | 76 |
77 |

Functions

78 |
79 |
80 | exception(args) 81 | 86 |
87 | 88 |

Specs:

89 | 94 | 95 |
96 |

Callback implementation of Exception.exception/1.

97 | 98 |
99 | 100 |
101 |
102 |
103 | message(exception) 104 | 109 |
110 | 111 |

Specs:

112 | 117 | 118 |
119 |

Callback implementation of Exception.message/1.

120 | 121 |
122 | 123 |
124 | 125 |
126 | 127 | 128 | 129 | 130 | 131 |
132 | 133 | 134 | -------------------------------------------------------------------------------- /doc/BitPay.BitPayError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BitPay.BitPayError 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 26 | 27 |
28 | 29 |

30 | BitPay.BitPayError 31 | 32 | exception 33 | 34 |

35 | 36 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |

Summary

54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | 67 | 68 | 69 | 70 |
exception(args)

Callback implementation of Exception.exception/1

59 |
message(exception)

Callback implementation of Exception.message/1

66 |
71 | 72 | 73 | 74 | 75 | 76 |
77 |

Functions

78 |
79 |
80 | exception(args) 81 | 86 |
87 | 88 |

Specs:

89 | 94 | 95 |
96 |

Callback implementation of Exception.exception/1.

97 | 98 |
99 | 100 |
101 |
102 |
103 | message(exception) 104 | 109 |
110 | 111 |

Specs:

112 | 117 | 118 |
119 |

Callback implementation of Exception.message/1.

120 | 121 |
122 | 123 |
124 | 125 |
126 | 127 | 128 | 129 | 130 | 131 |
132 | 133 | 134 | -------------------------------------------------------------------------------- /doc/BitPay.KeyUtils.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BitPay.KeyUtils 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 26 | 27 |
28 | 29 |

30 | BitPay.KeyUtils 31 | 32 |

33 | 34 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |

Summary

52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 | 69 | 70 | 72 | 73 | 74 | 75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | 86 | 87 | 88 | 89 |
compressed_public_key(pem)

retrieves the compressed public key from a pem file

57 |
generate_pem()

generates a pem file

64 |
get_sin_from_pem(pem)

creates a base58 encoded SIN from a pem file

71 |
private_key(pem)

retrieves the private key as a base16 string from the pem file

78 |
sign(payload, pem)

signs the input with the key retrieved from the pem file

85 |
90 | 91 | 92 | 93 | 94 | 95 |
96 |

Functions

97 |
98 |
99 | compressed_public_key(pem) 100 | 105 |
106 | 107 |
108 |

retrieves the compressed public key from a pem file

109 | 110 |
111 | 112 |
113 |
114 |
115 | generate_pem() 116 | 121 |
122 | 123 |
124 |

generates a pem file

125 | 126 |
127 | 128 |
129 |
130 |
131 | get_sin_from_pem(pem) 132 | 137 |
138 | 139 |
140 |

creates a base58 encoded SIN from a pem file

141 | 142 |
143 | 144 |
145 |
146 |
147 | private_key(pem) 148 | 153 |
154 | 155 |
156 |

retrieves the private key as a base16 string from the pem file

157 | 158 |
159 | 160 |
161 |
162 |
163 | sign(payload, pem) 164 | 169 |
170 | 171 |
172 |

signs the input with the key retrieved from the pem file

173 | 174 |
175 | 176 |
177 | 178 |
179 | 180 | 181 | 182 | 183 | 184 |
185 | 186 | 187 | -------------------------------------------------------------------------------- /doc/BitPay.WebClient.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BitPay.WebClient 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 26 | 27 |
28 | 29 |

30 | BitPay.WebClient 31 | 32 |

33 | 34 | 45 | 46 | 47 |
48 |

Convenience methods for the BitPay REST API.

49 | 50 |
51 | 52 | 53 | 54 | 55 | 56 |

Summary

57 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | 71 | 72 | 73 | 74 | 75 | 86 | 87 | 88 | 89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | 100 | 101 | 102 | 103 | 104 | 105 | 107 | 108 | 109 | 110 | 111 | 112 | 123 | 124 | 125 | 126 |
__struct__()

The module struct contains two fields:

62 |
create_invoice(params, webclient)

Sends a post request to the server that creates a new invoice

69 |
get(path, webclient)

Generic Get method to the WebClient endpoint + path 76 | Input:

77 |
    78 |
  • the path (string) 79 |
  • 80 |
  • params for the request (as map) 81 |
  • 82 |
  • WebClient struct 83 |
  • 84 |
85 |
get_invoice(id, webclient)

Retrieves an invoice from the BitPay server

92 |
get_pairing_code(client)

initiates a ‘client side’ pairing

99 |
pair_pos_client(code, client)

creates a token on the server corresponding to the WebClients public and private keys

106 |
post(path, params, webclient)

Generic post method to the WebClient endpoint + path 113 | Input:

114 |
    115 |
  • the path (string) 116 |
  • 117 |
  • params for the request (as map) 118 |
  • 119 |
  • WebClient struct 120 |
  • 121 |
122 |
127 | 128 | 129 | 130 | 131 | 132 |
133 |

Functions

134 |
135 |
136 | __struct__() 137 | 142 |
143 | 144 |

Specs:

145 |
    146 | 147 |
  • __struct__ :: %BitPay.WebClient{pem: term, uri: term}
  • 148 | 149 |
150 | 151 |
152 |

The module struct contains two fields:

153 |
    154 |
  • uri: the api uri, which defaults to https://bitpay.com 155 |
  • 156 |
  • pem: a pem file containing the public and private keys, which can be generated from the BitPay.KeyUtils module. 157 |
  • 158 |
159 | 160 |
161 | 162 |
163 |
164 |
165 | create_invoice(params, webclient) 166 | 171 |
172 | 173 |
174 |

Sends a post request to the server that creates a new invoice.

175 |

Input:

176 |
    177 |
  • a params map that must contain a price and a currency 178 |
  • 179 |
  • a WebClient struct. The web client struct must be paired with BitPay. 180 |
  • 181 |
182 |

Response: A map corresponding to the data section of the JSON response from the server.

183 | 184 |
185 | 186 |
187 |
188 |
189 | get(path, webclient) 190 | 195 |
196 | 197 |
198 |

Generic Get method to the WebClient endpoint + path 199 | Input:

200 |
    201 |
  • the path (string) 202 |
  • 203 |
  • params for the request (as map) 204 |
  • 205 |
  • WebClient struct

    206 |

    Response: 207 | a map containing the response code, successe status as true or false, and the body of the http response

    208 |
  • 209 |
210 | 211 |
212 | 213 |
214 |
215 |
216 | get_invoice(id, webclient) 217 | 222 |
223 | 224 |
225 |

Retrieves an invoice from the BitPay server.

226 |

Input:

227 |
    228 |
  • an invoice id 229 |
  • 230 |
  • a WebClient 231 |
  • 232 |
233 |

Response: 234 | a map corresponding to the data section of the JSON response from the server.

235 | 236 |
237 | 238 |
239 |
240 |
241 | get_pairing_code(client) 242 | 247 |
248 | 249 |
250 |

initiates a ‘client side’ pairing.

251 |

Input: a WebClient

252 |

Response: {:ok, <pairingCode> }

253 |

The pairingCode can then be used at /dashboard/merchant/api-tokens to authenticate the token

254 | 255 |
256 | 257 |
258 |
259 |
260 | pair_pos_client(code, client) 261 | 266 |
267 | 268 |
269 |

creates a token on the server corresponding to the WebClients public and private keys

270 |

Input:

271 |
    272 |
  • a pairing code from the server 273 |
  • 274 |
  • a WebClient 275 |
  • 276 |
277 |

Response: a key/value pair such as %{pos: 92hgkeit92392gjgj}

278 | 279 |
280 | 281 |
282 |
283 |
284 | post(path, params, webclient) 285 | 290 |
291 | 292 |
293 |

Generic post method to the WebClient endpoint + path 294 | Input:

295 |
    296 |
  • the path (string) 297 |
  • 298 |
  • params for the request (as map) 299 |
  • 300 |
  • WebClient struct

    301 |

    Response: 302 | a map containing the response code, successe status as true or false, and the body of the http response

    303 |
  • 304 |
305 | 306 |
307 | 308 |
309 | 310 |
311 | 312 | 313 | 314 | 315 | 316 |
317 | 318 | 319 | -------------------------------------------------------------------------------- /doc/BitPay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BitPay 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 26 | 27 |
28 | 29 |

30 | BitPay 31 | 32 |

33 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | 57 | 58 | -------------------------------------------------------------------------------- /doc/css/elixir.css: -------------------------------------------------------------------------------- 1 | .hljs { 2 | overflow-x: auto; 3 | color: #333; 4 | padding: 0.5em; 5 | border: #ffe0bb dotted 1px; 6 | background: #fffde8; 7 | display: block; 8 | -webkit-text-size-adjust: none; 9 | } 10 | 11 | .hljs-comment, 12 | .diff .hljs-header, 13 | .hljs-javadoc { 14 | color: #998; 15 | font-style: italic; 16 | } 17 | 18 | .hljs-keyword, 19 | .css .rule .hljs-keyword, 20 | .hljs-winutils, 21 | .nginx .hljs-title, 22 | .hljs-subst, 23 | .hljs-request, 24 | .hljs-status { 25 | color: #333; 26 | font-weight: bold; 27 | } 28 | 29 | .hljs-number, 30 | .hljs-hexcolor, 31 | .ruby .hljs-constant { 32 | color: #008080; 33 | } 34 | 35 | .hljs-string, 36 | .hljs-tag .hljs-value, 37 | .hljs-phpdoc, 38 | .hljs-dartdoc, 39 | .tex .hljs-formula { 40 | color: #d14; 41 | } 42 | 43 | .hljs-title, 44 | .hljs-id, 45 | .scss .hljs-preprocessor { 46 | color: #900; 47 | font-weight: bold; 48 | } 49 | 50 | .hljs-list .hljs-keyword, 51 | .hljs-subst { 52 | font-weight: normal; 53 | } 54 | 55 | .hljs-class .hljs-title, 56 | .hljs-type, 57 | .vhdl .hljs-literal, 58 | .tex .hljs-command { 59 | color: #445588; 60 | font-weight: bold; 61 | } 62 | 63 | .hljs-tag, 64 | .hljs-tag .hljs-title, 65 | .hljs-rules .hljs-property, 66 | .django .hljs-tag .hljs-keyword { 67 | color: #000080; 68 | font-weight: normal; 69 | } 70 | 71 | .hljs-attribute, 72 | .hljs-variable, 73 | .lisp .hljs-body { 74 | color: #008080; 75 | } 76 | 77 | .hljs-regexp { 78 | color: #009926; 79 | } 80 | 81 | .hljs-symbol, 82 | .ruby .hljs-symbol .hljs-string, 83 | .lisp .hljs-keyword, 84 | .clojure .hljs-keyword, 85 | .scheme .hljs-keyword, 86 | .tex .hljs-special, 87 | .hljs-prompt { 88 | color: #990073; 89 | } 90 | 91 | .hljs-built_in { 92 | color: #0086b3; 93 | } 94 | 95 | .hljs-preprocessor, 96 | .hljs-pragma, 97 | .hljs-pi, 98 | .hljs-doctype, 99 | .hljs-shebang, 100 | .hljs-cdata { 101 | color: #999; 102 | font-weight: bold; 103 | } 104 | 105 | .hljs-deletion { 106 | background: #fdd; 107 | } 108 | 109 | .hljs-addition { 110 | background: #dfd; 111 | } 112 | 113 | .diff .hljs-change { 114 | background: #0086b3; 115 | } 116 | 117 | .hljs-chunk { 118 | color: #aaa; 119 | } 120 | -------------------------------------------------------------------------------- /doc/css/full_list.css: -------------------------------------------------------------------------------- 1 | /*** DOCUMENT STRUCTURE: list_template.eex *** 2 | body.frames 3 | section#content [.in_search] 4 | h1#full_list_header 5 | h2#sub_list_header 6 | div#nav 7 | div#search [.loading] > input#search_field 8 | ul#full_list 9 | li.node [.collpased, .search_uncollapsed, .found] 10 | a.toggle 11 | a.object_link 12 | span.node_name 13 | li.docs [.collpased, .search_uncollapsed, .found] 14 | a.toggle 15 | a.object_link 16 | span.node_name 17 | ... 18 | div.no_results 19 | */ 20 | 21 | /* DOCUMENT STYLES */ 22 | body { 23 | font: 13px "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; 24 | height: 101%; 25 | margin: 0; 26 | overflow-x: hidden; 27 | } 28 | h1 { 29 | font-size: 1.4em; 30 | margin: 0; 31 | padding: 12px 10px 0; 32 | } 33 | a:link, a:visited { 34 | color: #05a; 35 | text-decoration: none; 36 | } 37 | li { 38 | color: #888; 39 | cursor: pointer; 40 | } 41 | li:hover { 42 | background: #ddd; 43 | } 44 | span.node_name { 45 | font-size: 0.8em; 46 | } 47 | 48 | /*** LEFT FRAME ***/ 49 | .frames li { 50 | white-space: nowrap; 51 | cursor: default; 52 | } 53 | 54 | /* HEADERS */ 55 | .frames h1 { 56 | margin-top: 0; 57 | } 58 | .frames h2 { 59 | font-size: 0.9em; 60 | margin: 5px 10px 15px; 61 | } 62 | 63 | /* NAVIGATION BAR */ 64 | .nav { 65 | margin: 0 0 10px 5px; 66 | font-size: 0.9em; 67 | color: #aaa; 68 | } 69 | .nav a:link, 70 | .nav a:visited { 71 | color: #358; 72 | } 73 | .nav a:hover { 74 | background: transparent; 75 | color: #5af; 76 | } 77 | .nav span { 78 | border-left: 1px solid #ccc; 79 | padding: 0 3px 0 5px; 80 | } 81 | .nav span:first-child { 82 | border-left: 0; 83 | border-radius: 3px; 84 | } 85 | .nav span.selected { 86 | text-decoration: underline; 87 | } 88 | 89 | /* SEARCH BOX */ 90 | #search { 91 | font-size: 0.9em; 92 | color: #888; 93 | margin: 3px; margin-left: 10px; 94 | padding-left: 0; padding-right: 24px; 95 | } 96 | #search_field { 97 | width: 180px; 98 | margin-right:35px; 99 | border:2px solid #d8d8e5; 100 | padding:2px 4px; 101 | -moz-box-sizing: border-box; 102 | } 103 | #search.loading { 104 | background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat 188px center; 105 | min-height:18px; 106 | } 107 | #content #no_results { 108 | margin-left: 7px; 109 | padding: 7px 12px; 110 | } 111 | 112 | /* FULL LIST OF CONTENTS */ 113 | #full_list { 114 | list-style: none; 115 | margin-left: 0; 116 | padding: 0; 117 | } 118 | #full_list ul { 119 | margin:0; 120 | padding: 0; 121 | } 122 | #full_list li { 123 | margin: 0; 124 | padding: 5px 5px 5px 0; 125 | font-size: 1.1em; 126 | list-style: none; 127 | } 128 | #full_list li.node { 129 | padding-left: 25px; 130 | } 131 | #full_list li.docs { 132 | padding:0; 133 | } 134 | #full_list li.docs li { 135 | padding-left: 25px; 136 | } 137 | #full_list li span.node_name { 138 | display: none; 139 | } 140 | #full_list .no_padding { 141 | padding-left:0; 142 | } 143 | /* while searching */ 144 | .in_search #full_list ul { 145 | margin-left:0;} 146 | .in_search #full_list li { 147 | display: none; 148 | } 149 | .in_search #full_list li.found { 150 | display: list-item; 151 | } 152 | .in_search #full_list li a.toggle { 153 | display: none; 154 | } 155 | .in_search #full_list li span.node_name { 156 | display: block; 157 | } 158 | /* collapsed menu */ 159 | #full_list .search_uncollapsed, 160 | #full_list .search_uncollapsed ul { 161 | display:block !important; 162 | } 163 | #full_list ul.collapsed ul, 164 | #full_list ul.collapsed li, 165 | #full_list li.collapsed ul, 166 | #full_list li.collapsed li { 167 | display: none; 168 | } 169 | #full_list ul.search_uncollapsed li.found, 170 | #full_list li.search_uncollapsed li.found { 171 | display: list-item; 172 | } 173 | li.deprecated { 174 | text-decoration: line-through; 175 | font-style: italic; 176 | } 177 | li.r1 { 178 | background: #f0f0f0; 179 | } 180 | li.r2 { 181 | background: #fafafa; 182 | } 183 | /* link properties */ 184 | li a.toggle { 185 | display: block; 186 | float: left; 187 | position: relative; 188 | left: -5px; 189 | top: 4px; 190 | width: 10px; 191 | height: 9px; 192 | margin-left: -10px; 193 | text-indent: -999px; 194 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; 195 | cursor: default; 196 | } 197 | li.collapsed a.toggle { 198 | opacity: 0.5; 199 | cursor: default; 200 | background-position: top left; 201 | } 202 | li.clicked { 203 | background: #05a; 204 | color: #ccc; 205 | } 206 | li.clicked a:link, li.clicked a:visited { 207 | color: #eee; 208 | } 209 | li.clicked a.toggle { 210 | opacity: 0.5; 211 | background-position: bottom right; 212 | } 213 | li.collapsed.clicked a.toggle { 214 | background-position: top right; 215 | } 216 | -------------------------------------------------------------------------------- /doc/css/style.css: -------------------------------------------------------------------------------- 1 | /*** DOCUMENT STRUCTURE: module_template.eex *** 2 | body 3 | section#content 4 | div.breadcrumbs 5 | 6 | h1 7 | small 8 | 9 | ul.summary_links 10 | li > a 11 | ... 12 | 13 | section.docstring#moduledoc 14 | a.view_source 15 | 16 | h2#summary > span.detail_header_links > a.to_top_link 17 | table.summary 18 | tr 19 | td.summary_signature > a 20 | td.summary_synopsis > p 21 | ... 22 | 23 | section.details_list#types_details 24 | h2 > a.to_top_link 25 | div.type_detail 26 | p.typespec > a 27 | ... 28 | 29 | section.details_list#functions_details 30 | h2 31 | section.detail 32 | div.detail_header 33 | span.signature > strong 34 | div.detail_header_links 35 | span.detail_type 36 | a.detail_link 37 | a.to_top_link 38 | ul.spec 39 | li > a 40 | ... 41 | section.docstring 42 | a.view_source 43 | ... 44 | 45 | */ 46 | 47 | /* DOCUMENT STYLES */ 48 | body { 49 | font: 13px "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; 50 | padding: 0 20px; 51 | } 52 | 53 | a:link, 54 | a:visited { 55 | color: #05a; 56 | text-decoration: none; 57 | } 58 | a:hover { 59 | color: #27c; 60 | } 61 | 62 | h1 { 63 | font-size: 25px; 64 | border-top: 0; 65 | margin-top: 0; 66 | padding-top: 4px; 67 | } 68 | h1 small { 69 | color: #888; 70 | font-size: 18px; 71 | } 72 | h2 { 73 | padding: 0; 74 | padding-bottom: 3px; 75 | border-bottom: 1px #aaa solid; 76 | font-size: 1.4em; 77 | margin: 1.8em 0 0.5em; 78 | } 79 | 80 | .clear { 81 | clear: both; 82 | } 83 | 84 | table { 85 | border: 1px solid #aaa; 86 | border-collapse: collapse; 87 | margin-top: 1em; 88 | } 89 | table th { 90 | background: #fafafa; 91 | } 92 | table th, 93 | table td { 94 | border: 1px solid #ddd; 95 | padding: 0.4em 1em 0.4em 0.4em; 96 | } 97 | table tr:nth-child(odd) { 98 | background: #f0f0f0; 99 | } 100 | table tr:nth-child(even) { 101 | background: #fafafa; 102 | } 103 | 104 | /* OTHERS */ 105 | body.frames { 106 | padding: 0 5px; 107 | } 108 | li.r1 { 109 | background: #f0f0f0; 110 | } 111 | li.r2 { 112 | background: #fafafa; 113 | } 114 | div.breadcrumbs { 115 | padding-bottom: 0.5em; 116 | } 117 | 118 | /* SUMMARY LINKS */ 119 | ul.summary_links { 120 | margin: 0 0 1em 0; 121 | padding: 0em; 122 | } 123 | ul.summary_links li { 124 | display: inline-block; 125 | list-style-type: none; 126 | width: 7em; 127 | text-align: center; 128 | background: #f0f0f0; 129 | } 130 | 131 | /* DOCSTRING */ 132 | section.docstring, 133 | p.docstring { 134 | margin-right: 6em; 135 | } 136 | .docstring h1, 137 | .docstring h2, 138 | .docstring h3, 139 | .docstring h4 { 140 | padding: 0; 141 | border: 0; 142 | } 143 | .docstring h1 { 144 | font-size: 1.3em; 145 | } 146 | .docstring h2 { 147 | font-size: 1.2em; 148 | } 149 | .docstring h3, 150 | .docstring h4 { 151 | font-size: 1em; 152 | padding-top: 10px; 153 | } 154 | .docstring ul { 155 | padding-left: 20px; 156 | } 157 | .docstring li > p { 158 | margin: 0; 159 | } 160 | 161 | /* SUMMARY */ 162 | div.detail_header_links { 163 | float: right; 164 | } 165 | a.to_top_link { 166 | padding-left: 0.3em; 167 | font-size: 1em; 168 | font-weight: normal; 169 | } 170 | table.summary { 171 | border: 0; 172 | border-collapse: separate; 173 | } 174 | table.summary tr:nth-child(odd) { 175 | background: #f0f0f0; 176 | } 177 | table.summary tr:nth-child(even) { 178 | background: #fafafa; 179 | } 180 | table.summary tr td { 181 | border: 0; 182 | padding-top: 0.5em; padding-bottom: 0.5em; 183 | } 184 | td.summary_signature { 185 | padding-right: 0.5em; 186 | } 187 | td.summary_synopsis { 188 | padding-left: 0.5em; 189 | } 190 | td.summary_synopsis p { 191 | margin: 0; 192 | } 193 | 194 | /* DETAILS LIST */ 195 | .spec, .typespec { 196 | font: bold 1em Courier, monospace; 197 | } 198 | ul.spec { 199 | padding: 6px 10px 6px 25px; 200 | list-style-type: none; 201 | } 202 | .type_detail { 203 | margin-top: 15px; 204 | padding-top: 0; 205 | } 206 | .type_detail > div.typespec_doc { 207 | margin-left: 3em; 208 | } 209 | .detail { 210 | border-top: 1px dotted #aaa; 211 | margin-top: 15px; 212 | padding-top: 0; 213 | } 214 | .detail:nth-child(2) { 215 | border: 0; 216 | } 217 | div.detail_header { 218 | background: #e5e8ff; 219 | border: 1px solid #d8d8e5; 220 | border-radius: 3px; 221 | margin-top: 18px; 222 | padding: 6px 10px; 223 | } 224 | span.signature { 225 | font: normal 1.1em Monaco, Consolas, Courier, monospace; 226 | } 227 | span.detail_type { 228 | font-style: italic; 229 | font-size: 0.9em; 230 | } 231 | a.detail_link { 232 | padding-left: 0.3em; 233 | } 234 | -------------------------------------------------------------------------------- /doc/exceptions_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List of Exceptions 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 |
19 |

20 | 21 | bitpay v0.2.4 22 | 23 |

24 | 25 |

26 | 27 | Overview 28 |

29 | 30 | 35 | 36 | 37 | 38 | 87 | 88 |
89 |
90 | 91 | 92 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | bitpay v0.2.4 Documentation 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /doc/js/app.js: -------------------------------------------------------------------------------- 1 | function fixOutsideWorldLinks() { 2 | $('a').each(function() { 3 | if (window.location.host != this.host) this.target = '_parent'; 4 | }); 5 | } 6 | 7 | $(fixOutsideWorldLinks); 8 | -------------------------------------------------------------------------------- /doc/js/full_list.js: -------------------------------------------------------------------------------- 1 | var inSearch = null; 2 | var defaultSearchItemTimeOut = 0; //set to "0" if not testing 3 | var searchIndex = 0; 4 | var searchCache = []; 5 | var searchString = ''; 6 | var regexSearchString = ''; 7 | var caseSensitiveMatch = false; 8 | var ignoreKeyCodeMin = 8; 9 | var ignoreKeyCodeMax = 46; 10 | var commandKey = 91; 11 | 12 | RegExp.escape = function(text) { 13 | return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 14 | } 15 | 16 | function fullListSearch() { 17 | // generate cache 18 | searchCache = []; 19 | $('#full_list li').each(function() { 20 | var link = $(this).find('a.object_link:first'); 21 | if ( link.attr('title') ) { 22 | var fullName = link.attr('title').split(' ')[0]; 23 | searchCache.push({name:link.text(), fullName:fullName, node:$(this), link:link}); 24 | } 25 | }); 26 | 27 | $('#search input').keypress(function (e) { 28 | if (e.which == 13) { 29 | $('#full_list li.found:first').find('a.object_link:first').click(); 30 | } 31 | }); 32 | 33 | //$('#search input').keyup(function(evnt) { 34 | $('#search input').bind("keyup search reset", function(evnt) { 35 | if ((evnt.keyCode > ignoreKeyCodeMin && evnt.keyCode < ignoreKeyCodeMax) 36 | || evnt.keyCode == commandKey) { 37 | return; 38 | } 39 | 40 | $('#search').addClass('loading'); 41 | searchString = this.value; 42 | caseSensitiveMatch = searchString.match(/[A-Z]/) != null; 43 | regexSearchString = RegExp.escape(searchString); 44 | if (searchString === "") { 45 | showAllResults(); 46 | } 47 | else { 48 | if (inSearch) { 49 | clearTimeout(inSearch); 50 | } 51 | searchIndex = 0; 52 | lastRowClass = ''; 53 | $('#content').addClass('in_search'); 54 | $('#no_results').text(''); 55 | searchItem(); 56 | } 57 | }); 58 | 59 | $('#search input').focus(); 60 | } 61 | 62 | function showAllResults() { 63 | clearTimeout(inSearch); 64 | inSearch = defaultSearchItemTimeOut; 65 | $('.search_uncollapsed').removeClass('search_uncollapsed'); 66 | $('#content').removeClass('in_search'); 67 | $('#full_list li').removeClass('found').each(function() { 68 | var link = $(this).find('a.object_link:first'); 69 | link.text(link.text()); 70 | }); 71 | if (clicked) { 72 | clicked.parents('li').each(function() { 73 | $(this).removeClass('collapsed').prev().removeClass('collapsed'); 74 | }); 75 | } 76 | $('#no_results').text(''); 77 | $('#search').removeClass('loading'); 78 | highlight(); 79 | } 80 | 81 | var lastRowClass = ''; 82 | function searchItem() { 83 | for (var i = 0; i < searchCache.length / 50; i++) { 84 | var item = searchCache[searchIndex]; 85 | var searchName = (searchString.indexOf('.') != -1 ? item.fullName : item.name); 86 | var matchString = regexSearchString; 87 | var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); 88 | if (searchName.match(matchRegexp) == null) { 89 | item.node.removeClass('found'); 90 | } 91 | else { 92 | item.node.addClass('found'); 93 | item.node.parents('li').addClass('search_uncollapsed'); 94 | item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); 95 | lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; 96 | item.link.html(item.name.replace(matchRegexp, "$&")); 97 | } 98 | 99 | if (searchCache.length === searchIndex + 1) { 100 | searchDone(); 101 | return; 102 | } 103 | else { 104 | searchIndex++; 105 | } 106 | } 107 | inSearch = setTimeout('searchItem()', defaultSearchItemTimeOut); 108 | } 109 | 110 | function searchDone() { 111 | highlight(true); 112 | if ($('#full_list li.found').size() === 0) { 113 | $('#no_results').text('No results were found.').hide().fadeIn(); 114 | } 115 | else { 116 | $('#no_results').text(''); 117 | } 118 | 119 | $('#search').removeClass('loading'); 120 | clearTimeout(inSearch); 121 | inSearch = null; 122 | } 123 | 124 | clicked = null; 125 | function linkList() { 126 | $('#full_list li, #full_list li a:last').click(function(evt) { 127 | if ($(this).hasClass('toggle')) { 128 | return true; 129 | } 130 | 131 | if (this.tagName.toLowerCase() == "li") { 132 | var toggle = $(this).children('a.toggle'); 133 | if (toggle.size() > 0 && evt.pageX < toggle.offset().left) { 134 | toggle.click(); 135 | return false; 136 | } 137 | } 138 | 139 | if (clicked) { 140 | clicked.removeClass('clicked'); 141 | } 142 | 143 | var win = window.top.frames.main ? window.top.frames.main : window.parent; 144 | if (this.tagName.toLowerCase() == "a") { 145 | clicked = $(this).parent('li').addClass('clicked'); 146 | win.location = this.href; 147 | } 148 | else { 149 | clicked = $(this).addClass('clicked'); 150 | win.location = $(this).find('a:last').attr('href'); 151 | } 152 | 153 | return false; 154 | }); 155 | } 156 | 157 | function collapse() { 158 | $('#full_list a.toggle').click(function() { 159 | $(this).parent().toggleClass('collapsed').next().toggleClass('collapsed'); 160 | highlight(); 161 | return false; 162 | }); 163 | 164 | $('#full_list > li.node').each(function() { 165 | $(this).addClass('collapsed').next('li.docs').addClass('collapsed'); 166 | }); 167 | 168 | highlight(); 169 | } 170 | 171 | function highlight(no_padding) { 172 | var n = 1; 173 | $('#full_list a.object_link:visible').each(function() { 174 | var next = n == 1 ? 2 : 1; 175 | var li = $(this).parent(); 176 | li.removeClass("r" + next).addClass("r" + n); 177 | no_padding ? li.addClass("no_padding") : li.removeClass("no_padding"); 178 | n = next; 179 | }); 180 | } 181 | 182 | function escapeShortcut() { 183 | $(document).keydown(function(evt) { 184 | if (evt.which == 27) { 185 | $('#search_frame', window.top.document).slideUp(100); 186 | $('#search a', window.top.document).removeClass('active inactive'); 187 | $(window.top).focus(); 188 | } 189 | }); 190 | } 191 | 192 | $(escapeShortcut); 193 | $(fullListSearch); 194 | $(linkList); 195 | $(collapse); -------------------------------------------------------------------------------- /doc/js/highlight.pack.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * highlight.js v8.4 3 | * https://highlightjs.org/ 4 | * 5 | * Copyright (c) 2006, Ivan Sagalaev 6 | * All rights reserved. 7 | * Redistribution is allowed, under the BSD 3-Clause License 8 | * https://github.com/isagalaev/highlight.js/blob/master/LICENSE 9 | * 10 | * Date: 2014-12-28 11 | * https://highlightjs.org/download/ 12 | * Custom Package to support the following languages: 13 | * Bash, CoffeeScript, CSS, Diff, Elixir, Erlang, Erlang-REPL, 14 | * HTML/XML, HTTP, JavaScript, JSON, Markdown, SQL. 15 | * 16 | */ 17 | !function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){var n=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return n=n.map(function(e){return e.replace(/^lang(uage)?-/,"")}),n.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function o(e,n){var t={};for(var r in e)t[r]=e[r];if(n)for(var r in n)t[r]=n[r];return t}function i(e){var n=[];return function r(e,a){for(var o=e.firstChild;o;o=o.nextSibling)3==o.nodeType?a+=o.nodeValue.length:1==o.nodeType&&(n.push({event:"start",offset:a,node:o}),a=r(o,a),t(o).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:o}));return a}(e,0),n}function c(e,r,a){function o(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"==e.event?i:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=o();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=o();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(i)}else"start"==g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function u(e){function n(e){return e&&e.source||e}function t(t,r){return RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");c[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):Object.keys(a.k).forEach(function(e){u(e,a.k[e])}),a.k=c}a.lR=t(a.l||/\b[A-Za-z0-9_]+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function s(e,t,a,o){function i(e,n){for(var t=0;t";return o+=e+'">',o+n+i}function d(){if(!w.k)return n(y);var e="",t=0;w.lR.lastIndex=0;for(var r=w.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(w,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=w.lR.lastIndex,r=w.lR.exec(y)}return e+n(y.substr(t))}function h(){if(w.sL&&!R[w.sL])return n(y);var e=w.sL?s(w.sL,y,!0,L[w.sL]):l(y);return w.r>0&&(B+=e.r),"continuous"==w.subLanguageMode&&(L[w.sL]=e.top),p(e.language,e.value,!1,!0)}function v(){return void 0!==w.sL?h():d()}function b(e,t){var r=e.cN?p(e.cN,"",!0):"";e.rB?(M+=r,y=""):e.eB?(M+=n(t)+r,y=""):(M+=r,y=t),w=Object.create(e,{parent:{value:w}})}function m(e,t){if(y+=e,void 0===t)return M+=v(),0;var r=i(t,w);if(r)return M+=v(),b(r,t),r.rB?0:t.length;var a=c(w,t);if(a){var o=w;o.rE||o.eE||(y+=t),M+=v();do w.cN&&(M+=""),B+=w.r,w=w.parent;while(w!=a.parent);return o.eE&&(M+=n(t)),y="",a.starts&&b(a.starts,""),o.rE?0:t.length}if(f(t,w))throw new Error('Illegal lexeme "'+t+'" for mode "'+(w.cN||"")+'"');return y+=t,t.length||1}var x=N(e);if(!x)throw new Error('Unknown language: "'+e+'"');u(x);for(var w=o||x,L={},M="",k=w;k!=x;k=k.parent)k.cN&&(M=p(k.cN,"",!0)+M);var y="",B=0;try{for(var C,j,I=0;;){if(w.t.lastIndex=I,C=w.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}m(t.substr(I));for(var k=w;k.parent;k=k.parent)k.cN&&(M+="");return{r:B,value:M,language:e,top:w}}catch(A){if(-1!=A.message.indexOf("Illegal"))return{r:0,value:n(t)};throw A}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(N(n)){var t=s(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function f(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function g(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/(\s|^)hljs(\s|$)/)||a.push("hljs"),r&&a.push(r),a.join(" ").trim()}function p(e){var n=a(e);if(!/no(-?)highlight/.test(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?s(n,r,!0):l(r),u=i(t);if(u.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(u,i(p),r)}o.value=f(o.value),e.innerHTML=o.value,e.className=g(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",h,!1),addEventListener("load",h,!1)}function b(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function m(){return Object.keys(R)}function N(e){return R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=s,e.highlightAuto=l,e.fixMarkup=f,e.highlightBlock=p,e.configure=d,e.initHighlighting=h,e.initHighlightingOnLoad=v,e.registerLanguage=b,e.listLanguages=m,e.getLanguage=N,e.inherit=o,e.IR="[a-zA-Z][a-zA-Z0-9_]*",e.UIR="[a-zA-Z_][a-zA-Z0-9_]*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.CLCM={cN:"comment",b:"//",e:"$",c:[e.PWM]},e.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM]},e.HCM={cN:"comment",b:"#",e:"$",c:[e.PWM]},e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",t={cN:"subst",b:/#\{/,e:/}/,k:c},r=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,t]},{b:/"/,e:/"/,c:[e.BE,t]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[t,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];t.c=r;var i=e.inherit(e.TM,{b:n}),s="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(r)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:r.concat([{cN:"comment",b:"###",e:"###",c:[e.PWM]},e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("xml",function(){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"},c={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[c],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[c],starts:{e:"",rE:!0,sL:"javascript"}},e,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},c]}]}});hljs.registerLanguage("diff",function(){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("markdown",function(){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",n="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:n},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},s={eW:!0,rE:!0,l:r,k:n,r:0},i={cN:"function",bK:"def defmacro",e:/\bdo\b/,c:[e.inherit(e.TM,{b:b,starts:s})]},l=e.inherit(i,{cN:"class",bK:"defmodule defrecord",e:/\bdo\b|$|;/}),t=[a,e.HCM,l,i,{cN:"constant",b:"(\\b[A-Z_]\\w*(.)?)+",r:0},{cN:"symbol",b:":",c:[a,{b:b}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=t,s.c=t,{l:r,k:n,c:t}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,s,a,t]}});hljs.registerLanguage("javascript",function(r){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",r:10,v:[{b:/^\s*('|")use strict('|")/},{b:/^\s*('|")use asm('|")/}]},r.ASM,r.QSM,r.CLCM,r.CBCM,r.CNM,{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[r.CLCM,r.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+r.IR,r:0}]}});hljs.registerLanguage("erlang-repl",function(e){return{k:{special_functions:"spawn spawn_link self",reserved:"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},c:[{cN:"prompt",b:"^[0-9]+> ",r:10},{cN:"comment",b:"%",e:"$"},{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{cN:"constant",b:"\\?(::)?([A-Z]\\w*(::)?)+"},{cN:"arrow",b:"->"},{cN:"ok",b:"ok"},{cN:"exclamation_mark",b:"!"},{cN:"function_or_atom",b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{cN:"variable",b:"[A-Z][a-zA-Z0-9_']*",r:0}]}});hljs.registerLanguage("sql",function(e){var t={cN:"comment",b:"--",e:"$"};return{cI:!0,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup",e:/;/,eW:!0,k:{keyword:"abs absolute acos action add adddate addtime aes_decrypt aes_encrypt after aggregate all allocate alter analyze and any are as asc ascii asin assertion at atan atan2 atn2 authorization authors avg backup before begin benchmark between bin binlog bit_and bit_count bit_length bit_or bit_xor both by cache call cascade cascaded case cast catalog ceil ceiling chain change changed char_length character_length charindex charset check checksum checksum_agg choose close coalesce coercibility collate collation collationproperty column columns columns_updated commit compress concat concat_ws concurrent connect connection connection_id consistent constraint constraints continue contributors conv convert convert_tz corresponding cos cot count count_big crc32 create cross cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime data database databases datalength date_add date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts datetimeoffsetfromparts day dayname dayofmonth dayofweek dayofyear deallocate declare decode default deferrable deferred degrees delayed delete des_decrypt des_encrypt des_key_file desc describe descriptor diagnostics difference disconnect distinct distinctrow div do domain double drop dumpfile each else elt enclosed encode encrypt end end-exec engine engines eomonth errors escape escaped event eventdata events except exception exec execute exists exp explain export_set extended external extract fast fetch field fields find_in_set first first_value floor flush for force foreign format found found_rows from from_base64 from_days from_unixtime full function get get_format get_lock getdate getutcdate global go goto grant grants greatest group group_concat grouping grouping_id gtid_subset gtid_subtract handler having help hex high_priority hosts hour ident_current ident_incr ident_seed identified identity if ifnull ignore iif ilike immediate in index indicator inet6_aton inet6_ntoa inet_aton inet_ntoa infile initially inner innodb input insert install instr intersect into is is_free_lock is_ipv4 is_ipv4_compat is_ipv4_mapped is_not is_not_null is_used_lock isdate isnull isolation join key kill language last last_day last_insert_id last_value lcase lead leading least leaves left len lenght level like limit lines ln load load_file local localtime localtimestamp locate lock log log10 log2 logfile logs low_priority lower lpad ltrim make_set makedate maketime master master_pos_wait match matched max md5 medium merge microsecond mid min minute mod mode module month monthname mutex name_const names national natural nchar next no no_write_to_binlog not now nullif nvarchar oct octet_length of old_password on only open optimize option optionally or ord order outer outfile output pad parse partial partition password patindex percent_rank percentile_cont percentile_disc period_add period_diff pi plugin position pow power pragma precision prepare preserve primary prior privileges procedure procedure_analyze processlist profile profiles public publishingservername purge quarter query quick quote quotename radians rand read references regexp relative relaylog release release_lock rename repair repeat replace replicate reset restore restrict return returns reverse revoke right rlike rollback rollup round row row_count rows rpad rtrim savepoint schema scroll sec_to_time second section select serializable server session session_user set sha sha1 sha2 share show sign sin size slave sleep smalldatetimefromparts snapshot some soname soundex sounds_like space sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sql_variant_property sqlstate sqrt square start starting status std stddev stddev_pop stddev_samp stdev stdevp stop str str_to_date straight_join strcmp string stuff subdate substr substring subtime subtring_index sum switchoffset sysdate sysdatetime sysdatetimeoffset system_user sysutcdatetime table tables tablespace tan temporary terminated tertiary_weights then time time_format time_to_sec timediff timefromparts timestamp timestampadd timestampdiff timezone_hour timezone_minute to to_base64 to_days to_seconds todatetimeoffset trailing transaction translation trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse ucase uncompress uncompressed_length unhex unicode uninstall union unique unix_timestamp unknown unlock update upgrade upped upper usage use user user_resources using utc_date utc_time utc_timestamp uuid uuid_short validate_password_strength value values var var_pop var_samp variables variance varp version view warnings week weekday weekofyear weight_string when whenever where with work write xml xor year yearweek zon",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int integer interval number numeric real serial smallint varchar varying int8 serial8 text"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",a={cN:"function",b:c+"\\(",rB:!0,eE:!0,e:"\\("};return{cI:!0,i:"[=/|']",c:[e.CBCM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[a,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:c,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[e.CBCM,{cN:"rule",b:"[^\\s]",rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[a,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});hljs.registerLanguage("http",function(){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:!0}}]}});hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",a={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},n={cN:"comment",b:"%",e:"$"},b={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},i={b:"fun\\s+"+r+"/\\d+"},o={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{cN:"function_name",b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},d={cN:"tuple",b:"{",e:"}",r:0},t={cN:"variable",b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},l={cN:"variable",b:"[A-Z][a-zA-Z0-9_]*",r:0},f={b:"#"+e.UIR,r:0,rB:!0,c:[{cN:"record_name",b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:a};s.c=[n,i,e.inherit(e.ASM,{cN:""}),s,o,e.QSM,b,d,t,l,f];var u=[n,i,s,o,e.QSM,b,d,t,l,f];o.c[1].c=u,d.c=u,f.c[1].c=u;var v={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:a,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[v,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:a,c:u}},n,{cN:"pp",b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[v]},b,e.QSM,f,t,l,d,{b:/\.$/}]}}); -------------------------------------------------------------------------------- /doc/js/jquery.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery JavaScript Library v1.5.2 3 | * http://jquery.com/ 4 | * 5 | * Copyright 2011, John Resig 6 | * Dual licensed under the MIT or GPL Version 2 licenses. 7 | * http://jquery.org/license 8 | * 9 | * Includes Sizzle.js 10 | * http://sizzlejs.com/ 11 | * Copyright 2011, The Dojo Foundation 12 | * Released under the MIT, BSD, and GPL Licenses. 13 | * 14 | * Date: Thu Mar 31 15:28:23 2011 -0400 15 | */ 16 | (function(a,b){function ci(a){return d.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cf(a){if(!b_[a]){var b=d("<"+a+">").appendTo("body"),c=b.css("display");b.remove();if(c==="none"||c==="")c="block";b_[a]=c}return b_[a]}function ce(a,b){var c={};d.each(cd.concat.apply([],cd.slice(0,b)),function(){c[this]=a});return c}function b$(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function bZ(){try{return new a.XMLHttpRequest}catch(b){}}function bY(){d(a).unload(function(){for(var a in bW)bW[a](0,1)})}function bS(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var e=a.dataTypes,f={},g,h,i=e.length,j,k=e[0],l,m,n,o,p;for(g=1;g=0===c})}function P(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function H(a,b){return(a&&a!=="*"?a+".":"")+b.replace(t,"`").replace(u,"&")}function G(a){var b,c,e,f,g,h,i,j,k,l,m,n,o,p=[],q=[],s=d._data(this,"events");if(a.liveFired!==this&&s&&s.live&&!a.target.disabled&&(!a.button||a.type!=="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var t=s.live.slice(0);for(i=0;ic)break;a.currentTarget=f.elem,a.data=f.handleObj.data,a.handleObj=f.handleObj,o=f.handleObj.origHandler.apply(f.elem,arguments);if(o===!1||a.isPropagationStopped()){c=f.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function E(a,c,e){var f=d.extend({},e[0]);f.type=a,f.originalEvent={},f.liveFired=b,d.event.handle.call(c,f),f.isDefaultPrevented()&&e[0].preventDefault()}function y(){return!0}function x(){return!1}function i(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function h(a,c,e){if(e===b&&a.nodeType===1){e=a.getAttribute("data-"+c);if(typeof e==="string"){try{e=e==="true"?!0:e==="false"?!1:e==="null"?null:d.isNaN(e)?g.test(e)?d.parseJSON(e):e:parseFloat(e)}catch(f){}d.data(a,c,e)}else e=b}return e}var c=a.document,d=function(){function G(){if(!d.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(G,1);return}d.ready()}}var d=function(a,b){return new d.fn.init(a,b,g)},e=a.jQuery,f=a.$,g,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,i=/\S/,j=/^\s+/,k=/\s+$/,l=/\d/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=navigator.userAgent,w,x,y,z=Object.prototype.toString,A=Object.prototype.hasOwnProperty,B=Array.prototype.push,C=Array.prototype.slice,D=String.prototype.trim,E=Array.prototype.indexOf,F={};d.fn=d.prototype={constructor:d,init:function(a,e,f){var g,i,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!e&&c.body){this.context=c,this[0]=c.body,this.selector="body",this.length=1;return this}if(typeof a==="string"){g=h.exec(a);if(!g||!g[1]&&e)return!e||e.jquery?(e||f).find(a):this.constructor(e).find(a);if(g[1]){e=e instanceof d?e[0]:e,k=e?e.ownerDocument||e:c,j=m.exec(a),j?d.isPlainObject(e)?(a=[c.createElement(j[1])],d.fn.attr.call(a,e,!0)):a=[k.createElement(j[1])]:(j=d.buildFragment([g[1]],[k]),a=(j.cacheable?d.clone(j.fragment):j.fragment).childNodes);return d.merge(this,a)}i=c.getElementById(g[2]);if(i&&i.parentNode){if(i.id!==g[2])return f.find(a);this.length=1,this[0]=i}this.context=c,this.selector=a;return this}if(d.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return d.makeArray(a,this)},selector:"",jquery:"1.5.2",length:0,size:function(){return this.length},toArray:function(){return C.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var e=this.constructor();d.isArray(a)?B.apply(e,a):d.merge(e,a),e.prevObject=this,e.context=this.context,b==="find"?e.selector=this.selector+(this.selector?" ":"")+c:b&&(e.selector=this.selector+"."+b+"("+c+")");return e},each:function(a,b){return d.each(this,a,b)},ready:function(a){d.bindReady(),x.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(C.apply(this,arguments),"slice",C.call(arguments).join(","))},map:function(a){return this.pushStack(d.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:B,sort:[].sort,splice:[].splice},d.fn.init.prototype=d.fn,d.extend=d.fn.extend=function(){var a,c,e,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i==="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!=="object"&&!d.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;x.resolveWith(c,[d]),d.fn.trigger&&d(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!x){x=d._Deferred();if(c.readyState==="complete")return setTimeout(d.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",y,!1),a.addEventListener("load",d.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",y),a.attachEvent("onload",d.ready);var b=!1;try{b=a.frameElement==null}catch(e){}c.documentElement.doScroll&&b&&G()}}},isFunction:function(a){return d.type(a)==="function"},isArray:Array.isArray||function(a){return d.type(a)==="array"},isWindow:function(a){return a&&typeof a==="object"&&"setInterval"in a},isNaN:function(a){return a==null||!l.test(a)||isNaN(a)},type:function(a){return a==null?String(a):F[z.call(a)]||"object"},isPlainObject:function(a){if(!a||d.type(a)!=="object"||a.nodeType||d.isWindow(a))return!1;if(a.constructor&&!A.call(a,"constructor")&&!A.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a){}return c===b||A.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!=="string"||!b)return null;b=d.trim(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return a.JSON&&a.JSON.parse?a.JSON.parse(b):(new Function("return "+b))();d.error("Invalid JSON: "+b)},parseXML:function(b,c,e){a.DOMParser?(e=new DOMParser,c=e.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),e=c.documentElement,(!e||!e.nodeName||e.nodeName==="parsererror")&&d.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(a){if(a&&i.test(a)){var b=c.head||c.getElementsByTagName("head")[0]||c.documentElement,e=c.createElement("script");d.support.scriptEval()?e.appendChild(c.createTextNode(a)):e.text=a,b.insertBefore(e,b.firstChild),b.removeChild(e)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,e){var f,g=0,h=a.length,i=h===b||d.isFunction(a);if(e){if(i){for(f in a)if(c.apply(a[f],e)===!1)break}else for(;g1?f.call(arguments,0):c,--g||h.resolveWith(h,f.call(b,0))}}var b=arguments,c=0,e=b.length,g=e,h=e<=1&&a&&d.isFunction(a.promise)?a:d.Deferred();if(e>1){for(;c
a";var e=b.getElementsByTagName("*"),f=b.getElementsByTagName("a")[0],g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=b.getElementsByTagName("input")[0];if(e&&e.length&&f){d.support={leadingWhitespace:b.firstChild.nodeType===3,tbody:!b.getElementsByTagName("tbody").length,htmlSerialize:!!b.getElementsByTagName("link").length,style:/red/.test(f.getAttribute("style")),hrefNormalized:f.getAttribute("href")==="/a",opacity:/^0.55$/.test(f.style.opacity),cssFloat:!!f.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,deleteExpando:!0,optDisabled:!1,checkClone:!1,noCloneEvent:!0,noCloneChecked:!0,boxModel:null,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableHiddenOffsets:!0,reliableMarginRight:!0},i.checked=!0,d.support.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,d.support.optDisabled=!h.disabled;var j=null;d.support.scriptEval=function(){if(j===null){var b=c.documentElement,e=c.createElement("script"),f="script"+d.now();try{e.appendChild(c.createTextNode("window."+f+"=1;"))}catch(g){}b.insertBefore(e,b.firstChild),a[f]?(j=!0,delete a[f]):j=!1,b.removeChild(e)}return j};try{delete b.test}catch(k){d.support.deleteExpando=!1}!b.addEventListener&&b.attachEvent&&b.fireEvent&&(b.attachEvent("onclick",function l(){d.support.noCloneEvent=!1,b.detachEvent("onclick",l)}),b.cloneNode(!0).fireEvent("onclick")),b=c.createElement("div"),b.innerHTML="";var m=c.createDocumentFragment();m.appendChild(b.firstChild),d.support.checkClone=m.cloneNode(!0).cloneNode(!0).lastChild.checked,d(function(){var a=c.createElement("div"),b=c.getElementsByTagName("body")[0];if(b){a.style.width=a.style.paddingLeft="1px",b.appendChild(a),d.boxModel=d.support.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,d.support.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",d.support.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
";var e=a.getElementsByTagName("td");d.support.reliableHiddenOffsets=e[0].offsetHeight===0,e[0].style.display="",e[1].style.display="none",d.support.reliableHiddenOffsets=d.support.reliableHiddenOffsets&&e[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(a.style.width="1px",a.style.marginRight="0",d.support.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(a,null).marginRight,10)||0)===0),b.removeChild(a).style.display="none",a=e=null}});var n=function(a){var b=c.createElement("div");a="on"+a;if(!b.attachEvent)return!0;var d=a in b;d||(b.setAttribute(a,"return;"),d=typeof b[a]==="function");return d};d.support.submitBubbles=n("submit"),d.support.changeBubbles=n("change"),b=e=f=null}}();var g=/^(?:\{.*\}|\[.*\])$/;d.extend({cache:{},uuid:0,expando:"jQuery"+(d.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?d.cache[a[d.expando]]:a[d.expando];return!!a&&!i(a)},data:function(a,c,e,f){if(d.acceptData(a)){var g=d.expando,h=typeof c==="string",i,j=a.nodeType,k=j?d.cache:a,l=j?a[d.expando]:a[d.expando]&&d.expando;if((!l||f&&l&&!k[l][g])&&h&&e===b)return;l||(j?a[d.expando]=l=++d.uuid:l=d.expando),k[l]||(k[l]={},j||(k[l].toJSON=d.noop));if(typeof c==="object"||typeof c==="function")f?k[l][g]=d.extend(k[l][g],c):k[l]=d.extend(k[l],c);i=k[l],f&&(i[g]||(i[g]={}),i=i[g]),e!==b&&(i[c]=e);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,e){if(d.acceptData(b)){var f=d.expando,g=b.nodeType,h=g?d.cache:b,j=g?b[d.expando]:d.expando;if(!h[j])return;if(c){var k=e?h[j][f]:h[j];if(k){delete k[c];if(!i(k))return}}if(e){delete h[j][f];if(!i(h[j]))return}var l=h[j][f];d.support.deleteExpando||h!=a?delete h[j]:h[j]=null,l?(h[j]={},g||(h[j].toJSON=d.noop),h[j][f]=l):g&&(d.support.deleteExpando?delete b[d.expando]:b.removeAttribute?b.removeAttribute(d.expando):b[d.expando]=null)}},_data:function(a,b,c){return d.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=d.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),d.fn.extend({data:function(a,c){var e=null;if(typeof a==="undefined"){if(this.length){e=d.data(this[0]);if(this[0].nodeType===1){var f=this[0].attributes,g;for(var i=0,j=f.length;i-1)return!0;return!1},val:function(a){if(!arguments.length){var c=this[0];if(c){if(d.nodeName(c,"option")){var e=c.attributes.value;return!e||e.specified?c.value:c.text}if(d.nodeName(c,"select")){var f=c.selectedIndex,g=[],h=c.options,i=c.type==="select-one";if(f<0)return null;for(var j=i?f:0,k=i?f+1:h.length;j=0;else if(d.nodeName(this,"select")){var f=d.makeArray(e);d("option",this).each(function(){this.selected=d.inArray(d(this).val(),f)>=0}),f.length||(this.selectedIndex=-1)}else this.value=e}})}}),d.extend({attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,e,f){if(!a||a.nodeType===3||a.nodeType===8||a.nodeType===2)return b;if(f&&c in d.attrFn)return d(a)[c](e);var g=a.nodeType!==1||!d.isXMLDoc(a),h=e!==b;c=g&&d.props[c]||c;if(a.nodeType===1){var i=m.test(c);if(c==="selected"&&!d.support.optSelected){var j=a.parentNode;j&&(j.selectedIndex,j.parentNode&&j.parentNode.selectedIndex)}if((c in a||a[c]!==b)&&g&&!i){h&&(c==="type"&&n.test(a.nodeName)&&a.parentNode&&d.error("type property can't be changed"),e===null?a.nodeType===1&&a.removeAttribute(c):a[c]=e);if(d.nodeName(a,"form")&&a.getAttributeNode(c))return a.getAttributeNode(c).nodeValue;if(c==="tabIndex"){var k=a.getAttributeNode("tabIndex");return k&&k.specified?k.value:o.test(a.nodeName)||p.test(a.nodeName)&&a.href?0:b}return a[c]}if(!d.support.style&&g&&c==="style"){h&&(a.style.cssText=""+e);return a.style.cssText}h&&a.setAttribute(c,""+e);if(!a.attributes[c]&&(a.hasAttribute&&!a.hasAttribute(c)))return b;var l=!d.support.hrefNormalized&&g&&i?a.getAttribute(c,2):a.getAttribute(c);return l===null?b:l}h&&(a[c]=e);return a[c]}});var r=/\.(.*)$/,s=/^(?:textarea|input|select)$/i,t=/\./g,u=/ /g,v=/[^\w\s.|`]/g,w=function(a){return a.replace(v,"\\$&")};d.event={add:function(c,e,f,g){if(c.nodeType!==3&&c.nodeType!==8){try{d.isWindow(c)&&(c!==a&&!c.frameElement)&&(c=a)}catch(h){}if(f===!1)f=x;else if(!f)return;var i,j;f.handler&&(i=f,f=i.handler),f.guid||(f.guid=d.guid++);var k=d._data(c);if(!k)return;var l=k.events,m=k.handle;l||(k.events=l={}),m||(k.handle=m=function(a){return typeof d!=="undefined"&&d.event.triggered!==a.type?d.event.handle.apply(m.elem,arguments):b}),m.elem=c,e=e.split(" ");var n,o=0,p;while(n=e[o++]){j=i?d.extend({},i):{handler:f,data:g},n.indexOf(".")>-1?(p=n.split("."),n=p.shift(),j.namespace=p.slice(0).sort().join(".")):(p=[],j.namespace=""),j.type=n,j.guid||(j.guid=f.guid);var q=l[n],r=d.event.special[n]||{};if(!q){q=l[n]=[];if(!r.setup||r.setup.call(c,g,p,m)===!1)c.addEventListener?c.addEventListener(n,m,!1):c.attachEvent&&c.attachEvent("on"+n,m)}r.add&&(r.add.call(c,j),j.handler.guid||(j.handler.guid=f.guid)),q.push(j),d.event.global[n]=!0}c=null}},global:{},remove:function(a,c,e,f){if(a.nodeType!==3&&a.nodeType!==8){e===!1&&(e=x);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=d.hasData(a)&&d._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(e=c.handler,c=c.type);if(!c||typeof c==="string"&&c.charAt(0)==="."){c=c||"";for(h in t)d.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+d.map(m.slice(0).sort(),w).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!e){for(j=0;j=0&&(a.type=f=f.slice(0,-1),a.exclusive=!0),e||(a.stopPropagation(),d.event.global[f]&&d.each(d.cache,function(){var b=d.expando,e=this[b];e&&e.events&&e.events[f]&&d.event.trigger(a,c,e.handle.elem)}));if(!e||e.nodeType===3||e.nodeType===8)return b;a.result=b,a.target=e,c=d.makeArray(c),c.unshift(a)}a.currentTarget=e;var h=d._data(e,"handle");h&&h.apply(e,c);var i=e.parentNode||e.ownerDocument;try{e&&e.nodeName&&d.noData[e.nodeName.toLowerCase()]||e["on"+f]&&e["on"+f].apply(e,c)===!1&&(a.result=!1,a.preventDefault())}catch(j){}if(!a.isPropagationStopped()&&i)d.event.trigger(a,c,i,!0);else if(!a.isDefaultPrevented()){var k,l=a.target,m=f.replace(r,""),n=d.nodeName(l,"a")&&m==="click",o=d.event.special[m]||{};if((!o._default||o._default.call(e,a)===!1)&&!n&&!(l&&l.nodeName&&d.noData[l.nodeName.toLowerCase()])){try{l[m]&&(k=l["on"+m],k&&(l["on"+m]=null),d.event.triggered=a.type,l[m]())}catch(p){}k&&(l["on"+m]=k),d.event.triggered=b}}},handle:function(c){var e,f,g,h,i,j=[],k=d.makeArray(arguments);c=k[0]=d.event.fix(c||a.event),c.currentTarget=this,e=c.type.indexOf(".")<0&&!c.exclusive,e||(g=c.type.split("."),c.type=g.shift(),j=g.slice(0).sort(),h=new RegExp("(^|\\.)"+j.join("\\.(?:.*\\.)?")+"(\\.|$)")),c.namespace=c.namespace||j.join("."),i=d._data(this,"events"),f=(i||{})[c.type];if(i&&f){f=f.slice(0);for(var l=0,m=f.length;l-1?d.map(a.options,function(a){return a.selected}).join("-"):"":a.nodeName.toLowerCase()==="select"&&(c=a.selectedIndex);return c},D=function D(a){var c=a.target,e,f;if(s.test(c.nodeName)&&!c.readOnly){e=d._data(c,"_change_data"),f=C(c),(a.type!=="focusout"||c.type!=="radio")&&d._data(c,"_change_data",f);if(e===b||f===e)return;if(e!=null||f)a.type="change",a.liveFired=b,d.event.trigger(a,arguments[1],c)}};d.event.special.change={filters:{focusout:D,beforedeactivate:D,click:function(a){var b=a.target,c=b.type;(c==="radio"||c==="checkbox"||b.nodeName.toLowerCase()==="select")&&D.call(this,a)},keydown:function(a){var b=a.target,c=b.type;(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&D.call(this,a)},beforeactivate:function(a){var b=a.target;d._data(b,"_change_data",C(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in B)d.event.add(this,c+".specialChange",B[c]);return s.test(this.nodeName)},teardown:function(a){d.event.remove(this,".specialChange");return s.test(this.nodeName)}},B=d.event.special.change.filters,B.focus=B.beforeactivate}c.addEventListener&&d.each({focus:"focusin",blur:"focusout"},function(a,b){function f(a){var c=d.event.fix(a);c.type=b,c.originalEvent={},d.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var e=0;d.event.special[b]={setup:function(){e++===0&&c.addEventListener(a,f,!0)},teardown:function(){--e===0&&c.removeEventListener(a,f,!0)}}}),d.each(["bind","one"],function(a,c){d.fn[c]=function(a,e,f){if(typeof a==="object"){for(var g in a)this[c](g,e,a[g],f);return this}if(d.isFunction(e)||e===!1)f=e,e=b;var h=c==="one"?d.proxy(f,function(a){d(this).unbind(a,h);return f.apply(this,arguments)}):f;if(a==="unload"&&c!=="one")this.one(a,e,f);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},d.attrFn&&(d.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,e,g){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!=="string")return e;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(f.call(n)==="[object Array]")if(u)if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&e.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&e.push(j[t]);else e.push.apply(e,n);else p(n,e);o&&(k(o,h,e,g),k.uniqueSort(e));return e};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b==="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return"text"===c&&(b===c||b===null)},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(f.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length==="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!=="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!=="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!=="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!=="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!=="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(var g=c;g0},closest:function(a,b){var c=[],e,f,g=this[0];if(d.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(e=0,f=a.length;e-1:d(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=N.test(a)?d(a,b||this.context):null;for(e=0,f=this.length;e-1:d.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b)break}}c=c.length>1?d.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a==="string")return d.inArray(this[0],a?d(a):this.parent().children());return d.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a==="string"?d(a,b):d.makeArray(a),e=d.merge(this.get(),c);return this.pushStack(P(c[0])||P(e[0])?e:d.unique(e))},andSelf:function(){return this.add(this.prevObject)}}),d.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return d.dir(a,"parentNode")},parentsUntil:function(a,b,c){return d.dir(a,"parentNode",c)},next:function(a){return d.nth(a,2,"nextSibling")},prev:function(a){return d.nth(a,2,"previousSibling")},nextAll:function(a){return d.dir(a,"nextSibling")},prevAll:function(a){return d.dir(a,"previousSibling")},nextUntil:function(a,b,c){return d.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return d.dir(a,"previousSibling",c)},siblings:function(a){return d.sibling(a.parentNode.firstChild,a)},children:function(a){return d.sibling(a.firstChild)},contents:function(a){return d.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:d.makeArray(a.childNodes)}},function(a,b){d.fn[a]=function(c,e){var f=d.map(this,b,c),g=M.call(arguments);I.test(a)||(e=c),e&&typeof e==="string"&&(f=d.filter(e,f)),f=this.length>1&&!O[a]?d.unique(f):f,(this.length>1||K.test(e))&&J.test(a)&&(f=f.reverse());return this.pushStack(f,a,g.join(","))}}),d.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?d.find.matchesSelector(b[0],a)?[b[0]]:[]:d.find.matches(a,b)},dir:function(a,c,e){var f=[],g=a[c];while(g&&g.nodeType!==9&&(e===b||g.nodeType!==1||!d(g).is(e)))g.nodeType===1&&f.push(g),g=g[c];return f},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var R=/ jQuery\d+="(?:\d+|null)"/g,S=/^\s+/,T=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,U=/<([\w:]+)/,V=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};Z.optgroup=Z.option,Z.tbody=Z.tfoot=Z.colgroup=Z.caption=Z.thead,Z.th=Z.td,d.support.htmlSerialize||(Z._default=[1,"div
","
"]),d.fn.extend({text:function(a){if(d.isFunction(a))return this.each(function(b){var c=d(this);c.text(a.call(this,b,c.text()))});if(typeof a!=="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return d.text(this)},wrapAll:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapAll(a.call(this,b))});if(this[0]){var b=d(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(d.isFunction(a))return this.each(function(b){d(this).wrapInner(a.call(this,b))});return this.each(function(){var b=d(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){d(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){d.nodeName(this,"body")||d(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=d(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,d(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,e;(e=this[c])!=null;c++)if(!a||d.filter(a,[e]).length)!b&&e.nodeType===1&&(d.cleanData(e.getElementsByTagName("*")),d.cleanData([e])),e.parentNode&&e.parentNode.removeChild(e);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&d.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return d.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(R,""):null;if(typeof a!=="string"||X.test(a)||!d.support.leadingWhitespace&&S.test(a)||Z[(U.exec(a)||["",""])[1].toLowerCase()])d.isFunction(a)?this.each(function(b){var c=d(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);else{a=a.replace(T,"<$1>");try{for(var c=0,e=this.length;c1&&l0?this.clone(!0):this).get();d(f[h])[b](j),e=e.concat(j)}return this.pushStack(e,a,f.selector)}}),d.extend({clone:function(a,b,c){var e=a.cloneNode(!0),f,g,h;if((!d.support.noCloneEvent||!d.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!d.isXMLDoc(a)){ba(a,e),f=bb(a),g=bb(e);for(h=0;f[h];++h)ba(f[h],g[h])}if(b){_(a,e);if(c){f=bb(a),g=bb(e);for(h=0;f[h];++h)_(f[h],g[h])}}return e},clean:function(a,b,e,f){b=b||c,typeof b.createElement==="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var g=[];for(var h=0,i;(i=a[h])!=null;h++){typeof i==="number"&&(i+="");if(!i)continue;if(typeof i!=="string"||W.test(i)){if(typeof i==="string"){i=i.replace(T,"<$1>");var j=(U.exec(i)||["",""])[1].toLowerCase(),k=Z[j]||Z._default,l=k[0],m=b.createElement("div");m.innerHTML=k[1]+i+k[2];while(l--)m=m.lastChild;if(!d.support.tbody){var n=V.test(i),o=j==="table"&&!n?m.firstChild&&m.firstChild.childNodes:k[1]===""&&!n?m.childNodes:[];for(var p=o.length-1;p>=0;--p)d.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!d.support.leadingWhitespace&&S.test(i)&&m.insertBefore(b.createTextNode(S.exec(i)[0]),m.firstChild),i=m.childNodes}}else i=b.createTextNode(i);i.nodeType?g.push(i):g=d.merge(g,i)}if(e)for(h=0;g[h];h++)!f||!d.nodeName(g[h],"script")||g[h].type&&g[h].type.toLowerCase()!=="text/javascript"?(g[h].nodeType===1&&g.splice.apply(g,[h+1,0].concat(d.makeArray(g[h].getElementsByTagName("script")))),e.appendChild(g[h])):f.push(g[h].parentNode?g[h].parentNode.removeChild(g[h]):g[h]);return g},cleanData:function(a){var b,c,e=d.cache,f=d.expando,g=d.event.special,h=d.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&d.noData[j.nodeName.toLowerCase()])continue;c=j[d.expando];if(c){b=e[c]&&e[c][f];if(b&&b.events){for(var k in b.events)g[k]?d.event.remove(j,k):d.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[d.expando]:j.removeAttribute&&j.removeAttribute(d.expando),delete e[c]}}}});var bd=/alpha\([^)]*\)/i,be=/opacity=([^)]*)/,bf=/-([a-z])/ig,bg=/([A-Z]|^ms)/g,bh=/^-?\d+(?:px)?$/i,bi=/^-?\d/,bj={position:"absolute",visibility:"hidden",display:"block"},bk=["Left","Right"],bl=["Top","Bottom"],bm,bn,bo,bp=function(a,b){return b.toUpperCase()};d.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return d.access(this,a,c,!0,function(a,c,e){return e!==b?d.style(a,c,e):d.css(a,c)})},d.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bm(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0},cssProps:{"float":d.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,e,f){if(a&&a.nodeType!==3&&a.nodeType!==8&&a.style){var g,h=d.camelCase(c),i=a.style,j=d.cssHooks[h];c=d.cssProps[h]||h;if(e===b){if(j&&"get"in j&&(g=j.get(a,!1,f))!==b)return g;return i[c]}if(typeof e==="number"&&isNaN(e)||e==null)return;typeof e==="number"&&!d.cssNumber[h]&&(e+="px");if(!j||!("set"in j)||(e=j.set(a,e))!==b)try{i[c]=e}catch(k){}}},css:function(a,c,e){var f,g=d.camelCase(c),h=d.cssHooks[g];c=d.cssProps[g]||g;if(h&&"get"in h&&(f=h.get(a,!0,e))!==b)return f;if(bm)return bm(a,c,g)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bf,bp)}}),d.curCSS=d.css,d.each(["height","width"],function(a,b){d.cssHooks[b]={get:function(a,c,e){var f;if(c){a.offsetWidth!==0?f=bq(a,b,e):d.swap(a,bj,function(){f=bq(a,b,e)});if(f<=0){f=bm(a,b,b),f==="0px"&&bo&&(f=bo(a,b,b));if(f!=null)return f===""||f==="auto"?"0px":f}if(f<0||f==null){f=a.style[b];return f===""||f==="auto"?"0px":f}return typeof f==="string"?f:f+"px"}},set:function(a,b){if(!bh.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),d.support.opacity||(d.cssHooks.opacity={get:function(a,b){return be.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style;c.zoom=1;var e=d.isNaN(b)?"":"alpha(opacity="+b*100+")",f=c.filter||"";c.filter=bd.test(f)?f.replace(bd,e):c.filter+" "+e}}),d(function(){d.support.reliableMarginRight||(d.cssHooks.marginRight={get:function(a,b){var c;d.swap(a,{display:"inline-block"},function(){b?c=bm(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bn=function(a,c,e){var f,g,h;e=e.replace(bg,"-$1").toLowerCase();if(!(g=a.ownerDocument.defaultView))return b;if(h=g.getComputedStyle(a,null))f=h.getPropertyValue(e),f===""&&!d.contains(a.ownerDocument.documentElement,a)&&(f=d.style(a,e));return f}),c.documentElement.currentStyle&&(bo=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bh.test(d)&&bi.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bm=bn||bo,d.expr&&d.expr.filters&&(d.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!d.support.reliableHiddenOffsets&&(a.style.display||d.css(a,"display"))==="none"},d.expr.filters.visible=function(a){return!d.expr.filters.hidden(a)});var br=/%20/g,bs=/\[\]$/,bt=/\r?\n/g,bu=/#.*$/,bv=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bw=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bx=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,by=/^(?:GET|HEAD)$/,bz=/^\/\//,bA=/\?/,bB=/)<[^<]*)*<\/script>/gi,bC=/^(?:select|textarea)/i,bD=/\s+/,bE=/([?&])_=[^&]*/,bF=/(^|\-)([a-z])/g,bG=function(a,b,c){return b+c.toUpperCase()},bH=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bI=d.fn.load,bJ={},bK={},bL,bM;try{bL=c.location.href}catch(bN){bL=c.createElement("a"),bL.href="",bL=bL.href}bM=bH.exec(bL.toLowerCase())||[],d.fn.extend({load:function(a,c,e){if(typeof a!=="string"&&bI)return bI.apply(this,arguments);if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var g=a.slice(f,a.length);a=a.slice(0,f)}var h="GET";c&&(d.isFunction(c)?(e=c,c=b):typeof c==="object"&&(c=d.param(c,d.ajaxSettings.traditional),h="POST"));var i=this;d.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?d("
").append(c.replace(bB,"")).find(g):c)),e&&i.each(e,[c,b,a])}});return this},serialize:function(){return d.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?d.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bC.test(this.nodeName)||bw.test(this.type))}).map(function(a,b){var c=d(this).val();return c==null?null:d.isArray(c)?d.map(c,function(a,c){return{name:b.name,value:a.replace(bt,"\r\n")}}):{name:b.name,value:c.replace(bt,"\r\n")}}).get()}}),d.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){d.fn[b]=function(a){return this.bind(b,a)}}),d.each(["get","post"],function(a,c){d[c]=function(a,e,f,g){d.isFunction(e)&&(g=g||f,f=e,e=b);return d.ajax({type:c,url:a,data:e,success:f,dataType:g})}}),d.extend({getScript:function(a,c){return d.get(a,b,c,"script")},getJSON:function(a,b,c){return d.get(a,b,c,"json")},ajaxSetup:function(a,b){b?d.extend(!0,a,d.ajaxSettings,b):(b=a,a=d.extend(!0,d.ajaxSettings,b));for(var c in {context:1,url:1})c in b?a[c]=b[c]:c in d.ajaxSettings&&(a[c]=d.ajaxSettings[c]);return a},ajaxSettings:{url:bL,isLocal:bx.test(bM[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":d.parseJSON,"text xml":d.parseXML}},ajaxPrefilter:bO(bJ),ajaxTransport:bO(bK),ajax:function(a,c){function v(a,c,l,n){if(r!==2){r=2,p&&clearTimeout(p),o=b,m=n||"",u.readyState=a?4:0;var q,t,v,w=l?bR(e,u,l):b,x,y;if(a>=200&&a<300||a===304){if(e.ifModified){if(x=u.getResponseHeader("Last-Modified"))d.lastModified[k]=x;if(y=u.getResponseHeader("Etag"))d.etag[k]=y}if(a===304)c="notmodified",q=!0;else try{t=bS(e,w),c="success",q=!0}catch(z){c="parsererror",v=z}}else{v=c;if(!c||a)c="error",a<0&&(a=0)}u.status=a,u.statusText=c,q?h.resolveWith(f,[t,c,u]):h.rejectWith(f,[u,c,v]),u.statusCode(j),j=b,s&&g.trigger("ajax"+(q?"Success":"Error"),[u,e,q?t:v]),i.resolveWith(f,[u,c]),s&&(g.trigger("ajaxComplete",[u,e]),--d.active||d.event.trigger("ajaxStop"))}}typeof a==="object"&&(c=a,a=b),c=c||{};var e=d.ajaxSetup({},c),f=e.context||e,g=f!==e&&(f.nodeType||f instanceof d)?d(f):d.event,h=d.Deferred(),i=d._Deferred(),j=e.statusCode||{},k,l={},m,n,o,p,q,r=0,s,t,u={readyState:0,setRequestHeader:function(a,b){r||(l[a.toLowerCase().replace(bF,bG)]=b);return this},getAllResponseHeaders:function(){return r===2?m:null},getResponseHeader:function(a){var c;if(r===2){if(!n){n={};while(c=bv.exec(m))n[c[1].toLowerCase()]=c[2]}c=n[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){r||(e.mimeType=a);return this},abort:function(a){a=a||"abort",o&&o.abort(a),v(0,a);return this}};h.promise(u),u.success=u.done,u.error=u.fail,u.complete=i.done,u.statusCode=function(a){if(a){var b;if(r<2)for(b in a)j[b]=[j[b],a[b]];else b=a[u.status],u.then(b,b)}return this},e.url=((a||e.url)+"").replace(bu,"").replace(bz,bM[1]+"//"),e.dataTypes=d.trim(e.dataType||"*").toLowerCase().split(bD),e.crossDomain==null&&(q=bH.exec(e.url.toLowerCase()),e.crossDomain=q&&(q[1]!=bM[1]||q[2]!=bM[2]||(q[3]||(q[1]==="http:"?80:443))!=(bM[3]||(bM[1]==="http:"?80:443)))),e.data&&e.processData&&typeof e.data!=="string"&&(e.data=d.param(e.data,e.traditional)),bP(bJ,e,c,u);if(r===2)return!1;s=e.global,e.type=e.type.toUpperCase(),e.hasContent=!by.test(e.type),s&&d.active++===0&&d.event.trigger("ajaxStart");if(!e.hasContent){e.data&&(e.url+=(bA.test(e.url)?"&":"?")+e.data),k=e.url;if(e.cache===!1){var w=d.now(),x=e.url.replace(bE,"$1_="+w);e.url=x+(x===e.url?(bA.test(e.url)?"&":"?")+"_="+w:"")}}if(e.data&&e.hasContent&&e.contentType!==!1||c.contentType)l["Content-Type"]=e.contentType;e.ifModified&&(k=k||e.url,d.lastModified[k]&&(l["If-Modified-Since"]=d.lastModified[k]),d.etag[k]&&(l["If-None-Match"]=d.etag[k])),l.Accept=e.dataTypes[0]&&e.accepts[e.dataTypes[0]]?e.accepts[e.dataTypes[0]]+(e.dataTypes[0]!=="*"?", */*; q=0.01":""):e.accepts["*"];for(t in e.headers)u.setRequestHeader(t,e.headers[t]);if(e.beforeSend&&(e.beforeSend.call(f,u,e)===!1||r===2)){u.abort();return!1}for(t in {success:1,error:1,complete:1})u[t](e[t]);o=bP(bK,e,c,u);if(o){u.readyState=1,s&&g.trigger("ajaxSend",[u,e]),e.async&&e.timeout>0&&(p=setTimeout(function(){u.abort("timeout")},e.timeout));try{r=1,o.send(l,v)}catch(y){status<2?v(-1,y):d.error(y)}}else v(-1,"No Transport");return u},param:function(a,c){var e=[],f=function(a,b){b=d.isFunction(b)?b():b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=d.ajaxSettings.traditional);if(d.isArray(a)||a.jquery&&!d.isPlainObject(a))d.each(a,function(){f(this.name,this.value)});else for(var g in a)bQ(g,a[g],c,f);return e.join("&").replace(br,"+")}}),d.extend({active:0,lastModified:{},etag:{}});var bT=d.now(),bU=/(\=)\?(&|$)|\?\?/i;d.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return d.expando+"_"+bT++}}),d.ajaxPrefilter("json jsonp",function(b,c,e){var f=typeof b.data==="string";if(b.dataTypes[0]==="jsonp"||c.jsonpCallback||c.jsonp!=null||b.jsonp!==!1&&(bU.test(b.url)||f&&bU.test(b.data))){var g,h=b.jsonpCallback=d.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2",m=function(){a[h]=i,g&&d.isFunction(i)&&a[h](g[0])};b.jsonp!==!1&&(j=j.replace(bU,l),b.url===j&&(f&&(k=k.replace(bU,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},e.then(m,m),b.converters["script json"]=function(){g||d.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),d.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){d.globalEval(a);return a}}}),d.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),d.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var bV=d.now(),bW,bX;d.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&bZ()||b$()}:bZ,bX=d.ajaxSettings.xhr(),d.support.ajax=!!bX,d.support.cors=bX&&"withCredentials"in bX,bX=b,d.support.ajax&&d.ajaxTransport(function(a){if(!a.crossDomain||d.support.cors){var c;return{send:function(e,f){var g=a.xhr(),h,i;a.username?g.open(a.type,a.url,a.async,a.username,a.password):g.open(a.type,a.url,a.async);if(a.xhrFields)for(i in a.xhrFields)g[i]=a.xhrFields[i];a.mimeType&&g.overrideMimeType&&g.overrideMimeType(a.mimeType),!a.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(i in e)g.setRequestHeader(i,e[i])}catch(j){}g.send(a.hasContent&&a.data||null),c=function(e,i){var j,k,l,m,n;try{if(c&&(i||g.readyState===4)){c=b,h&&(g.onreadystatechange=d.noop,delete bW[h]);if(i)g.readyState!==4&&g.abort();else{j=g.status,l=g.getAllResponseHeaders(),m={},n=g.responseXML,n&&n.documentElement&&(m.xml=n),m.text=g.responseText;try{k=g.statusText}catch(o){k=""}j||!a.isLocal||a.crossDomain?j===1223&&(j=204):j=m.text?200:404}}}catch(p){i||f(-1,p)}m&&f(j,k,m,l)},a.async&&g.readyState!==4?(bW||(bW={},bY()),h=bV++,g.onreadystatechange=bW[h]=c):c()},abort:function(){c&&c(0,1)}}}});var b_={},ca=/^(?:toggle|show|hide)$/,cb=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cc,cd=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];d.fn.extend({show:function(a,b,c){var e,f;if(a||a===0)return this.animate(ce("show",3),a,b,c);for(var g=0,h=this.length;g=0;a--)c[a].elem===this&&(b&&c[a](!0),c.splice(a,1))}),b||this.dequeue();return this}}),d.each({slideDown:ce("show",1),slideUp:ce("hide",1),slideToggle:ce("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){d.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),d.extend({speed:function(a,b,c){var e=a&&typeof a==="object"?d.extend({},a):{complete:c||!c&&b||d.isFunction(a)&&a,duration:a,easing:c&&b||b&&!d.isFunction(b)&&b};e.duration=d.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in d.fx.speeds?d.fx.speeds[e.duration]:d.fx.speeds._default,e.old=e.complete,e.complete=function(){e.queue!==!1&&d(this).dequeue(),d.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig||(b.orig={})}}),d.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(d.fx.step[this.prop]||d.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=d.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return e.step(a)}var e=this,f=d.fx;this.startTime=d.now(),this.start=a,this.end=b,this.unit=c||this.unit||(d.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&d.timers.push(g)&&!cc&&(cc=setInterval(f.tick,f.interval))},show:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),d(this.elem).show()},hide:function(){this.options.orig[this.prop]=d.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=d.now(),c=!0;if(a||b>=this.options.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),this.options.curAnim[this.prop]=!0;for(var e in this.options.curAnim)this.options.curAnim[e]!==!0&&(c=!1);if(c){if(this.options.overflow!=null&&!d.support.shrinkWrapBlocks){var f=this.elem,g=this.options;d.each(["","X","Y"],function(a,b){f.style["overflow"+b]=g.overflow[a]})}this.options.hide&&d(this.elem).hide();if(this.options.hide||this.options.show)for(var h in this.options.curAnim)d.style(this.elem,h,this.options.orig[h]);this.options.complete.call(this.elem)}return!1}var i=b-this.startTime;this.state=i/this.options.duration;var j=this.options.specialEasing&&this.options.specialEasing[this.prop],k=this.options.easing||(d.easing.swing?"swing":"linear");this.pos=d.easing[j||k](this.state,i,0,1,this.options.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update();return!0}},d.extend(d.fx,{tick:function(){var a=d.timers;for(var b=0;b
";d.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),e=b.firstChild,f=e.firstChild,h=e.nextSibling.firstChild.firstChild,this.doesNotAddBorder=f.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,f.style.position="fixed",f.style.top="20px",this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15,f.style.position=f.style.top="",e.style.overflow="hidden",e.style.position="relative",this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),d.offset.initialize=d.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;d.offset.initialize(),d.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(d.css(a,"marginTop"))||0,c+=parseFloat(d.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var e=d.css(a,"position");e==="static"&&(a.style.position="relative");var f=d(a),g=f.offset(),h=d.css(a,"top"),i=d.css(a,"left"),j=(e==="absolute"||e==="fixed")&&d.inArray("auto",[h,i])>-1,k={},l={},m,n;j&&(l=f.position()),m=j?l.top:parseInt(h,10)||0,n=j?l.left:parseInt(i,10)||0,d.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):f.css(k)}},d.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),e=ch.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(d.css(a,"marginTop"))||0,c.left-=parseFloat(d.css(a,"marginLeft"))||0,e.top+=parseFloat(d.css(b[0],"borderTopWidth"))||0,e.left+=parseFloat(d.css(b[0],"borderLeftWidth"))||0;return{top:c.top-e.top,left:c.left-e.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&(!ch.test(a.nodeName)&&d.css(a,"position")==="static"))a=a.offsetParent;return a})}}),d.each(["Left","Top"],function(a,c){var e="scroll"+c;d.fn[e]=function(c){var f=this[0],g;if(!f)return null;if(c!==b)return this.each(function(){g=ci(this),g?g.scrollTo(a?d(g).scrollLeft():c,a?c:d(g).scrollTop()):this[e]=c});g=ci(f);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:d.support.boxModel&&g.document.documentElement[e]||g.document.body[e]:f[e]}}),d.each(["Height","Width"],function(a,c){var e=c.toLowerCase();d.fn["inner"+c]=function(){return this[0]?parseFloat(d.css(this[0],e,"padding")):null},d.fn["outer"+c]=function(a){return this[0]?parseFloat(d.css(this[0],e,a?"margin":"border")):null},d.fn[e]=function(a){var f=this[0];if(!f)return a==null?null:this;if(d.isFunction(a))return this.each(function(b){var c=d(this);c[e](a.call(this,b,c[e]()))});if(d.isWindow(f)){var g=f.document.documentElement["client"+c];return f.document.compatMode==="CSS1Compat"&&g||f.document.body["client"+c]||g}if(f.nodeType===9)return Math.max(f.documentElement["client"+c],f.body["scroll"+c],f.documentElement["scroll"+c],f.body["offset"+c],f.documentElement["offset"+c]);if(a===b){var h=d.css(f,e),i=parseFloat(h);return d.isNaN(i)?h:i}return this.css(e,typeof a==="string"?a:a+"px")}}),a.jQuery=a.$=d})(window); -------------------------------------------------------------------------------- /doc/modules_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List of Modules 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 |
19 |

20 | 21 | bitpay v0.2.4 22 | 23 |

24 | 25 |

26 | 27 | Overview 28 |

29 | 30 | 35 | 36 | 37 | 38 | 132 | 133 |
134 |
135 | 136 | 137 | -------------------------------------------------------------------------------- /doc/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Overview 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 |
23 | 24 | 25 |

bitpay v0.2.4

26 | 27 | 36 | 37 | 38 |

Modules summary

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 |
BitPay
BitPay.KeyUtils
BitPay.WebClient

Convenience methods for the BitPay REST API

52 |
57 | 58 | 59 | 60 |

Exceptions summary

61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
BitPay.ArgumentError
BitPay.BitPayError
72 | 73 | 74 | 75 |
76 | 77 | 78 | -------------------------------------------------------------------------------- /doc/protocols_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | List of Protocols 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 |
19 |

20 | 21 | bitpay v0.2.4 22 | 23 |

24 | 25 |

26 | 27 | Overview 28 |

29 | 30 | 35 | 36 | 37 | 38 |
    39 | 40 |
41 | 42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/bitpay.ex: -------------------------------------------------------------------------------- 1 | defmodule BitPay do 2 | end 3 | -------------------------------------------------------------------------------- /lib/bitpay/errors.ex: -------------------------------------------------------------------------------- 1 | defmodule BitPay.ArgumentError do 2 | defexception message: "incorrect argument" 3 | end 4 | defmodule BitPay.BitPayError do 5 | defexception message: "BitPay Error" 6 | end 7 | -------------------------------------------------------------------------------- /lib/bitpay/key-utils.ex: -------------------------------------------------------------------------------- 1 | defmodule BitPay.KeyUtils do 2 | require Integer 3 | 4 | @doc """ 5 | generates a pem file 6 | """ 7 | def generate_pem do 8 | keys |> 9 | entity_from_keys |> 10 | der_encode_entity |> 11 | pem_encode_der 12 | end 13 | 14 | @doc """ 15 | creates a base58 encoded SIN from a pem file 16 | """ 17 | def get_sin_from_pem pem do 18 | compressed_public_key(pem) |> 19 | set_version_type |> 20 | (&(&1 <> write_checksum &1)).() |> 21 | encode_base58 22 | end 23 | 24 | @doc """ 25 | retrieves the compressed public key from a pem file 26 | """ 27 | def compressed_public_key pem do 28 | entity_from_pem(pem) |> 29 | extract_coordinates |> 30 | compress_key 31 | end 32 | 33 | @doc """ 34 | retrieves the private key as a base16 string from the pem file 35 | """ 36 | def private_key pem do 37 | entity_from_pem(pem) |> 38 | elem(2) |> 39 | :binary.list_to_bin |> 40 | Base.encode16 41 | end 42 | 43 | @doc """ 44 | signs the input with the key retrieved from the pem file 45 | """ 46 | def sign payload, pem do 47 | entity = :public_key.pem_decode(pem) |> 48 | List.first |> 49 | :public_key.pem_entry_decode 50 | :public_key.sign(payload, :sha256, entity) |> 51 | Base.encode16 52 | end 53 | 54 | defp keys, do: :crypto.generate_key(:ecdh, :secp256k1) 55 | 56 | defp entity_from_keys({public, private}) do 57 | {:ECPrivateKey, 58 | 1, 59 | :binary.bin_to_list(private), 60 | {:namedCurve, {1, 3, 132, 0, 10}}, 61 | {0, public}} 62 | end 63 | 64 | defp der_encode_entity(ec_entity), do: :public_key.der_encode(:ECPrivateKey, ec_entity) 65 | defp pem_encode_der(der_encoded), do: :public_key.pem_encode([{:ECPrivateKey, der_encoded, :not_encrypted}]) 66 | 67 | defp entity_from_pem pem do 68 | [{_, dncoded, _}] = :public_key.pem_decode(pem) 69 | :public_key.der_decode(:ECPrivateKey, dncoded) 70 | end 71 | 72 | defp extract_coordinates(ec_entity) do 73 | elem(ec_entity, 4) |> 74 | elem(1) |> 75 | Base.encode16 |> 76 | split_x_y 77 | end 78 | 79 | defp split_x_y(uncompressed), do: {String.slice(uncompressed, 2..65), String.slice(uncompressed, 66..-1)} 80 | 81 | defp compress_key({x, y}) do 82 | convert_y_to_int({x, y}) |> 83 | return_compressed_key 84 | end 85 | defp convert_y_to_int({x, y}), do: ({x, String.to_integer(y, 16)}) 86 | defp return_compressed_key({x, y}) when Integer.is_even(y), do: "02#{x}" 87 | defp return_compressed_key({x, y}) when Integer.is_odd(y), do: "03#{x}" 88 | 89 | defp set_version_type public_key do 90 | digest(public_key, :sha256) |> 91 | digest(:ripemd160) |> 92 | (&("0F02" <> &1)).() 93 | end 94 | 95 | defp write_checksum version do 96 | digest(version, :sha256) |> 97 | digest(:sha256) |> 98 | String.slice(0..7) 99 | end 100 | 101 | defp digest hex_val, encoding do 102 | Base.decode16(hex_val) |> 103 | elem(1) |> 104 | (&(:crypto.hash(encoding, &1))).() |> 105 | Base.encode16 106 | end 107 | 108 | defp encode_base58 string do 109 | String.to_integer(string, 16) |> 110 | (&(encode("", &1, digit_list))).() 111 | end 112 | 113 | defp encode(output_string, number, _list) when number == 0, do: output_string 114 | defp encode(output_string, number, list) do 115 | elem(list, rem(number,58)) <> output_string |> 116 | encode(div(number, 58), list) 117 | end 118 | 119 | defp digit_list do 120 | "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" |> 121 | String.split("") |> 122 | List.to_tuple 123 | end 124 | end 125 | -------------------------------------------------------------------------------- /lib/bitpay/webclient.ex: -------------------------------------------------------------------------------- 1 | defmodule BitPay.WebClient do 2 | @moduledoc """ 3 | Convenience methods for the BitPay REST API. 4 | """ 5 | require IEx 6 | alias BitPay.KeyUtils, as: KeyUtils 7 | @doc """ 8 | The module struct contains two fields: 9 | 10 | - uri: the api uri, which defaults to https://bitpay.com 11 | - pem: a pem file containing the public and private keys, which can be generated from the BitPay.KeyUtils module. 12 | """ 13 | defstruct uri: "https://bitpay.com", pem: KeyUtils.generate_pem 14 | 15 | @doc """ 16 | creates a token on the server corresponding to the WebClients public and private keys 17 | 18 | Input: 19 | 20 | * a pairing code from the server 21 | * a WebClient 22 | 23 | Response: a key/value pair such as `%{pos: 92hgkeit92392gjgj}` 24 | """ 25 | def pair_pos_client code, client do 26 | pair_pos_client code, (code =~ ~r/^\p{Xan}{7}$/), client 27 | end 28 | 29 | @doc """ 30 | initiates a 'client side' pairing. 31 | 32 | Input: a WebClient 33 | 34 | Response: `{:ok, }` 35 | 36 | The pairingCode can then be used at /dashboard/merchant/api-tokens to authenticate the token 37 | """ 38 | def get_pairing_code client do 39 | post("tokens", %{with_facade: :public}, client) 40 | |> process_data 41 | |> extract_pairing_code 42 | end 43 | 44 | def get_pairing_code client, facade do 45 | post("tokens", %{with_facade: :public, facade: facade}, client) 46 | |> process_data 47 | |> extract_pairing_code 48 | end 49 | 50 | defp extract_pairing_code({:error, message}), do: {:error, message} 51 | defp extract_pairing_code({:ok, data}), do: data |> List.first |> Access.get(:pairingCode) |> (&({:ok, &1})).() 52 | 53 | @doc """ 54 | Sends a post request to the server that creates a new invoice. 55 | 56 | Input: 57 | 58 | * a params map that must contain a price and a currency 59 | * a WebClient struct. The web client struct must be paired with BitPay. 60 | 61 | Response: A map corresponding to the data section of the JSON response from the server. 62 | """ 63 | def create_invoice params, webclient do 64 | validate_price(params.price, params.currency) 65 | |> validate_currency(params.currency) 66 | |> post("invoices", params, webclient) 67 | |> process_data 68 | end 69 | 70 | @doc """ 71 | Retrieves an invoice from the BitPay server. 72 | 73 | Input: 74 | 75 | * an invoice id 76 | * a WebClient 77 | 78 | Response: 79 | a map corresponding to the data section of the JSON response from the server. 80 | """ 81 | def get_invoice(id, webclient) do 82 | "#{webclient.uri}/invoices/#{id}" 83 | |> HTTPotion.get 84 | |> parse_response 85 | |> process_data 86 | end 87 | 88 | @doc """ 89 | Generic Get method to the WebClient endpoint + path 90 | Input: 91 | * the path (string) 92 | * params for the request (as map) 93 | * WebClient struct 94 | 95 | Response: 96 | a map containing the response code, successe status as true or false, and the body of the http response 97 | """ 98 | def get path, webclient do 99 | uri = "#{webclient.uri}/#{path}" 100 | headers = signed_headers uri, webclient.pem 101 | headers = Enum.concat(["content-type": "application/json", "accept": "application/json", "X-accept-version": "2.0.0"], headers) 102 | HTTPotion.get( uri, headers, []) |> 103 | parse_response 104 | end 105 | 106 | @doc """ 107 | Generic post method to the WebClient endpoint + path 108 | Input: 109 | * the path (string) 110 | * params for the request (as map) 111 | * WebClient struct 112 | 113 | Response: 114 | a map containing the response code, successe status as true or false, and the body of the http response 115 | """ 116 | def post({:error, message}, _, _, _), do: {:error, message} 117 | def post({:ok, _}, path, params, webclient), do: post(path, params, webclient) 118 | def post path, params, webclient do 119 | check_tokens({:ok, "first in pipe"}, params, webclient) 120 | |> build_post(path, params, webclient) 121 | |> post_to_server 122 | end 123 | 124 | defp build_post({:ok, %{token: token}}, path, params, webclient) do 125 | params = Map.drop(params, [:with_facade]) |> Map.put(:token, token) 126 | build_post({:ok, "added token to params"}, path, params, webclient) 127 | end 128 | defp build_post({:ok, %{with_facade: :public}}, path, params, webclient) do 129 | params = Map.drop(params, [:with_facade]) 130 | uri = "#{webclient.uri}/#{path}" 131 | body = params |> Map.put(:id, KeyUtils.get_sin_from_pem(webclient.pem)) |> JSX.encode! 132 | headers = [] 133 | {:ok, %{uri: uri, body: body, headers: headers}} 134 | end 135 | defp build_post({:ok, _}, path, params, webclient) do 136 | uri = "#{webclient.uri}/#{path}" 137 | body = params |> Map.put(:id, KeyUtils.get_sin_from_pem(webclient.pem)) |> JSX.encode! 138 | headers = signed_headers uri <> body, webclient.pem 139 | {:ok, %{uri: uri, body: body, headers: headers}} 140 | end 141 | 142 | defp pair_pos_client(_code, false, _client), do: {:error, "pairing code is not legal"} 143 | defp pair_pos_client code, true, client do 144 | post("tokens", %{with_facade: :public, pairingCode: code}, client) 145 | |> process_data 146 | |> extract_facade 147 | end 148 | 149 | defp check_tokens({:error, message}, _, _), do: {:error, message} 150 | defp check_tokens({:ok, _}, %{token: _token}, _webclient), do: {:ok, "token passed in"} 151 | defp check_tokens({:ok, _}, %{with_facade: :public}, _webclient), do: {:ok, %{with_facade: :public}} 152 | defp check_tokens({:ok, _}, %{with_facade: facade}, webclient) do 153 | get_tokens_from_server(webclient) |> 154 | extract_token(facade) 155 | end 156 | defp check_tokens({:ok, _}, _params, webclient) do 157 | get_tokens_from_server(webclient) |> 158 | extract_token 159 | end 160 | 161 | defp get_tokens_from_server(webclient) do 162 | response = get("tokens", webclient) 163 | process_data(response.body, response.status, response.success) 164 | end 165 | 166 | defp extract_token({:error, message}), do: {:error, message} 167 | defp extract_token({:ok, data}) do 168 | Enum.map(data, fn(item) -> item[:pos] || item[:merchant] end) 169 | |> filter_token 170 | end 171 | defp extract_token({:ok, data}, facade) do 172 | Enum.map(data, fn(item) -> item[facade] end) 173 | |> filter_token 174 | end 175 | 176 | defp filter_token(tokens) do 177 | Enum.filter(tokens, fn(i)->i end) 178 | |> select_token 179 | end 180 | 181 | defp extract_facade({:error, message}), do: {:error, message} 182 | defp extract_facade({:ok, data}) do 183 | data = data |> List.first 184 | Dict.put(%{}, data.facade |> String.to_atom, data.token) 185 | end 186 | 187 | defp select_token([]), do: {:error, "no merchant or pos tokens on server"} 188 | defp select_token(tokens), do: {:ok, %{token: Enum.at(tokens, 0)}} 189 | 190 | defp process_data({:error, message}), do: {:error, message} 191 | defp process_data(%{body: body, status: status, success: success}), do: process_data(body, status, success) 192 | defp process_data(body, _status, true), do: {:ok, body.data} 193 | defp process_data(body, status, false), do: process_response(body, status, false) 194 | 195 | defp process_response body, status, false do 196 | message = body.error 197 | {:error, "#{status}: #{message}"} 198 | end 199 | 200 | defp post_to_server({:error, message}), do: {:error, message} 201 | defp post_to_server({:ok, %{uri: uri, body: body, headers: headers}}), do: post_to_server(uri, body, headers) 202 | defp post_to_server uri, body, headers do 203 | headers = Enum.concat(["content-type": "application/json", "accept": "application/json", "X-accept-version": "2.0.0"], headers) 204 | HTTPotion.post(uri, body, headers) |> 205 | parse_response 206 | end 207 | 208 | defp signed_headers message, pem do 209 | x_identity = KeyUtils.compressed_public_key pem 210 | x_signature = KeyUtils.sign(message, pem) 211 | [ "x-signature": x_signature, "x-identity": x_identity ] 212 | end 213 | 214 | defp parse_response response do 215 | success = HTTPotion.Response.success? response 216 | body = JSX.decode(response.body, [{:labels, :atom}]) |> elem(1) 217 | status = response.status_code 218 | %{status: status, body: body, success: success} 219 | end 220 | 221 | defp validate_price(price, _currency) when is_integer(price), do: {:ok, "price is valid"} 222 | defp validate_price(price, _currency) when is_float(price), do: {:ok, "price is valid"} 223 | defp validate_price(price, currency) when is_list(price), do: validate_price(List.to_string(price), currency) 224 | defp validate_price(price, "BTC") when is_binary(price), do: invoice_args_errors(price =~ ~r/^\d+(\.\d{1,8})?$/, true) 225 | defp validate_price(price, _currency) when is_binary(price), do: invoice_args_errors(price =~ ~r/^\d+(\.\d{1,2})?$/, true) 226 | 227 | defp validate_currency({:ok, message}, currency) when is_list(currency), do: validate_currency({:ok, message}, List.to_string(currency)) 228 | defp validate_currency({:ok, _}, currency) when is_binary(currency), do: invoice_args_errors(true, currency =~ ~r/^\p{Lu}{3}$/) 229 | defp validate_currency({:error, message}, _), do: {:error, message} 230 | 231 | defp invoice_args_errors(true, true), do: {:ok, "no invoice argument error"} 232 | defp invoice_args_errors(false, _), do: {:error, "Illegal Argument: Price must be formatted as a float"} 233 | defp invoice_args_errors(_, false), do: {:error, "Illegal Argument: Currency is invalid."} 234 | end 235 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Client.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :bitpay, 6 | version: "0.2.5", 7 | elixir: "~> 1.0", 8 | description: description, 9 | package: package, 10 | deps: deps, 11 | test_coverage: [tool: ExCoveralls]] 12 | end 13 | 14 | # Configuration for the OTP application 15 | # 16 | # Type `mix help compile.app` for more information 17 | def application do 18 | [applications: [:logger, :httpotion, :exjsx, :uuid]] 19 | end 20 | 21 | # Dependencies can be Hex packages: 22 | # 23 | # {:mydep, "~> 0.3.0"} 24 | # 25 | # Or git/path repositories: 26 | # 27 | # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} 28 | # 29 | # Type `mix help deps` for more examples and options 30 | defp description do 31 | """ 32 | Library to allow elixir apps to easily use the BitPay REST API to authenticate, generate invoices, and retrieve invoices. 33 | 34 | Includes Utilities for using Erlangs library for Elliptic Curve Keys. 35 | """ 36 | end 37 | 38 | defp package do 39 | [# These are the default files included in the package 40 | files: ["lib", "mix.exs", "README*", "readme*", "LICENSE*", "license*"], 41 | contributors: ["Paul Daigle"], 42 | licenses: ["MIT"], 43 | links: %{"GitHub" => "https://github.com/bitpay/elixir-client"}] 44 | end 45 | 46 | defp deps do 47 | [{ :mock, "~> 0.1.0", only: [:dev, :test] }, 48 | { :ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.1.0" }, 49 | { :httpotion, "~> 1.0.0" }, 50 | { :exjsx, "~> 3.1.0" }, 51 | { :uuid, "~> 0.1.5" }, 52 | { :earmark, "~> 0.1", only: :dev }, 53 | { :ex_doc, "~> 0.7", only: :dev}, 54 | { :excoveralls, "~> 0.3", only: [:dev, :test]}] 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{"earmark": {:hex, :earmark, "0.1.13"}, 2 | "ex_doc": {:hex, :ex_doc, "0.7.1"}, 3 | "excoveralls": {:hex, :excoveralls, "0.3.10"}, 4 | "exjsx": {:hex, :exjsx, "3.1.0"}, 5 | "hackney": {:hex, :hackney, "0.14.3"}, 6 | "hound": {:hex, :hound, "0.6.0"}, 7 | "httpoison": {:hex, :httpoison, "0.5.0"}, 8 | "httpotion": {:hex, :httpotion, "1.0.0"}, 9 | "ibrowse": {:git, "git://github.com/cmullaparthi/ibrowse.git", "7871e2ebe8811efb64e1917e2de455fa87e8dfe3", [tag: "v4.1.0"]}, 10 | "idna": {:hex, :idna, "1.0.1"}, 11 | "jazz": {:hex, :jazz, "0.2.1"}, 12 | "jsx": {:hex, :jsx, "2.4.0"}, 13 | "meck": {:hex, :meck, "0.8.2"}, 14 | "mock": {:hex, :mock, "0.1.0"}, 15 | "poison": {:hex, :poison, "1.3.0"}, 16 | "uuid": {:hex, :uuid, "0.1.5"}, 17 | "webdriver": {:git, "git://github.com/atlantaelixir/elixir-webdriver.git", "4c09661914b6810bff257b66fa7fc3512b101442", [tag: "v0.7.2"]}} 18 | -------------------------------------------------------------------------------- /test/features/pairing_test.exs: -------------------------------------------------------------------------------- 1 | defmodule PairingTest do 2 | use ExUnit.Case, async: false 3 | alias BitPay.WebClient, as: WebClient 4 | @pem System.get_env["BITPAYPEM"] |> String.replace("\\n", "\n") 5 | @api System.get_env["BITPAYAPI"] 6 | 7 | test 'pairs with the server' do 8 | :timer.sleep(5000) 9 | if(is_nil(System.get_env["BITPAYAPI"])) do 10 | raise ArgumentError, message: "Please set the system variables" 11 | end 12 | client = %WebClient{pem: @pem, uri: @api} 13 | response = BitPay.WebClient.post("tokens", %{facade: "pos", with_facade: :merchant}, client).body.data |> List.first |> Access.get(:pairingCode) |> WebClient.pair_pos_client(client) 14 | assert response.pos =~ ~r/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{20,44}$/ 15 | end 16 | 17 | test 'initiates a client side pairing' do 18 | :timer.sleep(5000) 19 | if(is_nil(System.get_env["BITPAYAPI"])) do 20 | raise ArgumentError, message: "Please set the system variables" 21 | end 22 | client = %WebClient{uri: @api} 23 | {:ok, pairingCode} = BitPay.WebClient.get_pairing_code(client) 24 | assert String.length(pairingCode) == 7 25 | end 26 | 27 | test 'creates an invoice' do 28 | if(is_nil(System.get_env["BITPAYAPI"])) do 29 | raise ArgumentError, message: "Please set the system variables" 30 | end 31 | client = %WebClient{pem: @pem, uri: @api} 32 | params = %{ price: 10, currency: "USD" } 33 | {:ok, invoice} = WebClient.create_invoice(params, client) 34 | assert invoice.status == "new" 35 | end 36 | 37 | test 'retrieves an invoice' do 38 | invoice_id = "8qnKuf41s1791339gmwB3S" 39 | client = %WebClient{uri: "https://test.bitpay.com"} 40 | {:ok, invoice} = WebClient.get_invoice(invoice_id, client) 41 | assert invoice.id == invoice_id 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /test/key_utils_test.exs: -------------------------------------------------------------------------------- 1 | defmodule KeyUtilsTest do 2 | use ExUnit.Case 3 | alias BitPay.KeyUtils, as: KeyUtils 4 | 5 | @sin "TeyN4LPrXiG5t2yuSamKqP3ynVk3F52iHrX" 6 | @pem """ 7 | -----BEGIN EC PRIVATE KEY----- 8 | MHQCAQEEICg7E4NN53YkaWuAwpoqjfAofjzKI7Jq1f532dX+0O6QoAcGBSuBBAAK 9 | oUQDQgAEjZcNa6Kdz6GQwXcUD9iJ+t1tJZCx7hpqBuJV2/IrQBfue8jh8H7Q/4vX 10 | fAArmNMaGotTpjdnymWlMfszzXJhlw== 11 | -----END EC PRIVATE KEY----- 12 | 13 | """ 14 | 15 | @private_key "283B13834DE77624696B80C29A2A8DF0287E3CCA23B26AD5FE77D9D5FED0EE90" 16 | 17 | test 'generate pem file generates a valid ec pem file' do 18 | pem = KeyUtils.generate_pem() 19 | assert Regex.match?(~r/BEGIN EC PRIVATE KEY.*\n.*\n.*\n.*\n.*END EC PRIVATE KEY/, pem) 20 | end 21 | 22 | test 'get_sin_from_pem' do 23 | sin = KeyUtils.get_sin_from_pem @pem 24 | assert sin == @sin 25 | end 26 | 27 | test 'get_private_key_from_pem' do 28 | assert KeyUtils.private_key(@pem) == @private_key 29 | end 30 | 31 | test 'sign' do 32 | signature_decoded = KeyUtils.sign("this land is your land", @pem) |> Base.decode16 |> elem(1) 33 | public_key = :public_key.pem_decode(@pem) |> List.first |> :public_key.pem_entry_decode |> elem(4) |> elem(1) 34 | verify = :crypto.verify(:ecdsa, :sha256, "this land is your land", signature_decoded, [public_key, :secp256k1]) 35 | assert verify 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/set_constants.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export RCROOTADDRESS=$1 4 | echo $RCROOTADDRESS 5 | export RCTESTUSER=$2 6 | echo $RCTESTUSER 7 | export RCTESTPASSWORD=$3 8 | echo $RCTESTPASSWORD 9 | 10 | -------------------------------------------------------------------------------- /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | 3 | #def an_illegal_claim_code 4 | # legal_map = [*'A'..'Z'] + [*'a'..'z'] + [*0..9] 5 | # first_length = rand(6) 6 | # short_code = (0..first_length).map{legal_map.sample}.join 7 | # second_length = [*8..25].sample 8 | # long_code = [*8..25].sample.times.inject([]){|arr| arr << legal_map.sample}.join 9 | # [nil, short_code, long_code].sample 10 | #end 11 | -------------------------------------------------------------------------------- /test/webclient_test.exs: -------------------------------------------------------------------------------- 1 | defmodule WebClientTest do 2 | use ExUnit.Case, async: false 3 | alias BitPay.WebClient, as: WebClient 4 | import Mock 5 | 6 | test 'post method does not try to get token if public facade input' do 7 | client = %WebClient{} 8 | with_mock HTTPotion, [post: fn("https://bitpay.com/testpoint", _body, _headers) -> %HTTPotion.Response{status_code: 200, body: "{\"data\":[{\"policies\":[{\"policy\":\"id\",\"method\":\"unclaimed\",\"params\":[]}],\"resource\":\"4e2rQDFK6Y1X4eU5ugw8AYy9FFih6jRicv6dxeccgS8r\",\"token\":\"BHMA5LMxUdEvePuAaEPmuW5tPYbGpw65jirDHzbXLfkt\",\"facade\":\"pos\",\"dateCreated\":1440003119142,\"pairingExpiration\":1440089519142,\"pairingCode\":\"8GSQvjb\"}]}" } end] do 9 | response = WebClient.post("testpoint", %{with_facade: :public}, client) 10 | assert response.body.data |> List.first |> Access.get(:token) == "BHMA5LMxUdEvePuAaEPmuW5tPYbGpw65jirDHzbXLfkt" 11 | end 12 | end 13 | 14 | test 'get_pairing_code makes a public call to the tokens endpoint' do 15 | client = %WebClient{} 16 | with_mock HTTPotion, [post: fn("https://bitpay.com/tokens", _body, _headers) -> %HTTPotion.Response{status_code: 200, body: "{\"data\":[{\"policies\":[{\"policy\":\"id\",\"method\":\"unclaimed\",\"params\":[]}],\"resource\":\"4e2rQDFK6Y1X4eU5ugw8AYy9FFih6jRicv6dxeccgS8r\",\"token\":\"BHMA5LMxUdEvePuAaEPmuW5tPYbGpw65jirDHzbXLfkt\",\"facade\":\"pos\",\"dateCreated\":1440003119142,\"pairingExpiration\":1440089519142,\"pairingCode\":\"8GSQvjb\"}]}" } end] do 17 | {:ok, pairingCode} = WebClient.get_pairing_code(client) 18 | assert pairingCode == "8GSQvjb" 19 | end 20 | end 21 | 22 | test 'get_pairing_code accepts "merchant" or "pos" arguments' do 23 | client = %WebClient{} 24 | with_mock HTTPotion, [post: fn("https://bitpay.com/tokens", _body, _headers) -> %HTTPotion.Response{status_code: 200, body: "{\"data\":[{\"policies\":[{\"policy\":\"id\",\"method\":\"unclaimed\",\"params\":[]}],\"resource\":\"4e2rQDFK6Y1X4eU5ugw8AYy9FFih6jRicv6dxeccgS8r\",\"token\":\"BHMA5LMxUdEvePuAaEPmuW5tPYbGpw65jirDHzbXLfkt\",\"facade\":\"pos\",\"dateCreated\":1440003119142,\"pairingExpiration\":1440089519142,\"pairingCode\":\"8GSQvjb\"}]}" } end] do 25 | {:ok, pairingCode} = WebClient.get_pairing_code(client, :merchant) 26 | assert pairingCode == "8GSQvjb" 27 | end 28 | end 29 | test 'post method gets specified token if input' do 30 | client = %WebClient{} 31 | with_mock HTTPotion, [get: fn("https://bitpay.com/tokens", _body, _headers) -> %HTTPotion.Response{status_code: 228, body: "{\"data\":[{\"testfacade\":\"EBtD6Dae9VXvK8ky7zYkCMfwZCzcsGsDiEfqmZB3Et9K\"},{\"pos/invoice\":\"ED2H47jWZbQKnPTwRLeZcfQ7eN9NyiRFVnRexmoWLScu\"}]}"} end, post: fn("https://bitpay.com/testpoint", _body, _headers) -> %HTTPotion.Response{status_code: 200, body: "{\"data\":[{\"policies\":[{\"policy\":\"id\",\"method\":\"unclaimed\",\"params\":[]}],\"resource\":\"4e2rQDFK6Y1X4eU5ugw8AYy9FFih6jRicv6dxeccgS8r\",\"token\":\"BHMA5LMxUdEvePuAaEPmuW5tPYbGpw65jirDHzbXLfkt\",\"facade\":\"pos\",\"dateCreated\":1440003119142,\"pairingExpiration\":1440089519142,\"pairingCode\":\"8GSQvjb\"}]}" } end] do 32 | response = WebClient.post("testpoint", %{with_facade: :testfacade}, client) 33 | assert response.body.data |> List.first |> Access.get(:token) == "BHMA5LMxUdEvePuAaEPmuW5tPYbGpw65jirDHzbXLfkt" 34 | end 35 | 36 | end 37 | 38 | test 'get method' do 39 | with_mock HTTPotion, [get: fn("https://bitpay.com/blocks", _body, _headers) -> %HTTPotion.Response{status_code: 228, body: "{\"data\":[{\"pos\":\"EBtD6Dae9VXvK8ky7zYkCMfwZCzcsGsDiEfqmZB3Et9K\"},{\"pos/invoice\":\"ED2H47jWZbQKnPTwRLeZcfQ7eN9NyiRFVnRexmoWLScu\"}]}"} end] do 40 | assert WebClient.get("blocks", %WebClient{}).status == 228 41 | end 42 | end 43 | 44 | test 'pairing short circuits with invalid code' do 45 | illegal_pairing_codes() |> Enum.each fn(item) -> 46 | assert WebClient.pair_pos_client(item, %WebClient{}) == {:error, "pairing code is not legal"} 47 | end 48 | end 49 | 50 | test 'pairing handles errors gracefully' do 51 | with_mock HTTPotion, [post: fn("https://bitpay.com/tokens", _body, _headers) -> 52 | %HTTPotion.Response{status_code: 403, 53 | body: "{\n \"error\": \"this is a 403 error\"\n}"} end] do 54 | assert {:error, "403: this is a 403 error"} == WebClient.pair_pos_client "aBD3fhg", %WebClient{} 55 | end 56 | end 57 | 58 | test "create invoice fails gracefully with improper price" do 59 | params = %{price: "100,00", currency: "USD", token: "anything"} 60 | assert {:error, "Illegal Argument: Price must be formatted as a float"} == WebClient.create_invoice(params, %BitPay.WebClient{}) 61 | end 62 | 63 | test "create invoice retrieves tokens from server" do 64 | params = %{price: 100, currency: "USD"} 65 | with_mock HTTPotion, [get: fn("https://bitpay.com/tokens", _body, _headers) -> %HTTPotion.Response{status_code: 228, body: "{\"data\":[{\"pos\":\"EBtD6Dae9VXvK8ky7zYkCMfwZCzcsGsDiEfqmZB3Et9K\"},{\"pos/invoice\":\"ED2H47jWZbQKnPTwRLeZcfQ7eN9NyiRFVnRexmoWLScu\"}]}"} end, post: fn("https://bitpay.com/invoices", _body, _headers) -> %HTTPotion.Response{status_code: 200, body: "{\"facade\":\"pos/invoice\",\"data\":{\"url\":\"https://test.bitpay.com/invoice?id=A41p1sHqruaA38YaKC83L7\",\"status\":\"new\",\"btcPrice\":\"0.388736\",\"btcDue\":\"0.388736\",\"price\":100,\"currency\":\"USD\",\"exRates\":{\"USD\":257.24390946963365},\"invoiceTime\":1439829619654,\"expirationTime\":1439830519654,\"currentTime\":1439829619916,\"guid\":\"ebf5fe06-b738-4d51-bb9c-f5dcd6613124\",\"id\":\"A41p1sHqruaA38YaKC83L7\",\"btcPaid\":\"0.000000\",\"rate\":257.24,\"exceptionStatus\":false,\"paymentUrls\":{\"BIP21\":\"bitcoin:mtzuBK37L5CxsvPVfP1E711gk6h7VJQ3rJ?amount=0.388736\",\"BIP72\":\"bitcoin:mtzuBK37L5CxsvPVfP1E711gk6h7VJQ3rJ?amount=0.388736&r=https://test.bitpay.com/i/A41p1sHqruaA38YaKC83L7\",\"BIP72b\":\"bitcoin:?r=https://test.bitpay.com/i/A41p1sHqruaA38YaKC83L7\",\"BIP73\":\"https://test.bitpay.com/i/A41p1sHqruaA38YaKC83L7\"},\"token\":\"8CWU2YMJSozc2SKoYJygRkuqmyiuCAQSQrShMpzGT4f77BPABLt9EovsxkmVkUWvPE\"}}" } end] do 66 | {:ok, response} = WebClient.create_invoice(params, %WebClient{}) 67 | assert 1439829619916 == response.currentTime 68 | end 69 | end 70 | 71 | test "create invoice handles BTC" do 72 | params = %{price: "0.004", currency: "BTC", token: "anything"} 73 | with_mock HTTPotion, [post: fn("https://bitpay.com/invoices", _body, _headers) -> 74 | %HTTPotion.Response{status_code: 200, 75 | body: "{\"facade\":\"pos/invoice\",\"data\":{\"url\":\"https://test.bitpay.com/invoice?id=A41p1sHqruaA38YaKC83L7\",\"status\":\"new\",\"btcPrice\":\"0.388736\",\"btcDue\":\"0.388736\",\"price\":100,\"currency\":\"USD\",\"exRates\":{\"USD\":257.24390946963365},\"invoiceTime\":1439829619654,\"expirationTime\":1439830519654,\"currentTime\":1439829619916,\"guid\":\"ebf5fe06-b738-4d51-bb9c-f5dcd6613124\",\"id\":\"A41p1sHqruaA38YaKC83L7\",\"btcPaid\":\"0.000000\",\"rate\":257.24,\"exceptionStatus\":false,\"paymentUrls\":{\"BIP21\":\"bitcoin:mtzuBK37L5CxsvPVfP1E711gk6h7VJQ3rJ?amount=0.388736\",\"BIP72\":\"bitcoin:mtzuBK37L5CxsvPVfP1E711gk6h7VJQ3rJ?amount=0.388736&r=https://test.bitpay.com/i/A41p1sHqruaA38YaKC83L7\",\"BIP72b\":\"bitcoin:?r=https://test.bitpay.com/i/A41p1sHqruaA38YaKC83L7\",\"BIP73\":\"https://test.bitpay.com/i/A41p1sHqruaA38YaKC83L7\"},\"token\":\"8CWU2YMJSozc2SKoYJygRkuqmyiuCAQSQrShMpzGT4f77BPABLt9EovsxkmVkUWvPE\"}}" } end] do 76 | {:ok, response} = WebClient.create_invoice(params, %BitPay.WebClient{}) 77 | assert 1439829619916 == response.currentTime 78 | end 79 | end 80 | 81 | test "create invoice fails gracefully with improper currency" do 82 | params = %{price: 100.00, currency: "USDa", token: "anything"} 83 | assert {:error, "Illegal Argument: Currency is invalid."} == WebClient.create_invoice(params, %BitPay.WebClient{}) 84 | end 85 | 86 | defp illegal_pairing_codes do 87 | ["abcdefgh", "habcdefg", "abcd-fg"] 88 | end 89 | end 90 | --------------------------------------------------------------------------------