| blib/lib/WWW/Challonge.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % | 
| statement | 1 | 3 | 33.3 | 
| branch | n/a | ||
| condition | n/a | ||
| subroutine | 1 | 1 | 100.0 | 
| pod | n/a | ||
| total | 2 | 4 | 50.0 | 
| line | stmt | bran | cond | sub | pod | time | code | 
|---|---|---|---|---|---|---|---|
| 1 | package WWW::Challonge; | ||||||
| 2 | 1 | 1 | 13964 | use WWW::Challonge::Tournament; | |||
| 0 | |||||||
| 0 | |||||||
| 3 | use REST::Client; | ||||||
| 4 | use JSON qw/to_json from_json/; | ||||||
| 5 | |||||||
| 6 | use 5.006; | ||||||
| 7 | use strict; | ||||||
| 8 | use warnings; | ||||||
| 9 | |||||||
| 10 | =head1 NAME | ||||||
| 11 | |||||||
| 12 | WWW::Challonge - Perl wrapper for the Challonge API | ||||||
| 13 | |||||||
| 14 | =head1 VERSION | ||||||
| 15 | |||||||
| 16 | Version 0.10 | ||||||
| 17 | |||||||
| 18 | =cut | ||||||
| 19 | |||||||
| 20 | our $VERSION = '0.10'; | ||||||
| 21 | |||||||
| 22 | =head1 SYNOPSIS | ||||||
| 23 | |||||||
| 24 | Access the Challonge API within Perl. Contains all the functions within the API, | ||||||
| 25 | as documented L | ||||||
| 26 | |||||||
| 27 | use WWW::Challonge; | ||||||
| 28 | |||||||
| 29 | my $c = WWW::Challonge->new($api_key) | ||||||
| 30 | ... | ||||||
| 31 | |||||||
| 32 | =head1 SUBROUTINES/METHODS | ||||||
| 33 | |||||||
| 34 | =head2 new | ||||||
| 35 | |||||||
| 36 | Creates a new C | ||||||
| 37 | |||||||
| 38 | my $c = WWW::Challonge->new($api_key); | ||||||
| 39 | |||||||
| 40 | =cut | ||||||
| 41 | |||||||
| 42 | sub new | ||||||
| 43 | { | ||||||
| 44 | # Get the API key: | ||||||
| 45 | my $class = shift; | ||||||
| 46 | my $key = shift; | ||||||
| 47 | |||||||
| 48 | # Create a REST client to interface Challonge: | ||||||
| 49 | my $client = REST::Client->new(); | ||||||
| 50 | $client->setHost("https://api.challonge.com/v1"); | ||||||
| 51 | |||||||
| 52 | # Try to get some content and check the response code: | ||||||
| 53 | $client->GET("/tournaments.json?api_key=$key"); | ||||||
| 54 | |||||||
| 55 | # Check to see if the API key is valid: | ||||||
| 56 | if($client->responseCode() eq '401') | ||||||
| 57 | { | ||||||
| 58 | # If it isn't, warn the user and exit: | ||||||
| 59 | print STDERR "Error: Challonge API key is invalid.\n"; | ||||||
| 60 | return undef; | ||||||
| 61 | } | ||||||
| 62 | |||||||
| 63 | # Otherwise, keep the key and the client in an object and return: | ||||||
| 64 | my $c = { key => $key, client => $client }; | ||||||
| 65 | bless $c, $class; | ||||||
| 66 | } | ||||||
| 67 | |||||||
| 68 | =head2 index | ||||||
| 69 | |||||||
| 70 | Returns an arrayref of all C | ||||||
| 71 | user authenticated with in the 'new' request (the logged in user, so to speak). | ||||||
| 72 | Takes a number of optional arguments: | ||||||
| 73 | |||||||
| 74 | =over 4 | ||||||
| 75 | |||||||
| 76 | =item state | ||||||
| 77 | |||||||
| 78 | Get tournaments based on their progress: | ||||||
| 79 | |||||||
| 80 | =over 4 | ||||||
| 81 | |||||||
| 82 | =item all | ||||||
| 83 | |||||||
| 84 | Gets all tournaments regardless of state. | ||||||
| 85 | |||||||
| 86 | =item pending | ||||||
| 87 | |||||||
| 88 | Gets all tournaments that have yet to start. | ||||||
| 89 | |||||||
| 90 | =item in_progress | ||||||
| 91 | |||||||
| 92 | Gets all tournaments that have started but have not finished. | ||||||
| 93 | |||||||
| 94 | =item ended | ||||||
| 95 | |||||||
| 96 | Gets all tournaments that have finished. | ||||||
| 97 | |||||||
| 98 | =back | ||||||
| 99 | |||||||
| 100 | =item type | ||||||
| 101 | |||||||
| 102 | Gets all tournaments of the given type: | ||||||
| 103 | |||||||
| 104 | =over 4 | ||||||
| 105 | |||||||
| 106 | =item single_elimination | ||||||
| 107 | |||||||
| 108 | =item double_elimination | ||||||
| 109 | |||||||
| 110 | =item round_robin | ||||||
| 111 | |||||||
| 112 | =item swiss | ||||||
| 113 | |||||||
| 114 | =back | ||||||
| 115 | |||||||
| 116 | =item created_after | ||||||
| 117 | |||||||
| 118 | Gets all the tournaments created after the given date. Can be given as a string | ||||||
| 119 | (YYYY-MM-DD) or as a C | ||||||
| 120 | |||||||
| 121 | =item created_before | ||||||
| 122 | |||||||
| 123 | Gets all the tournaments created before the given date. Can be given as a string | ||||||
| 124 | (YYYY-MM-DD) or as a C | ||||||
| 125 | |||||||
| 126 | =item subdomain | ||||||
| 127 | |||||||
| 128 | Gets all tournaments created under the given subdomian. | ||||||
| 129 | |||||||
| 130 | =back | ||||||
| 131 | |||||||
| 132 | my $tournies = $c->index(); | ||||||
| 133 | my $tournies2 = $c->index({ | ||||||
| 134 | type => "double_elimination", | ||||||
| 135 | created_after => "2015-03-18", | ||||||
| 136 | }); | ||||||
| 137 | |||||||
| 138 | =cut | ||||||
| 139 | |||||||
| 140 | sub index | ||||||
| 141 | { | ||||||
| 142 | my $self = shift; | ||||||
| 143 | my $options = shift // {}; | ||||||
| 144 | |||||||
| 145 | # Get the key and the client: | ||||||
| 146 | my $key = $self->{key}; | ||||||
| 147 | my $client = $self->{client}; | ||||||
| 148 | |||||||
| 149 | # The intial request URL: | ||||||
| 150 | my $req = "/tournaments.json?api_key=$key"; | ||||||
| 151 | |||||||
| 152 | # Loop through the options (if any) and add them on: | ||||||
| 153 | for my $option(keys %{$options}) | ||||||
| 154 | { | ||||||
| 155 | # Validate the input: | ||||||
| 156 | if($option =~ /^state$/) | ||||||
| 157 | { | ||||||
| 158 | if($options->{$option} !~ /^all|pending|in_progress|ended$/) | ||||||
| 159 | { | ||||||
| 160 | print STDERR "Error: Argument '" . $options->{option} . | ||||||
| 161 | "' for option '$option' is invalid."; | ||||||
| 162 | } | ||||||
| 163 | } | ||||||
| 164 | elsif($option =~ /^type$/) | ||||||
| 165 | { | ||||||
| 166 | if($options->{$option} !~ /^(single|double)_elimination|round_robin|swiss$/) | ||||||
| 167 | { | ||||||
| 168 | print STDERR "Error: Argument '" . $options->{option} . | ||||||
| 169 | "' for option '$option' is invalid."; | ||||||
| 170 | } | ||||||
| 171 | } | ||||||
| 172 | elsif($option =~ /^created_(before|after)$/) | ||||||
| 173 | { | ||||||
| 174 | if($options->{$option} !~ /^\d{4}-\d{2}-\d{2}$/) | ||||||
| 175 | { | ||||||
| 176 | print STDERR "Error: Argument '" . $options->{option} . | ||||||
| 177 | "' for option '$option' is invalid."; | ||||||
| 178 | } | ||||||
| 179 | } | ||||||
| 180 | elsif($option =~ /^subdomain$/) | ||||||
| 181 | { | ||||||
| 182 | if($options->{$option} !~ /^[a-zA-Z0-9_]*$/) | ||||||
| 183 | { | ||||||
| 184 | print STDERR "Error: Argument '" . $options->{option} . | ||||||
| 185 | "' for option '$option' is invalid."; | ||||||
| 186 | } | ||||||
| 187 | } | ||||||
| 188 | else | ||||||
| 189 | { | ||||||
| 190 | print STDERR "Error: Option '$option' is invalid."; | ||||||
| 191 | return undef; | ||||||
| 192 | } | ||||||
| 193 | |||||||
| 194 | $req .= "&" . $option . "=" . $options->{$option}; | ||||||
| 195 | } | ||||||
| 196 | |||||||
| 197 | # Make the request: | ||||||
| 198 | $client->GET($req); | ||||||
| 199 | |||||||
| 200 | # Make a new tournament object for every tourney returned: | ||||||
| 201 | my @tournaments; | ||||||
| 202 | for my $tournament(@{from_json($client->responseContent())}) | ||||||
| 203 | { | ||||||
| 204 | push @tournaments, WWW::Challonge::Tournament->new($tournament, | ||||||
| 205 | $key, $client); | ||||||
| 206 | } | ||||||
| 207 | |||||||
| 208 | # Return the array of tournaments: | ||||||
| 209 | return \@tournaments; | ||||||
| 210 | } | ||||||
| 211 | |||||||
| 212 | =head2 show | ||||||
| 213 | |||||||
| 214 | Gets a single C | ||||||
| 215 | |||||||
| 216 | my $tourney = $c->show("sample_tournament_1"); | ||||||
| 217 | |||||||
| 218 | If the tournament has a subdomain (e.g. test.challonge.com/mytourney), simply | ||||||
| 219 | specify like so: | ||||||
| 220 | |||||||
| 221 | my $tourney = $c->show("test-mytourney") | ||||||
| 222 | |||||||
| 223 | =cut | ||||||
| 224 | |||||||
| 225 | sub show | ||||||
| 226 | { | ||||||
| 227 | my $self = shift; | ||||||
| 228 | my $url = shift; | ||||||
| 229 | |||||||
| 230 | # Get the key and REST client: | ||||||
| 231 | my $key = $self->{key}; | ||||||
| 232 | my $client = $self->{client}; | ||||||
| 233 | |||||||
| 234 | # Try to get the tournament: | ||||||
| 235 | $client->GET("/tournaments/$url.json?api_key=$key"); | ||||||
| 236 | |||||||
| 237 | # Check for any errors: | ||||||
| 238 | if($client->responseCode eq '404') | ||||||
| 239 | { | ||||||
| 240 | print STDERR "Error: Tournament '$url' not found.\n"; | ||||||
| 241 | return undef; | ||||||
| 242 | } | ||||||
| 243 | |||||||
| 244 | # Otherwise create a tourney with the object and return it: | ||||||
| 245 | my $tourney = WWW::Challonge::Tournament->new( | ||||||
| 246 | from_json($client->responseContent), $key, $client); | ||||||
| 247 | return $tourney; | ||||||
| 248 | } | ||||||
| 249 | |||||||
| 250 | =head2 create | ||||||
| 251 | |||||||
| 252 | Creates a new tournament, and returns it as a C | ||||||
| 253 | object. It takes an hashref of arguments. The name and URL are required, all | ||||||
| 254 | others are optional. | ||||||
| 255 | |||||||
| 256 | =over 4 | ||||||
| 257 | |||||||
| 258 | =item name | ||||||
| 259 | |||||||
| 260 | A string containing the name of the tournament. | ||||||
| 261 | |||||||
| 262 | =item tournament_type | ||||||
| 263 | |||||||
| 264 | A string containing one of the following, detailing the type of tournament. | ||||||
| 265 | |||||||
| 266 | =over 4 | ||||||
| 267 | |||||||
| 268 | =item single elimination (default) | ||||||
| 269 | |||||||
| 270 | =item double elimination | ||||||
| 271 | |||||||
| 272 | =item round robin | ||||||
| 273 | |||||||
| 274 | =item swiss | ||||||
| 275 | |||||||
| 276 | =back | ||||||
| 277 | |||||||
| 278 | =item url | ||||||
| 279 | |||||||
| 280 | The url of the tournament, containing only letters, numbers and underscores. | ||||||
| 281 | |||||||
| 282 | =item subdomain | ||||||
| 283 | |||||||
| 284 | The subdomain of the tournament (requires write access to the given subdomain). | ||||||
| 285 | |||||||
| 286 | =item description | ||||||
| 287 | |||||||
| 288 | The description of the tournament to be displayed above the bracket. | ||||||
| 289 | |||||||
| 290 | =item game_name | ||||||
| 291 | |||||||
| 292 | The name of the game or sport being played. | ||||||
| 293 | |||||||
| 294 | =item open_signup | ||||||
| 295 | |||||||
| 296 | True/false. Have Challonge host a sign-up page (otherwise, manually add | ||||||
| 297 | participants). | ||||||
| 298 | |||||||
| 299 | =item hold_third_place_match | ||||||
| 300 | |||||||
| 301 | True/false. Single elimination only. Hold a match for semifinals losers to | ||||||
| 302 | determine third place? Default is false. | ||||||
| 303 | |||||||
| 304 | =item pts_for_match_win | ||||||
| 305 | |||||||
| 306 | Decimal (to the nearest tenth). Number of points gained on winning a match. | ||||||
| 307 | Swiss only. Default is 1.0. | ||||||
| 308 | |||||||
| 309 | =item pts_for_match_tie | ||||||
| 310 | |||||||
| 311 | Decimal (to the nearest tenth). Number of points gained on drawing a match. | ||||||
| 312 | Swiss only. Default is 0.5. | ||||||
| 313 | |||||||
| 314 | =item pts_for_game_win | ||||||
| 315 | |||||||
| 316 | Decimal (to the nearest tenth). Number of points gained on winning a single | ||||||
| 317 | game within a match. Swiss only. Default is 0.0. | ||||||
| 318 | |||||||
| 319 | =item pts_for_game_tie | ||||||
| 320 | |||||||
| 321 | Decimal (to the nearest tenth). Number of points gained on drawing a single | ||||||
| 322 | game within a match. Swiss only. Default is 0.0. | ||||||
| 323 | |||||||
| 324 | =item pts_for_bye | ||||||
| 325 | |||||||
| 326 | Decimal (to the nearest tenth). Number of points gained on getting a bye. | ||||||
| 327 | Swiss only. Default is 1.0. | ||||||
| 328 | |||||||
| 329 | =item swiss_rounds | ||||||
| 330 | |||||||
| 331 | Integer. Number of swiss rounds to play. Swiss only. It is recommended that | ||||||
| 332 | the number of rounds is limited to no more than two thirds of the number of | ||||||
| 333 | players, otherwise an impossible pairing situation may occur and the | ||||||
| 334 | tournament may end prematurely. | ||||||
| 335 | |||||||
| 336 | =item ranked_by | ||||||
| 337 | |||||||
| 338 | How the tournament is ranked. Can be one of the following. | ||||||
| 339 | |||||||
| 340 | =over 4 | ||||||
| 341 | |||||||
| 342 | =item match wins | ||||||
| 343 | |||||||
| 344 | =item game wins | ||||||
| 345 | |||||||
| 346 | =item points scored | ||||||
| 347 | |||||||
| 348 | =item points difference | ||||||
| 349 | |||||||
| 350 | =item custom | ||||||
| 351 | |||||||
| 352 | =back | ||||||
| 353 | |||||||
| 354 | =item rr_pts_for_match_win | ||||||
| 355 | |||||||
| 356 | Decimal (to the nearest tenth). Number of points gained by winning a match. | ||||||
| 357 | Round Robin 'custom' only. Default is 1.0. | ||||||
| 358 | |||||||
| 359 | =item rr_pts_for_match_tie | ||||||
| 360 | |||||||
| 361 | Decimal (to the nearest tenth). Number of points gained by drawing a match. | ||||||
| 362 | Round Robin 'custom' only. Default is 0.5. | ||||||
| 363 | |||||||
| 364 | =item rr_pts_for_game_win | ||||||
| 365 | |||||||
| 366 | Decimal (to the nearest tenth). Number of points gained by winning a single | ||||||
| 367 | game within a match. Round Robin 'custom' only. Default is 0.0. | ||||||
| 368 | |||||||
| 369 | =item rr_pts_for_game_tie | ||||||
| 370 | |||||||
| 371 | Decimal (to the nearest tenth). Number of points gained by drawing a single | ||||||
| 372 | game within a match. Round Robin 'custom' only. Default is 0.0. | ||||||
| 373 | |||||||
| 374 | =item accept_attachments | ||||||
| 375 | |||||||
| 376 | True/false. Allow match attachment uploads. Default is false. | ||||||
| 377 | |||||||
| 378 | =item hide_forum | ||||||
| 379 | |||||||
| 380 | True/false. Hide the forum tab on your Challonge page. Default is false. | ||||||
| 381 | |||||||
| 382 | =item show_rounds | ||||||
| 383 | |||||||
| 384 | True/false. Label each round about the bracket. Single and double elimination | ||||||
| 385 | only. Default is false. | ||||||
| 386 | |||||||
| 387 | =item private | ||||||
| 388 | |||||||
| 389 | True/false. Hide this tournament from the public browsable index and your | ||||||
| 390 | profile. Default is false. | ||||||
| 391 | |||||||
| 392 | =item notify_users_when_matches_open | ||||||
| 393 | |||||||
| 394 | True/false. Send registered Challonge users an email when matches open up | ||||||
| 395 | for them. Default is false. | ||||||
| 396 | |||||||
| 397 | =item nofity_users_when_the_tournament_ends | ||||||
| 398 | |||||||
| 399 | True/false. Send registered Challonge users an email with the results when | ||||||
| 400 | the tournament ends. Default is false. | ||||||
| 401 | |||||||
| 402 | =item sequential_pairings | ||||||
| 403 | |||||||
| 404 | True/false. Instead of following traditional seeding rules, make the pairings | ||||||
| 405 | go straight down the list of participants. For example, the first match will | ||||||
| 406 | be the first seed versus the second. Default is false. | ||||||
| 407 | |||||||
| 408 | =item signup_cap | ||||||
| 409 | |||||||
| 410 | Integer. The maximum number of participants. Any additional participants will | ||||||
| 411 | go on a waiting list. | ||||||
| 412 | |||||||
| 413 | =item start_at | ||||||
| 414 | |||||||
| 415 | DateTime. The planned time to start the tournament. Timezone defaults to | ||||||
| 416 | Eastern (EST). | ||||||
| 417 | |||||||
| 418 | =item check_in_duration | ||||||
| 419 | |||||||
| 420 | Integer. The length of the check-in window in minutes. | ||||||
| 421 | |||||||
| 422 | =back | ||||||
| 423 | |||||||
| 424 | my $tournament = $c->create({ | ||||||
| 425 | name => "sample tournament", | ||||||
| 426 | url => "sample_tournament_1", | ||||||
| 427 | type => "double elimination" | ||||||
| 428 | }); | ||||||
| 429 | |||||||
| 430 | =cut | ||||||
| 431 | |||||||
| 432 | sub create | ||||||
| 433 | { | ||||||
| 434 | my $self = shift; | ||||||
| 435 | my $args = shift; | ||||||
| 436 | |||||||
| 437 | # Get the key and REST client: | ||||||
| 438 | my $key = $self->{key}; | ||||||
| 439 | my $client = $self->{client}; | ||||||
| 440 | |||||||
| 441 | # Fail if name and URL aren't given: | ||||||
| 442 | if((! defined $args->{name}) && (! defined $args->{url})) | ||||||
| 443 | { | ||||||
| 444 | print STDERR "Error: Name and URL are required to create a ", | ||||||
| 445 | "tournament.\n"; | ||||||
| 446 | return undef; | ||||||
| 447 | } | ||||||
| 448 | |||||||
| 449 | # Check the arguments and values are valid: | ||||||
| 450 | return undef unless(WWW::Challonge::Tournament::__args_are_valid($args)); | ||||||
| 451 | |||||||
| 452 | # Add in the API key and convert to a POST request: | ||||||
| 453 | my $params = { api_key => $key, tournament => $args }; | ||||||
| 454 | |||||||
| 455 | # Now we have all the arguments validated, send the POST request: | ||||||
| 456 | $client->POST("/tournaments.json", to_json($params), | ||||||
| 457 | { "Content-Type" => 'application/json' }); | ||||||
| 458 | |||||||
| 459 | # Check for any errors: | ||||||
| 460 | if($client->responseCode >= 300) | ||||||
| 461 | { | ||||||
| 462 | my $error = from_json($client->responseContent)->{errors}->[0]; | ||||||
| 463 | if($error =~ /taken/) | ||||||
| 464 | { | ||||||
| 465 | print STDERR "Error: URL '", $args->{url}, "' is already taken\n"; | ||||||
| 466 | } | ||||||
| 467 | return undef; | ||||||
| 468 | } | ||||||
| 469 | |||||||
| 470 | # Otherwise, make a tournament object and return it: | ||||||
| 471 | my $t = WWW::Challonge::Tournament->new( | ||||||
| 472 | from_json($client->responseContent), $key, $client); | ||||||
| 473 | return $t; | ||||||
| 474 | } | ||||||
| 475 | |||||||
| 476 | =head1 AUTHOR | ||||||
| 477 | |||||||
| 478 | Alex Kerr, C<< | ||||||
| 479 | |||||||
| 480 | =head1 BUGS | ||||||
| 481 | |||||||
| 482 | Please report any bugs or feature requests to C | ||||||
| 483 | the web interface at L | ||||||
| 484 | automatically be notified of progress on your bug as I make changes. | ||||||
| 485 | |||||||
| 486 | =head1 SUPPORT | ||||||
| 487 | |||||||
| 488 | You can find documentation for this module with the perldoc command. | ||||||
| 489 | |||||||
| 490 | perldoc WWW::Challonge | ||||||
| 491 | |||||||
| 492 | You can also look for information at: | ||||||
| 493 | |||||||
| 494 | =over 4 | ||||||
| 495 | |||||||
| 496 | =item * RT: CPAN's request tracker (report bugs here) | ||||||
| 497 | |||||||
| 498 | L | ||||||
| 499 | |||||||
| 500 | =item * AnnoCPAN: Annotated CPAN documentation | ||||||
| 501 | |||||||
| 502 | L | ||||||
| 503 | |||||||
| 504 | =item * CPAN Ratings | ||||||
| 505 | |||||||
| 506 | L | ||||||
| 507 | |||||||
| 508 | =item * Search CPAN | ||||||
| 509 | |||||||
| 510 | L | ||||||
| 511 | |||||||
| 512 | =back | ||||||
| 513 | |||||||
| 514 | =head1 SEE ALSO | ||||||
| 515 | |||||||
| 516 | =over 4 | ||||||
| 517 | |||||||
| 518 | =item L | ||||||
| 519 | |||||||
| 520 | =item L | ||||||
| 521 | |||||||
| 522 | =item L | ||||||
| 523 | |||||||
| 524 | =back | ||||||
| 525 | |||||||
| 526 | =head1 ACKNOWLEDGEMENTS | ||||||
| 527 | |||||||
| 528 | Everyone on the L | ||||||
| 529 | service. | ||||||
| 530 | |||||||
| 531 | =head1 LICENSE AND COPYRIGHT | ||||||
| 532 | |||||||
| 533 | Copyright 2015 Alex Kerr. | ||||||
| 534 | |||||||
| 535 | This program is free software; you can redistribute it and/or modify it | ||||||
| 536 | under the terms of the the Artistic License (2.0). You may obtain a | ||||||
| 537 | copy of the full license at: | ||||||
| 538 | |||||||
| 539 | L | ||||||
| 540 | |||||||
| 541 | Any use, modification, and distribution of the Standard or Modified | ||||||
| 542 | Versions is governed by this Artistic License. By using, modifying or | ||||||
| 543 | distributing the Package, you accept this license. Do not use, modify, | ||||||
| 544 | or distribute the Package, if you do not accept this license. | ||||||
| 545 | |||||||
| 546 | If your Modified Version has been derived from a Modified Version made | ||||||
| 547 | by someone other than you, you are nevertheless required to ensure that | ||||||
| 548 | your Modified Version complies with the requirements of this license. | ||||||
| 549 | |||||||
| 550 | This license does not grant you the right to use any trademark, service | ||||||
| 551 | mark, tradename, or logo of the Copyright Holder. | ||||||
| 552 | |||||||
| 553 | This license includes the non-exclusive, worldwide, free-of-charge | ||||||
| 554 | patent license to make, have made, use, offer to sell, sell, import and | ||||||
| 555 | otherwise transfer the Package with respect to any patent claims | ||||||
| 556 | licensable by the Copyright Holder that are necessarily infringed by the | ||||||
| 557 | Package. If you institute patent litigation (including a cross-claim or | ||||||
| 558 | counterclaim) against any party alleging that the Package constitutes | ||||||
| 559 | direct or contributory patent infringement, then this Artistic License | ||||||
| 560 | to you shall terminate on the date that such litigation is filed. | ||||||
| 561 | |||||||
| 562 | Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER | ||||||
| 563 | AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. | ||||||
| 564 | THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||||||
| 565 | PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY | ||||||
| 566 | YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR | ||||||
| 567 | CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR | ||||||
| 568 | CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, | ||||||
| 569 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
| 570 | |||||||
| 571 | =cut | ||||||
| 572 | |||||||
| 573 | 1; # End of WWW::Challonge |