├── .project └── WebContent ├── COPYING ├── COPYING.LESSER ├── manifest.json ├── pages ├── notification-abort.html ├── notification.css ├── popup.css └── popup.html ├── resources ├── default-favico.gif ├── icon-128.png ├── icon-16.png └── icon-48.png └── scripts ├── background.js ├── deflate.js ├── inflate.js ├── popup.js └── zip.js /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ZipTabs 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.jsdt.core.javascriptValidator 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.common.project.facet.core.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.validation.validationbuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.wst.common.project.facet.core.nature 26 | org.eclipse.wst.common.modulecore.ModuleCoreNature 27 | org.eclipse.wst.jsdt.core.jsNature 28 | 29 | 30 | -------------------------------------------------------------------------------- /WebContent/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /WebContent/COPYING.LESSER: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /WebContent/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZipTabs", 3 | "icons": { 4 | "16": "resources/icon-16.png", 5 | "48": "resources/icon-48.png", 6 | "128": "resources/icon-128.png" 7 | }, 8 | "version": "0.1.7", 9 | "description": "Archive tabs in a zip file", 10 | "background" : { 11 | "scripts": [ 12 | "scripts/zip.js", 13 | "scripts/background.js" 14 | ] 15 | }, 16 | "browser_action": { 17 | "default_icon": "resources/icon-48.png", 18 | "default_title": "View tabs", 19 | "default_popup": "pages/popup.html" 20 | }, 21 | "web_accessible_resources": [ 22 | "pages/notification-abort.html", 23 | "pages/notification.css" 24 | ], 25 | "permissions" : ["tabs", "unlimitedStorage", "notifications"], 26 | "minimum_chrome_version" : "14", 27 | "manifest_version": 2 28 | } -------------------------------------------------------------------------------- /WebContent/pages/notification-abort.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Notification 5 | 6 | 7 | 8 | 9 | Error: process has been aborted 10 | 11 | -------------------------------------------------------------------------------- /WebContent/pages/notification.css: -------------------------------------------------------------------------------- 1 | .label { 2 | font-family: sans-serif; 3 | font-size: 10pt; 4 | font-weight: bold; 5 | display: inline-block; 6 | position: absolute; 7 | left: 40px; 8 | top: 8px; 9 | } 10 | 11 | .error { 12 | font-size: 9pt; 13 | color: red; 14 | } 15 | 16 | img { 17 | height: 16pt; 18 | width: 16pt; 19 | margin-right: 2pt; 20 | } -------------------------------------------------------------------------------- /WebContent/pages/popup.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: 400px; 3 | margin: 5px; 4 | font-family: sans-serif; 5 | font-size: 10pt; 6 | } 7 | 8 | h4 { 9 | position: relative; 10 | margin-top: 2px; 11 | margin-bottom: 5px; 12 | padding: 5px; 13 | border-bottom: solid 2px #CCC; 14 | padding-bottom: 10px; 15 | height: 30px; 16 | } 17 | 18 | h4 span { 19 | font-size: 18pt; 20 | padding-bottom: 10px; 21 | padding-left: 10px; 22 | text-shadow: 2px 1px 1px #aaa; 23 | position: relative; 24 | bottom: 4px; 25 | display: inline-block; 26 | } 27 | 28 | h4 img { 29 | width: 32px; 30 | height: 32px; 31 | } 32 | 33 | ul { 34 | -webkit-box-flex: 1; 35 | padding-left: 10px; 36 | overflow-y: auto; 37 | padding-left: 5px; 38 | padding-right: 5px; 39 | padding-top: 2px; 40 | padding-bottom: 5px; 41 | margin-bottom: 30px; 42 | max-height: 500px; 43 | margin-top: 3px; 44 | } 45 | 46 | li { 47 | list-style-type: none; 48 | padding-bottom: 2px; 49 | padding-top: 1px; 50 | position: relative; 51 | } 52 | 53 | input { 54 | background-color: inherit; 55 | } 56 | 57 | input[type=checkbox] { 58 | margin-right: 0px; 59 | } 60 | 61 | input[type=button],button { 62 | width: 120px; 63 | background-color: #f3f3f3; 64 | -webkit-border-radius: 3px; 65 | } 66 | 67 | input[type=file] { 68 | position: absolute; 69 | right: 0px; 70 | top: 1px; 71 | margin: 2px; 72 | direction: rtl; 73 | color: transparent; 74 | } 75 | 76 | ul a:visited,#pages-links a { 77 | color: #00C; 78 | } 79 | 80 | .tabs-tab-favico { 81 | height: 16px; 82 | left: 3px; 83 | margin-right: 8px; 84 | margin-left: 5px; 85 | position: relative; 86 | top: 1px; 87 | width: 16px; 88 | } 89 | 90 | #tabs-zip-action { 91 | position: absolute; 92 | right: 0px; 93 | bottom: 0px; 94 | width: 80px; 95 | } 96 | 97 | .tabs-tab-title { 98 | display: inline-block; 99 | width: 320px; 100 | margin-left: 5px; 101 | overflow: hidden; 102 | text-overflow: ellipsis; 103 | white-space: nowrap; 104 | overflow: hidden; 105 | position: relative; 106 | top: -2px; 107 | } 108 | 109 | .tabs-tab-title.saving { 110 | width: 220px; 111 | } 112 | 113 | .tabs-tab-progress { 114 | position: absolute; 115 | right: 5px; 116 | top: 3px; 117 | height: 15px; 118 | width: 95px; 119 | opacity: .5; 120 | } 121 | 122 | #error { 123 | padding-left: 5px; 124 | padding-right: 5px; 125 | font-size: 11pt; 126 | } 127 | 128 | *::-webkit-file-upload-button { 129 | background-color: transparent; 130 | color: blue; 131 | border: none; 132 | text-decoration: underline; 133 | cursor: pointer; 134 | } -------------------------------------------------------------------------------- /WebContent/pages/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ZipTabs 5 | 6 | 7 | 8 | 12 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /WebContent/resources/default-favico.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/ZipTabs/dfaf1651d584a8acdbd43fa4767e4fe3a2fd3410/WebContent/resources/default-favico.gif -------------------------------------------------------------------------------- /WebContent/resources/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/ZipTabs/dfaf1651d584a8acdbd43fa4767e4fe3a2fd3410/WebContent/resources/icon-128.png -------------------------------------------------------------------------------- /WebContent/resources/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/ZipTabs/dfaf1651d584a8acdbd43fa4767e4fe3a2fd3410/WebContent/resources/icon-16.png -------------------------------------------------------------------------------- /WebContent/resources/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gildas-lormeau/ZipTabs/dfaf1651d584a8acdbd43fa4767e4fe3a2fd3410/WebContent/resources/icon-48.png -------------------------------------------------------------------------------- /WebContent/scripts/background.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of ZipTabs. 6 | * 7 | * ZipTabs is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * ZipTabs is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with ZipTabs. If not, see . 19 | */ 20 | 21 | (function(globalObject) { 22 | 23 | var dev = false; 24 | 25 | var SINGLE_FILE_ID = dev ? "onlinihoegnbbcmeeocfeplgbkmoidla" : "jemlklgaibiijojffihnhieihhagocma"; 26 | var STATE = { 27 | IDLE : 0, 28 | EXPORTING : 1, 29 | IMPORTING : 2 30 | }; 31 | var EMPTY_FUNCTION = function() { 32 | }; 33 | 34 | var state = STATE.IDLE; 35 | var createFile, cleanFilesystem; 36 | 37 | function getValidFileName(fileName) { 38 | return fileName.replace(/[\\\/:\*\?\"><|]/gi, "").trim(); 39 | } 40 | 41 | function WatchDog(resetFn) { 42 | var timeout, that = this; 43 | 44 | that.reset = function() { 45 | if (timeout) 46 | clearTimeout(timeout); 47 | timeout = null; 48 | }; 49 | 50 | that.set = function() { 51 | that.reset(); 52 | timeout = setTimeout(function() { 53 | var notificationNoResponse = webkitNotifications.createHTMLNotification("pages/notification-abort.html"); 54 | notificationNoResponse.show(); 55 | setTimeout(function() { 56 | notificationNoResponse.cancel(); 57 | }, 3000); 58 | resetFn(); 59 | timeout = null; 60 | }, 90000); 61 | }; 62 | } 63 | 64 | function terminateProcess(process, watchdog) { 65 | function end() { 66 | chrome.browserAction.setBadgeText({ 67 | text : "" 68 | }); 69 | chrome.browserAction.setTitle({ 70 | title : "" 71 | }); 72 | state = STATE.IDLE; 73 | watchdog.reset(); 74 | } 75 | 76 | if (process) 77 | process.close(end); 78 | else 79 | end(); 80 | } 81 | 82 | globalObject.ziptabs = { 83 | idle : function() { 84 | return state == STATE.IDLE; 85 | }, 86 | detectSingleFile : function(callback) { 87 | var img = new Image(); 88 | img.src = "chrome-extension://" + SINGLE_FILE_ID + "/resources/icon_16.png"; 89 | img.onload = function() { 90 | callback(true); 91 | }; 92 | img.onerror = function() { 93 | callback(false); 94 | }; 95 | }, 96 | refreshPopup : EMPTY_FUNCTION, 97 | exportTabs : function(tabIds, filename) { 98 | var zipWriter, file, index = 0, max = tabIds.length, watchdog = new WatchDog(terminate), tabs = {}; 99 | 100 | function onProgress(tabId, tab) { 101 | if (tab) 102 | tabs[tabId] = tab; 103 | chrome.extension.getViews({ 104 | type : "popup" 105 | }).forEach(function(popup) { 106 | popup.ziptabs.onTabProgress(tabId, tabs[tabId].state, tabs[tabId].index, tabs[tabId].max); 107 | }); 108 | } 109 | 110 | function terminate() { 111 | globalObject.ziptabs.refreshPopup = EMPTY_FUNCTION; 112 | terminateProcess(zipWriter, watchdog); 113 | zipWriter = null; 114 | } 115 | 116 | function singleFileListener(request, sender, sendResponse) { 117 | var tabId = request.tabId; 118 | if (request.processProgress) 119 | onProgress(tabId, { 120 | index : request.tabIndex, 121 | max : request.tabMaxIndex, 122 | state : 1 123 | }); 124 | else if (request.processEnd) { 125 | var content, filename, blob; 126 | content = request.content.replace(/]*http-equiv\s*=\s*["']?content-type[^>]*>/gi, "").replace(/]*charset\s*=[^>]*>/gi, ""); 127 | filename = (request.title.replace(/[\\\/:\*\?\"><|]/gi, "").trim() || "Untitled") + " (" + tabId + ").html"; 128 | blob = new Blob([ new Uint8Array([ 0xEF, 0xBB, 0xBF ]), content ], { 129 | type : "text/html" 130 | }); 131 | zipWriter.add(filename, new zip.BlobReader(blob), function() { 132 | onProgress(tabId, { 133 | state : 2 134 | }); 135 | watchdog.set(); 136 | index++; 137 | if (index == max) { 138 | chrome.extension.onMessageExternal.removeListener(singleFileListener); 139 | zipWriter.close(function() { 140 | chrome.tabs.create({ 141 | url : file.toURL(), 142 | selected : false 143 | }); 144 | zipWriter = null; 145 | terminate(); 146 | }); 147 | } else 148 | chrome.extension.sendMessage(SINGLE_FILE_ID, { 149 | tabIds : [ tabIds[index] ] 150 | }, function() { 151 | }); 152 | chrome.browserAction.setBadgeText({ 153 | text : Math.floor((index / max) * 100) + "%" 154 | }); 155 | chrome.browserAction.setTitle({ 156 | title : "Exporting tabs..." 157 | }); 158 | }, function(current, total) { 159 | onProgress(tabId, { 160 | index : current, 161 | max : total, 162 | state : 2 163 | }); 164 | }); 165 | } 166 | } 167 | 168 | globalObject.ziptabs.refreshPopup = function() { 169 | tabIds.forEach(function(tabId) { 170 | onProgress(tabId); 171 | }); 172 | }; 173 | state = STATE.EXPORTING; 174 | watchdog.set(); 175 | tabIds.forEach(function(tabId) { 176 | onProgress(tabId, { 177 | index : 0, 178 | max : 100, 179 | state : 0 180 | }); 181 | }); 182 | chrome.extension.onMessageExternal.addListener(singleFileListener); 183 | cleanFilesystem(function() { 184 | createFile(filename, function(outputFile) { 185 | file = outputFile; 186 | zip.createWriter(new zip.FileWriter(outputFile), function(writer) { 187 | zipWriter = writer; 188 | chrome.extension.sendMessage(SINGLE_FILE_ID, { 189 | tabIds : [ tabIds[index] ] 190 | }, function() { 191 | }); 192 | }, onerror); 193 | }); 194 | }); 195 | }, 196 | importTabs : function(inputFile) { 197 | var watchdog = new WatchDog(terminate), zipReader; 198 | 199 | function terminate() { 200 | terminateProcess(zipReader, watchdog); 201 | } 202 | 203 | zip.createReader(new zip.BlobReader(inputFile), function(reader) { 204 | zipReader = reader; 205 | zipReader.getEntries(function(entries) { 206 | function getEntry(index) { 207 | var entry = entries[index]; 208 | 209 | function nextFile() { 210 | chrome.browserAction.setBadgeText({ 211 | text : Math.floor((index / entries.length) * 100) + "%" 212 | }); 213 | chrome.browserAction.setTitle({ 214 | title : "Importing archives..." 215 | }); 216 | if (index == entries.length - 1) 217 | terminate(); 218 | else { 219 | getEntry(index + 1); 220 | watchdog.set(); 221 | } 222 | } 223 | 224 | if (entry && /.html$|.htm$/.test(entry.filename)) 225 | createFile(index + ".html", function(file) { 226 | entry.getData(new zip.FileWriter(file), function() { 227 | chrome.tabs.create({ 228 | url : file.toURL(), 229 | selected : false 230 | }, nextFile); 231 | }, function(current, total) { 232 | chrome.browserAction.setBadgeText({ 233 | text : Math.floor((index / entries.length) * 100 + ((current / total) * (100 / entries.length))) + "%" 234 | }); 235 | }); 236 | }, !index); 237 | else 238 | nextFile(); 239 | } 240 | 241 | cleanFilesystem(function() { 242 | getEntry(0); 243 | }); 244 | }, onerror); 245 | watchdog.set(); 246 | }, onerror); 247 | 248 | state = STATE.IMPORTING; 249 | } 250 | }; 251 | 252 | zip.workerScriptsPath = "scripts/"; 253 | webkitRequestFileSystem(TEMPORARY, 1024 * 1024 * 1024, function(filesystem) { 254 | cleanFilesystem = function(callback) { 255 | var rootReader = filesystem.root.createReader("/"); 256 | rootReader.readEntries(function(entries) { 257 | var i = 0; 258 | 259 | function removeNextEntry() { 260 | function next() { 261 | i++; 262 | removeNextEntry(); 263 | } 264 | 265 | if (i < entries.length) 266 | entries[i].remove(next, next); 267 | else 268 | callback(); 269 | } 270 | 271 | removeNextEntry(); 272 | }, callback); 273 | }; 274 | createFile = function(filename, callback) { 275 | filename = getValidFileName(filename); 276 | filesystem.root.getFile(filename, { 277 | create : true 278 | }, callback, callback); 279 | }; 280 | }); 281 | 282 | chrome.browserAction.setBadgeBackgroundColor({ 283 | color : [ 4, 229, 36, 255 ] 284 | }); 285 | 286 | })(window); 287 | -------------------------------------------------------------------------------- /WebContent/scripts/inflate.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* 30 | * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc. 31 | * JZlib is based on zlib-1.1.3, so all credit should go authors 32 | * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) 33 | * and contributors of zlib. 34 | */ 35 | 36 | (function(obj) { 37 | 38 | // Global 39 | var MAX_BITS = 15; 40 | 41 | var Z_OK = 0; 42 | var Z_STREAM_END = 1; 43 | var Z_NEED_DICT = 2; 44 | var Z_STREAM_ERROR = -2; 45 | var Z_DATA_ERROR = -3; 46 | var Z_MEM_ERROR = -4; 47 | var Z_BUF_ERROR = -5; 48 | 49 | var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 50 | 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ]; 51 | 52 | var MANY = 1440; 53 | 54 | var MAX_WBITS = 15; // 32K LZ77 window 55 | var DEF_WBITS = MAX_WBITS; 56 | 57 | // JZlib version : "1.0.2" 58 | var Z_NO_FLUSH = 0; 59 | var Z_FINISH = 4; 60 | 61 | // InfTree 62 | var fixed_bl = 9; 63 | var fixed_bd = 5; 64 | 65 | var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 66 | 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 67 | 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 68 | 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 69 | 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 70 | 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 71 | 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 72 | 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 73 | 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 74 | 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 75 | 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 76 | 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 77 | 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 78 | 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 79 | 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80 | 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 81 | 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 82 | 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 83 | 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 84 | 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 85 | 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 86 | 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 87 | 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 88 | 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 89 | 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 90 | 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 91 | 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 92 | 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 93 | 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 94 | 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 95 | 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 96 | 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 97 | 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 98 | 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 99 | 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 100 | 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 101 | 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ]; 102 | var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 103 | 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 104 | 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ]; 105 | 106 | // Tables for deflate from PKZIP's appnote.txt. 107 | var cplens = [ // Copy lengths for literal codes 257..285 108 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ]; 109 | 110 | // see note #13 above about 258 111 | var cplext = [ // Extra bits for literal codes 257..285 112 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid 113 | ]; 114 | 115 | var cpdist = [ // Copy offsets for distance codes 0..29 116 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ]; 117 | 118 | var cpdext = [ // Extra bits for distance codes 119 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ]; 120 | 121 | // If BMAX needs to be larger than 16, then h and x[] should be uLong. 122 | var BMAX = 15; // maximum bit length of any code 123 | 124 | function InfTree() { 125 | var that = this; 126 | 127 | var hn; // hufts used in space 128 | var v; // work area for huft_build 129 | var c; // bit length count table 130 | var r; // table entry for structure assignment 131 | var u; // table stack 132 | var x; // bit offsets, then code stack 133 | 134 | function huft_build(b, // code lengths in bits (all assumed <= 135 | // BMAX) 136 | bindex, n, // number of codes (assumed <= 288) 137 | s, // number of simple-valued codes (0..s-1) 138 | d, // list of base values for non-simple codes 139 | e, // list of extra bits for non-simple codes 140 | t, // result: starting table 141 | m, // maximum lookup bits, returns actual 142 | hp,// space for trees 143 | hn,// hufts used in space 144 | v // working area: values in order of bit length 145 | ) { 146 | // Given a list of code lengths and a maximum table size, make a set of 147 | // tables to decode that set of codes. Return Z_OK on success, 148 | // Z_BUF_ERROR 149 | // if the given code set is incomplete (the tables are still built in 150 | // this 151 | // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set 152 | // of 153 | // lengths), or Z_MEM_ERROR if not enough memory. 154 | 155 | var a; // counter for codes of length k 156 | var f; // i repeats in table every f entries 157 | var g; // maximum code length 158 | var h; // table level 159 | var i; // counter, current code 160 | var j; // counter 161 | var k; // number of bits in current code 162 | var l; // bits per table (returned in m) 163 | var mask; // (1 << w) - 1, to avoid cc -O bug on HP 164 | var p; // pointer into c[], b[], or v[] 165 | var q; // points to current table 166 | var w; // bits before this table == (l * h) 167 | var xp; // pointer into x 168 | var y; // number of dummy codes added 169 | var z; // number of entries in current table 170 | 171 | // Generate counts for each bit length 172 | 173 | p = 0; 174 | i = n; 175 | do { 176 | c[b[bindex + p]]++; 177 | p++; 178 | i--; // assume all entries <= BMAX 179 | } while (i !== 0); 180 | 181 | if (c[0] == n) { // null input--all zero length codes 182 | t[0] = -1; 183 | m[0] = 0; 184 | return Z_OK; 185 | } 186 | 187 | // Find minimum and maximum length, bound *m by those 188 | l = m[0]; 189 | for (j = 1; j <= BMAX; j++) 190 | if (c[j] !== 0) 191 | break; 192 | k = j; // minimum code length 193 | if (l < j) { 194 | l = j; 195 | } 196 | for (i = BMAX; i !== 0; i--) { 197 | if (c[i] !== 0) 198 | break; 199 | } 200 | g = i; // maximum code length 201 | if (l > i) { 202 | l = i; 203 | } 204 | m[0] = l; 205 | 206 | // Adjust last length count to fill out codes, if needed 207 | for (y = 1 << j; j < i; j++, y <<= 1) { 208 | if ((y -= c[j]) < 0) { 209 | return Z_DATA_ERROR; 210 | } 211 | } 212 | if ((y -= c[i]) < 0) { 213 | return Z_DATA_ERROR; 214 | } 215 | c[i] += y; 216 | 217 | // Generate starting offsets into the value table for each length 218 | x[1] = j = 0; 219 | p = 1; 220 | xp = 2; 221 | while (--i !== 0) { // note that i == g from above 222 | x[xp] = (j += c[p]); 223 | xp++; 224 | p++; 225 | } 226 | 227 | // Make a table of values in order of bit lengths 228 | i = 0; 229 | p = 0; 230 | do { 231 | if ((j = b[bindex + p]) !== 0) { 232 | v[x[j]++] = i; 233 | } 234 | p++; 235 | } while (++i < n); 236 | n = x[g]; // set n to length of v 237 | 238 | // Generate the Huffman codes and for each, make the table entries 239 | x[0] = i = 0; // first Huffman code is zero 240 | p = 0; // grab values in bit order 241 | h = -1; // no tables yet--level -1 242 | w = -l; // bits decoded == (l * h) 243 | u[0] = 0; // just to keep compilers happy 244 | q = 0; // ditto 245 | z = 0; // ditto 246 | 247 | // go through the bit lengths (k already is bits in shortest code) 248 | for (; k <= g; k++) { 249 | a = c[k]; 250 | while (a-- !== 0) { 251 | // here i is the Huffman code of length k bits for value *p 252 | // make tables up to required level 253 | while (k > w + l) { 254 | h++; 255 | w += l; // previous table always l bits 256 | // compute minimum size table less than or equal to l bits 257 | z = g - w; 258 | z = (z > l) ? l : z; // table size upper limit 259 | if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table 260 | // too few codes for 261 | // k-w bit table 262 | f -= a + 1; // deduct codes from patterns left 263 | xp = k; 264 | if (j < z) { 265 | while (++j < z) { // try smaller tables up to z bits 266 | if ((f <<= 1) <= c[++xp]) 267 | break; // enough codes to use up j bits 268 | f -= c[xp]; // else deduct codes from patterns 269 | } 270 | } 271 | } 272 | z = 1 << j; // table entries for j-bit table 273 | 274 | // allocate new table 275 | if (hn[0] + z > MANY) { // (note: doesn't matter for fixed) 276 | return Z_DATA_ERROR; // overflow of MANY 277 | } 278 | u[h] = q = /* hp+ */hn[0]; // DEBUG 279 | hn[0] += z; 280 | 281 | // connect to last table, if there is one 282 | if (h !== 0) { 283 | x[h] = i; // save pattern for backing up 284 | r[0] = /* (byte) */j; // bits in this table 285 | r[1] = /* (byte) */l; // bits to dump before this table 286 | j = i >>> (w - l); 287 | r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table 288 | hp.set(r, (u[h - 1] + j) * 3); 289 | // to 290 | // last 291 | // table 292 | } else { 293 | t[0] = q; // first table is returned result 294 | } 295 | } 296 | 297 | // set up table entry in r 298 | r[1] = /* (byte) */(k - w); 299 | if (p >= n) { 300 | r[0] = 128 + 64; // out of values--invalid code 301 | } else if (v[p] < s) { 302 | r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is 303 | // end-of-block 304 | r[2] = v[p++]; // simple code is just the value 305 | } else { 306 | r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look 307 | // up in lists 308 | r[2] = d[v[p++] - s]; 309 | } 310 | 311 | // fill code-like entries with r 312 | f = 1 << (k - w); 313 | for (j = i >>> w; j < z; j += f) { 314 | hp.set(r, (q + j) * 3); 315 | } 316 | 317 | // backwards increment the k-bit code i 318 | for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) { 319 | i ^= j; 320 | } 321 | i ^= j; 322 | 323 | // backup over finished tables 324 | mask = (1 << w) - 1; // needed on HP, cc -O bug 325 | while ((i & mask) != x[h]) { 326 | h--; // don't need to update q 327 | w -= l; 328 | mask = (1 << w) - 1; 329 | } 330 | } 331 | } 332 | // Return Z_BUF_ERROR if we were given an incomplete table 333 | return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK; 334 | } 335 | 336 | function initWorkArea(vsize) { 337 | var i; 338 | if (!hn) { 339 | hn = []; // []; //new Array(1); 340 | v = []; // new Array(vsize); 341 | c = new Int32Array(BMAX + 1); // new Array(BMAX + 1); 342 | r = []; // new Array(3); 343 | u = new Int32Array(BMAX); // new Array(BMAX); 344 | x = new Int32Array(BMAX + 1); // new Array(BMAX + 1); 345 | } 346 | if (v.length < vsize) { 347 | v = []; // new Array(vsize); 348 | } 349 | for (i = 0; i < vsize; i++) { 350 | v[i] = 0; 351 | } 352 | for (i = 0; i < BMAX + 1; i++) { 353 | c[i] = 0; 354 | } 355 | for (i = 0; i < 3; i++) { 356 | r[i] = 0; 357 | } 358 | // for(int i=0; i 257)) { 415 | if (result == Z_DATA_ERROR) { 416 | z.msg = "oversubscribed distance tree"; 417 | } else if (result == Z_BUF_ERROR) { 418 | z.msg = "incomplete distance tree"; 419 | result = Z_DATA_ERROR; 420 | } else if (result != Z_MEM_ERROR) { 421 | z.msg = "empty distance tree with lengths"; 422 | result = Z_DATA_ERROR; 423 | } 424 | return result; 425 | } 426 | 427 | return Z_OK; 428 | }; 429 | 430 | } 431 | 432 | InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth 433 | bd, // distance desired/actual bit depth 434 | tl,// literal/length tree result 435 | td,// distance tree result 436 | z // for memory allocation 437 | ) { 438 | bl[0] = fixed_bl; 439 | bd[0] = fixed_bd; 440 | tl[0] = fixed_tl; 441 | td[0] = fixed_td; 442 | return Z_OK; 443 | }; 444 | 445 | // InfCodes 446 | 447 | // waiting for "i:"=input, 448 | // "o:"=output, 449 | // "x:"=nothing 450 | var START = 0; // x: set up for LEN 451 | var LEN = 1; // i: get length/literal/eob next 452 | var LENEXT = 2; // i: getting length extra (have base) 453 | var DIST = 3; // i: get distance next 454 | var DISTEXT = 4;// i: getting distance extra 455 | var COPY = 5; // o: copying bytes in window, waiting 456 | // for space 457 | var LIT = 6; // o: got literal, waiting for output 458 | // space 459 | var WASH = 7; // o: got eob, possibly still output 460 | // waiting 461 | var END = 8; // x: got eob and all data flushed 462 | var BADCODE = 9;// x: got error 463 | 464 | function InfCodes() { 465 | var that = this; 466 | 467 | var mode; // current inflate_codes mode 468 | 469 | // mode dependent information 470 | var len = 0; 471 | 472 | var tree; // pointer into tree 473 | var tree_index = 0; 474 | var need = 0; // bits needed 475 | 476 | var lit = 0; 477 | 478 | // if EXT or COPY, where and how much 479 | var get = 0; // bits to get for extra 480 | var dist = 0; // distance back to copy from 481 | 482 | var lbits = 0; // ltree bits decoded per branch 483 | var dbits = 0; // dtree bits decoder per branch 484 | var ltree; // literal/length/eob tree 485 | var ltree_index = 0; // literal/length/eob tree 486 | var dtree; // distance tree 487 | var dtree_index = 0; // distance tree 488 | 489 | // Called with number of bytes left to write in window at least 258 490 | // (the maximum string length) and number of input bytes available 491 | // at least ten. The ten bytes are six bytes for the longest length/ 492 | // distance pair plus four bytes for overloading the bit buffer. 493 | 494 | function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) { 495 | var t; // temporary pointer 496 | var tp; // temporary pointer 497 | var tp_index; // temporary pointer 498 | var e; // extra bits or operation 499 | var b; // bit buffer 500 | var k; // bits in bit buffer 501 | var p; // input data pointer 502 | var n; // bytes available there 503 | var q; // output window write pointer 504 | var m; // bytes to end of window or read pointer 505 | var ml; // mask for literal/length tree 506 | var md; // mask for distance tree 507 | var c; // bytes to copy 508 | var d; // distance back to copy from 509 | var r; // copy source pointer 510 | 511 | var tp_index_t_3; // (tp_index+t)*3 512 | 513 | // load input, output, bit values 514 | p = z.next_in_index; 515 | n = z.avail_in; 516 | b = s.bitb; 517 | k = s.bitk; 518 | q = s.write; 519 | m = q < s.read ? s.read - q - 1 : s.end - q; 520 | 521 | // initialize masks 522 | ml = inflate_mask[bl]; 523 | md = inflate_mask[bd]; 524 | 525 | // do until not enough input or output space for fast loop 526 | do { // assume called with m >= 258 && n >= 10 527 | // get literal/length code 528 | while (k < (20)) { // max bits for literal/length code 529 | n--; 530 | b |= (z.read_byte(p++) & 0xff) << k; 531 | k += 8; 532 | } 533 | 534 | t = b & ml; 535 | tp = tl; 536 | tp_index = tl_index; 537 | tp_index_t_3 = (tp_index + t) * 3; 538 | if ((e = tp[tp_index_t_3]) === 0) { 539 | b >>= (tp[tp_index_t_3 + 1]); 540 | k -= (tp[tp_index_t_3 + 1]); 541 | 542 | s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2]; 543 | m--; 544 | continue; 545 | } 546 | do { 547 | 548 | b >>= (tp[tp_index_t_3 + 1]); 549 | k -= (tp[tp_index_t_3 + 1]); 550 | 551 | if ((e & 16) !== 0) { 552 | e &= 15; 553 | c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]); 554 | 555 | b >>= e; 556 | k -= e; 557 | 558 | // decode distance base of block to copy 559 | while (k < (15)) { // max bits for distance code 560 | n--; 561 | b |= (z.read_byte(p++) & 0xff) << k; 562 | k += 8; 563 | } 564 | 565 | t = b & md; 566 | tp = td; 567 | tp_index = td_index; 568 | tp_index_t_3 = (tp_index + t) * 3; 569 | e = tp[tp_index_t_3]; 570 | 571 | do { 572 | 573 | b >>= (tp[tp_index_t_3 + 1]); 574 | k -= (tp[tp_index_t_3 + 1]); 575 | 576 | if ((e & 16) !== 0) { 577 | // get extra bits to add to distance base 578 | e &= 15; 579 | while (k < (e)) { // get extra bits (up to 13) 580 | n--; 581 | b |= (z.read_byte(p++) & 0xff) << k; 582 | k += 8; 583 | } 584 | 585 | d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); 586 | 587 | b >>= (e); 588 | k -= (e); 589 | 590 | // do the copy 591 | m -= c; 592 | if (q >= d) { // offset before dest 593 | // just copy 594 | r = q - d; 595 | if (q - r > 0 && 2 > (q - r)) { 596 | s.window[q++] = s.window[r++]; // minimum 597 | // count is 598 | // three, 599 | s.window[q++] = s.window[r++]; // so unroll 600 | // loop a 601 | // little 602 | c -= 2; 603 | } else { 604 | s.window.set(s.window.subarray(r, r + 2), q); 605 | q += 2; 606 | r += 2; 607 | c -= 2; 608 | } 609 | } else { // else offset after destination 610 | r = q - d; 611 | do { 612 | r += s.end; // force pointer in window 613 | } while (r < 0); // covers invalid distances 614 | e = s.end - r; 615 | if (c > e) { // if source crosses, 616 | c -= e; // wrapped copy 617 | if (q - r > 0 && e > (q - r)) { 618 | do { 619 | s.window[q++] = s.window[r++]; 620 | } while (--e !== 0); 621 | } else { 622 | s.window.set(s.window.subarray(r, r + e), q); 623 | q += e; 624 | r += e; 625 | e = 0; 626 | } 627 | r = 0; // copy rest from start of window 628 | } 629 | 630 | } 631 | 632 | // copy all or what's left 633 | if (q - r > 0 && c > (q - r)) { 634 | do { 635 | s.window[q++] = s.window[r++]; 636 | } while (--c !== 0); 637 | } else { 638 | s.window.set(s.window.subarray(r, r + c), q); 639 | q += c; 640 | r += c; 641 | c = 0; 642 | } 643 | break; 644 | } else if ((e & 64) === 0) { 645 | t += tp[tp_index_t_3 + 2]; 646 | t += (b & inflate_mask[e]); 647 | tp_index_t_3 = (tp_index + t) * 3; 648 | e = tp[tp_index_t_3]; 649 | } else { 650 | z.msg = "invalid distance code"; 651 | 652 | c = z.avail_in - n; 653 | c = (k >> 3) < c ? k >> 3 : c; 654 | n += c; 655 | p -= c; 656 | k -= c << 3; 657 | 658 | s.bitb = b; 659 | s.bitk = k; 660 | z.avail_in = n; 661 | z.total_in += p - z.next_in_index; 662 | z.next_in_index = p; 663 | s.write = q; 664 | 665 | return Z_DATA_ERROR; 666 | } 667 | } while (true); 668 | break; 669 | } 670 | 671 | if ((e & 64) === 0) { 672 | t += tp[tp_index_t_3 + 2]; 673 | t += (b & inflate_mask[e]); 674 | tp_index_t_3 = (tp_index + t) * 3; 675 | if ((e = tp[tp_index_t_3]) === 0) { 676 | 677 | b >>= (tp[tp_index_t_3 + 1]); 678 | k -= (tp[tp_index_t_3 + 1]); 679 | 680 | s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2]; 681 | m--; 682 | break; 683 | } 684 | } else if ((e & 32) !== 0) { 685 | 686 | c = z.avail_in - n; 687 | c = (k >> 3) < c ? k >> 3 : c; 688 | n += c; 689 | p -= c; 690 | k -= c << 3; 691 | 692 | s.bitb = b; 693 | s.bitk = k; 694 | z.avail_in = n; 695 | z.total_in += p - z.next_in_index; 696 | z.next_in_index = p; 697 | s.write = q; 698 | 699 | return Z_STREAM_END; 700 | } else { 701 | z.msg = "invalid literal/length code"; 702 | 703 | c = z.avail_in - n; 704 | c = (k >> 3) < c ? k >> 3 : c; 705 | n += c; 706 | p -= c; 707 | k -= c << 3; 708 | 709 | s.bitb = b; 710 | s.bitk = k; 711 | z.avail_in = n; 712 | z.total_in += p - z.next_in_index; 713 | z.next_in_index = p; 714 | s.write = q; 715 | 716 | return Z_DATA_ERROR; 717 | } 718 | } while (true); 719 | } while (m >= 258 && n >= 10); 720 | 721 | // not enough input or output--restore pointers and return 722 | c = z.avail_in - n; 723 | c = (k >> 3) < c ? k >> 3 : c; 724 | n += c; 725 | p -= c; 726 | k -= c << 3; 727 | 728 | s.bitb = b; 729 | s.bitk = k; 730 | z.avail_in = n; 731 | z.total_in += p - z.next_in_index; 732 | z.next_in_index = p; 733 | s.write = q; 734 | 735 | return Z_OK; 736 | } 737 | 738 | that.init = function(bl, bd, tl, tl_index, td, td_index, z) { 739 | mode = START; 740 | lbits = /* (byte) */bl; 741 | dbits = /* (byte) */bd; 742 | ltree = tl; 743 | ltree_index = tl_index; 744 | dtree = td; 745 | dtree_index = td_index; 746 | tree = null; 747 | }; 748 | 749 | that.proc = function(s, z, r) { 750 | var j; // temporary storage 751 | var t; // temporary pointer 752 | var tindex; // temporary pointer 753 | var e; // extra bits or operation 754 | var b = 0; // bit buffer 755 | var k = 0; // bits in bit buffer 756 | var p = 0; // input data pointer 757 | var n; // bytes available there 758 | var q; // output window write pointer 759 | var m; // bytes to end of window or read pointer 760 | var f; // pointer to copy strings from 761 | 762 | // copy input/output information to locals (UPDATE macro restores) 763 | p = z.next_in_index; 764 | n = z.avail_in; 765 | b = s.bitb; 766 | k = s.bitk; 767 | q = s.write; 768 | m = q < s.read ? s.read - q - 1 : s.end - q; 769 | 770 | // process input and output based on current state 771 | while (true) { 772 | switch (mode) { 773 | // waiting for "i:"=input, "o:"=output, "x:"=nothing 774 | case START: // x: set up for LEN 775 | if (m >= 258 && n >= 10) { 776 | 777 | s.bitb = b; 778 | s.bitk = k; 779 | z.avail_in = n; 780 | z.total_in += p - z.next_in_index; 781 | z.next_in_index = p; 782 | s.write = q; 783 | r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); 784 | 785 | p = z.next_in_index; 786 | n = z.avail_in; 787 | b = s.bitb; 788 | k = s.bitk; 789 | q = s.write; 790 | m = q < s.read ? s.read - q - 1 : s.end - q; 791 | 792 | if (r != Z_OK) { 793 | mode = r == Z_STREAM_END ? WASH : BADCODE; 794 | break; 795 | } 796 | } 797 | need = lbits; 798 | tree = ltree; 799 | tree_index = ltree_index; 800 | 801 | mode = LEN; 802 | case LEN: // i: get length/literal/eob next 803 | j = need; 804 | 805 | while (k < (j)) { 806 | if (n !== 0) 807 | r = Z_OK; 808 | else { 809 | 810 | s.bitb = b; 811 | s.bitk = k; 812 | z.avail_in = n; 813 | z.total_in += p - z.next_in_index; 814 | z.next_in_index = p; 815 | s.write = q; 816 | return s.inflate_flush(z, r); 817 | } 818 | n--; 819 | b |= (z.read_byte(p++) & 0xff) << k; 820 | k += 8; 821 | } 822 | 823 | tindex = (tree_index + (b & inflate_mask[j])) * 3; 824 | 825 | b >>>= (tree[tindex + 1]); 826 | k -= (tree[tindex + 1]); 827 | 828 | e = tree[tindex]; 829 | 830 | if (e === 0) { // literal 831 | lit = tree[tindex + 2]; 832 | mode = LIT; 833 | break; 834 | } 835 | if ((e & 16) !== 0) { // length 836 | get = e & 15; 837 | len = tree[tindex + 2]; 838 | mode = LENEXT; 839 | break; 840 | } 841 | if ((e & 64) === 0) { // next table 842 | need = e; 843 | tree_index = tindex / 3 + tree[tindex + 2]; 844 | break; 845 | } 846 | if ((e & 32) !== 0) { // end of block 847 | mode = WASH; 848 | break; 849 | } 850 | mode = BADCODE; // invalid code 851 | z.msg = "invalid literal/length code"; 852 | r = Z_DATA_ERROR; 853 | 854 | s.bitb = b; 855 | s.bitk = k; 856 | z.avail_in = n; 857 | z.total_in += p - z.next_in_index; 858 | z.next_in_index = p; 859 | s.write = q; 860 | return s.inflate_flush(z, r); 861 | 862 | case LENEXT: // i: getting length extra (have base) 863 | j = get; 864 | 865 | while (k < (j)) { 866 | if (n !== 0) 867 | r = Z_OK; 868 | else { 869 | 870 | s.bitb = b; 871 | s.bitk = k; 872 | z.avail_in = n; 873 | z.total_in += p - z.next_in_index; 874 | z.next_in_index = p; 875 | s.write = q; 876 | return s.inflate_flush(z, r); 877 | } 878 | n--; 879 | b |= (z.read_byte(p++) & 0xff) << k; 880 | k += 8; 881 | } 882 | 883 | len += (b & inflate_mask[j]); 884 | 885 | b >>= j; 886 | k -= j; 887 | 888 | need = dbits; 889 | tree = dtree; 890 | tree_index = dtree_index; 891 | mode = DIST; 892 | case DIST: // i: get distance next 893 | j = need; 894 | 895 | while (k < (j)) { 896 | if (n !== 0) 897 | r = Z_OK; 898 | else { 899 | 900 | s.bitb = b; 901 | s.bitk = k; 902 | z.avail_in = n; 903 | z.total_in += p - z.next_in_index; 904 | z.next_in_index = p; 905 | s.write = q; 906 | return s.inflate_flush(z, r); 907 | } 908 | n--; 909 | b |= (z.read_byte(p++) & 0xff) << k; 910 | k += 8; 911 | } 912 | 913 | tindex = (tree_index + (b & inflate_mask[j])) * 3; 914 | 915 | b >>= tree[tindex + 1]; 916 | k -= tree[tindex + 1]; 917 | 918 | e = (tree[tindex]); 919 | if ((e & 16) !== 0) { // distance 920 | get = e & 15; 921 | dist = tree[tindex + 2]; 922 | mode = DISTEXT; 923 | break; 924 | } 925 | if ((e & 64) === 0) { // next table 926 | need = e; 927 | tree_index = tindex / 3 + tree[tindex + 2]; 928 | break; 929 | } 930 | mode = BADCODE; // invalid code 931 | z.msg = "invalid distance code"; 932 | r = Z_DATA_ERROR; 933 | 934 | s.bitb = b; 935 | s.bitk = k; 936 | z.avail_in = n; 937 | z.total_in += p - z.next_in_index; 938 | z.next_in_index = p; 939 | s.write = q; 940 | return s.inflate_flush(z, r); 941 | 942 | case DISTEXT: // i: getting distance extra 943 | j = get; 944 | 945 | while (k < (j)) { 946 | if (n !== 0) 947 | r = Z_OK; 948 | else { 949 | 950 | s.bitb = b; 951 | s.bitk = k; 952 | z.avail_in = n; 953 | z.total_in += p - z.next_in_index; 954 | z.next_in_index = p; 955 | s.write = q; 956 | return s.inflate_flush(z, r); 957 | } 958 | n--; 959 | b |= (z.read_byte(p++) & 0xff) << k; 960 | k += 8; 961 | } 962 | 963 | dist += (b & inflate_mask[j]); 964 | 965 | b >>= j; 966 | k -= j; 967 | 968 | mode = COPY; 969 | case COPY: // o: copying bytes in window, waiting for space 970 | f = q - dist; 971 | while (f < 0) { // modulo window size-"while" instead 972 | f += s.end; // of "if" handles invalid distances 973 | } 974 | while (len !== 0) { 975 | 976 | if (m === 0) { 977 | if (q == s.end && s.read !== 0) { 978 | q = 0; 979 | m = q < s.read ? s.read - q - 1 : s.end - q; 980 | } 981 | if (m === 0) { 982 | s.write = q; 983 | r = s.inflate_flush(z, r); 984 | q = s.write; 985 | m = q < s.read ? s.read - q - 1 : s.end - q; 986 | 987 | if (q == s.end && s.read !== 0) { 988 | q = 0; 989 | m = q < s.read ? s.read - q - 1 : s.end - q; 990 | } 991 | 992 | if (m === 0) { 993 | s.bitb = b; 994 | s.bitk = k; 995 | z.avail_in = n; 996 | z.total_in += p - z.next_in_index; 997 | z.next_in_index = p; 998 | s.write = q; 999 | return s.inflate_flush(z, r); 1000 | } 1001 | } 1002 | } 1003 | 1004 | s.window[q++] = s.window[f++]; 1005 | m--; 1006 | 1007 | if (f == s.end) 1008 | f = 0; 1009 | len--; 1010 | } 1011 | mode = START; 1012 | break; 1013 | case LIT: // o: got literal, waiting for output space 1014 | if (m === 0) { 1015 | if (q == s.end && s.read !== 0) { 1016 | q = 0; 1017 | m = q < s.read ? s.read - q - 1 : s.end - q; 1018 | } 1019 | if (m === 0) { 1020 | s.write = q; 1021 | r = s.inflate_flush(z, r); 1022 | q = s.write; 1023 | m = q < s.read ? s.read - q - 1 : s.end - q; 1024 | 1025 | if (q == s.end && s.read !== 0) { 1026 | q = 0; 1027 | m = q < s.read ? s.read - q - 1 : s.end - q; 1028 | } 1029 | if (m === 0) { 1030 | s.bitb = b; 1031 | s.bitk = k; 1032 | z.avail_in = n; 1033 | z.total_in += p - z.next_in_index; 1034 | z.next_in_index = p; 1035 | s.write = q; 1036 | return s.inflate_flush(z, r); 1037 | } 1038 | } 1039 | } 1040 | r = Z_OK; 1041 | 1042 | s.window[q++] = /* (byte) */lit; 1043 | m--; 1044 | 1045 | mode = START; 1046 | break; 1047 | case WASH: // o: got eob, possibly more output 1048 | if (k > 7) { // return unused byte, if any 1049 | k -= 8; 1050 | n++; 1051 | p--; // can always return one 1052 | } 1053 | 1054 | s.write = q; 1055 | r = s.inflate_flush(z, r); 1056 | q = s.write; 1057 | m = q < s.read ? s.read - q - 1 : s.end - q; 1058 | 1059 | if (s.read != s.write) { 1060 | s.bitb = b; 1061 | s.bitk = k; 1062 | z.avail_in = n; 1063 | z.total_in += p - z.next_in_index; 1064 | z.next_in_index = p; 1065 | s.write = q; 1066 | return s.inflate_flush(z, r); 1067 | } 1068 | mode = END; 1069 | case END: 1070 | r = Z_STREAM_END; 1071 | s.bitb = b; 1072 | s.bitk = k; 1073 | z.avail_in = n; 1074 | z.total_in += p - z.next_in_index; 1075 | z.next_in_index = p; 1076 | s.write = q; 1077 | return s.inflate_flush(z, r); 1078 | 1079 | case BADCODE: // x: got error 1080 | 1081 | r = Z_DATA_ERROR; 1082 | 1083 | s.bitb = b; 1084 | s.bitk = k; 1085 | z.avail_in = n; 1086 | z.total_in += p - z.next_in_index; 1087 | z.next_in_index = p; 1088 | s.write = q; 1089 | return s.inflate_flush(z, r); 1090 | 1091 | default: 1092 | r = Z_STREAM_ERROR; 1093 | 1094 | s.bitb = b; 1095 | s.bitk = k; 1096 | z.avail_in = n; 1097 | z.total_in += p - z.next_in_index; 1098 | z.next_in_index = p; 1099 | s.write = q; 1100 | return s.inflate_flush(z, r); 1101 | } 1102 | } 1103 | }; 1104 | 1105 | that.free = function(z) { 1106 | // ZFREE(z, c); 1107 | }; 1108 | 1109 | } 1110 | 1111 | // InfBlocks 1112 | 1113 | // Table for deflate from PKZIP's appnote.txt. 1114 | var border = [ // Order of the bit length code lengths 1115 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; 1116 | 1117 | var TYPE = 0; // get type bits (3, including end bit) 1118 | var LENS = 1; // get lengths for stored 1119 | var STORED = 2;// processing stored block 1120 | var TABLE = 3; // get table lengths 1121 | var BTREE = 4; // get bit lengths tree for a dynamic 1122 | // block 1123 | var DTREE = 5; // get length, distance trees for a 1124 | // dynamic block 1125 | var CODES = 6; // processing fixed or dynamic block 1126 | var DRY = 7; // output remaining window bytes 1127 | var DONELOCKS = 8; // finished last block, done 1128 | var BADBLOCKS = 9; // ot a data error--stuck here 1129 | 1130 | function InfBlocks(z, w) { 1131 | var that = this; 1132 | 1133 | var mode = TYPE; // current inflate_block mode 1134 | 1135 | var left = 0; // if STORED, bytes left to copy 1136 | 1137 | var table = 0; // table lengths (14 bits) 1138 | var index = 0; // index into blens (or border) 1139 | var blens; // bit lengths of codes 1140 | var bb = [ 0 ]; // bit length tree depth 1141 | var tb = [ 0 ]; // bit length decoding tree 1142 | 1143 | var codes = new InfCodes(); // if CODES, current state 1144 | 1145 | var last = 0; // true if this block is the last block 1146 | 1147 | var hufts = new Int32Array(MANY * 3); // single malloc for tree space 1148 | var check = 0; // check on output 1149 | var inftree = new InfTree(); 1150 | 1151 | that.bitk = 0; // bits in bit buffer 1152 | that.bitb = 0; // bit buffer 1153 | that.window = new Uint8Array(w); // sliding window 1154 | that.end = w; // one byte after sliding window 1155 | that.read = 0; // window read pointer 1156 | that.write = 0; // window write pointer 1157 | 1158 | that.reset = function(z, c) { 1159 | if (c) 1160 | c[0] = check; 1161 | // if (mode == BTREE || mode == DTREE) { 1162 | // } 1163 | if (mode == CODES) { 1164 | codes.free(z); 1165 | } 1166 | mode = TYPE; 1167 | that.bitk = 0; 1168 | that.bitb = 0; 1169 | that.read = that.write = 0; 1170 | }; 1171 | 1172 | that.reset(z, null); 1173 | 1174 | // copy as much as possible from the sliding window to the output area 1175 | that.inflate_flush = function(z, r) { 1176 | var n; 1177 | var p; 1178 | var q; 1179 | 1180 | // local copies of source and destination pointers 1181 | p = z.next_out_index; 1182 | q = that.read; 1183 | 1184 | // compute number of bytes to copy as far as end of window 1185 | n = /* (int) */((q <= that.write ? that.write : that.end) - q); 1186 | if (n > z.avail_out) 1187 | n = z.avail_out; 1188 | if (n !== 0 && r == Z_BUF_ERROR) 1189 | r = Z_OK; 1190 | 1191 | // update counters 1192 | z.avail_out -= n; 1193 | z.total_out += n; 1194 | 1195 | // copy as far as end of window 1196 | z.next_out.set(that.window.subarray(q, q + n), p); 1197 | p += n; 1198 | q += n; 1199 | 1200 | // see if more to copy at beginning of window 1201 | if (q == that.end) { 1202 | // wrap pointers 1203 | q = 0; 1204 | if (that.write == that.end) 1205 | that.write = 0; 1206 | 1207 | // compute bytes to copy 1208 | n = that.write - q; 1209 | if (n > z.avail_out) 1210 | n = z.avail_out; 1211 | if (n !== 0 && r == Z_BUF_ERROR) 1212 | r = Z_OK; 1213 | 1214 | // update counters 1215 | z.avail_out -= n; 1216 | z.total_out += n; 1217 | 1218 | // copy 1219 | z.next_out.set(that.window.subarray(q, q + n), p); 1220 | p += n; 1221 | q += n; 1222 | } 1223 | 1224 | // update pointers 1225 | z.next_out_index = p; 1226 | that.read = q; 1227 | 1228 | // done 1229 | return r; 1230 | }; 1231 | 1232 | that.proc = function(z, r) { 1233 | var t; // temporary storage 1234 | var b; // bit buffer 1235 | var k; // bits in bit buffer 1236 | var p; // input data pointer 1237 | var n; // bytes available there 1238 | var q; // output window write pointer 1239 | var m; // bytes to end of window or read pointer 1240 | 1241 | var i; 1242 | 1243 | // copy input/output information to locals (UPDATE macro restores) 1244 | // { 1245 | p = z.next_in_index; 1246 | n = z.avail_in; 1247 | b = that.bitb; 1248 | k = that.bitk; 1249 | // } 1250 | // { 1251 | q = that.write; 1252 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1253 | // } 1254 | 1255 | // process input based on current state 1256 | // DEBUG dtree 1257 | while (true) { 1258 | switch (mode) { 1259 | case TYPE: 1260 | 1261 | while (k < (3)) { 1262 | if (n !== 0) { 1263 | r = Z_OK; 1264 | } else { 1265 | that.bitb = b; 1266 | that.bitk = k; 1267 | z.avail_in = n; 1268 | z.total_in += p - z.next_in_index; 1269 | z.next_in_index = p; 1270 | that.write = q; 1271 | return that.inflate_flush(z, r); 1272 | } 1273 | n--; 1274 | b |= (z.read_byte(p++) & 0xff) << k; 1275 | k += 8; 1276 | } 1277 | t = /* (int) */(b & 7); 1278 | last = t & 1; 1279 | 1280 | switch (t >>> 1) { 1281 | case 0: // stored 1282 | // { 1283 | b >>>= (3); 1284 | k -= (3); 1285 | // } 1286 | t = k & 7; // go to byte boundary 1287 | 1288 | // { 1289 | b >>>= (t); 1290 | k -= (t); 1291 | // } 1292 | mode = LENS; // get length of stored block 1293 | break; 1294 | case 1: // fixed 1295 | // { 1296 | var bl = []; // new Array(1); 1297 | var bd = []; // new Array(1); 1298 | var tl = [ [] ]; // new Array(1); 1299 | var td = [ [] ]; // new Array(1); 1300 | 1301 | InfTree.inflate_trees_fixed(bl, bd, tl, td, z); 1302 | codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z); 1303 | // } 1304 | 1305 | // { 1306 | b >>>= (3); 1307 | k -= (3); 1308 | // } 1309 | 1310 | mode = CODES; 1311 | break; 1312 | case 2: // dynamic 1313 | 1314 | // { 1315 | b >>>= (3); 1316 | k -= (3); 1317 | // } 1318 | 1319 | mode = TABLE; 1320 | break; 1321 | case 3: // illegal 1322 | 1323 | // { 1324 | b >>>= (3); 1325 | k -= (3); 1326 | // } 1327 | mode = BADBLOCKS; 1328 | z.msg = "invalid block type"; 1329 | r = Z_DATA_ERROR; 1330 | 1331 | that.bitb = b; 1332 | that.bitk = k; 1333 | z.avail_in = n; 1334 | z.total_in += p - z.next_in_index; 1335 | z.next_in_index = p; 1336 | that.write = q; 1337 | return that.inflate_flush(z, r); 1338 | } 1339 | break; 1340 | case LENS: 1341 | 1342 | while (k < (32)) { 1343 | if (n !== 0) { 1344 | r = Z_OK; 1345 | } else { 1346 | that.bitb = b; 1347 | that.bitk = k; 1348 | z.avail_in = n; 1349 | z.total_in += p - z.next_in_index; 1350 | z.next_in_index = p; 1351 | that.write = q; 1352 | return that.inflate_flush(z, r); 1353 | } 1354 | n--; 1355 | b |= (z.read_byte(p++) & 0xff) << k; 1356 | k += 8; 1357 | } 1358 | 1359 | if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) { 1360 | mode = BADBLOCKS; 1361 | z.msg = "invalid stored block lengths"; 1362 | r = Z_DATA_ERROR; 1363 | 1364 | that.bitb = b; 1365 | that.bitk = k; 1366 | z.avail_in = n; 1367 | z.total_in += p - z.next_in_index; 1368 | z.next_in_index = p; 1369 | that.write = q; 1370 | return that.inflate_flush(z, r); 1371 | } 1372 | left = (b & 0xffff); 1373 | b = k = 0; // dump bits 1374 | mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE); 1375 | break; 1376 | case STORED: 1377 | if (n === 0) { 1378 | that.bitb = b; 1379 | that.bitk = k; 1380 | z.avail_in = n; 1381 | z.total_in += p - z.next_in_index; 1382 | z.next_in_index = p; 1383 | that.write = q; 1384 | return that.inflate_flush(z, r); 1385 | } 1386 | 1387 | if (m === 0) { 1388 | if (q == that.end && that.read !== 0) { 1389 | q = 0; 1390 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1391 | } 1392 | if (m === 0) { 1393 | that.write = q; 1394 | r = that.inflate_flush(z, r); 1395 | q = that.write; 1396 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1397 | if (q == that.end && that.read !== 0) { 1398 | q = 0; 1399 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1400 | } 1401 | if (m === 0) { 1402 | that.bitb = b; 1403 | that.bitk = k; 1404 | z.avail_in = n; 1405 | z.total_in += p - z.next_in_index; 1406 | z.next_in_index = p; 1407 | that.write = q; 1408 | return that.inflate_flush(z, r); 1409 | } 1410 | } 1411 | } 1412 | r = Z_OK; 1413 | 1414 | t = left; 1415 | if (t > n) 1416 | t = n; 1417 | if (t > m) 1418 | t = m; 1419 | that.window.set(z.read_buf(p, t), q); 1420 | p += t; 1421 | n -= t; 1422 | q += t; 1423 | m -= t; 1424 | if ((left -= t) !== 0) 1425 | break; 1426 | mode = last !== 0 ? DRY : TYPE; 1427 | break; 1428 | case TABLE: 1429 | 1430 | while (k < (14)) { 1431 | if (n !== 0) { 1432 | r = Z_OK; 1433 | } else { 1434 | that.bitb = b; 1435 | that.bitk = k; 1436 | z.avail_in = n; 1437 | z.total_in += p - z.next_in_index; 1438 | z.next_in_index = p; 1439 | that.write = q; 1440 | return that.inflate_flush(z, r); 1441 | } 1442 | 1443 | n--; 1444 | b |= (z.read_byte(p++) & 0xff) << k; 1445 | k += 8; 1446 | } 1447 | 1448 | table = t = (b & 0x3fff); 1449 | if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { 1450 | mode = BADBLOCKS; 1451 | z.msg = "too many length or distance symbols"; 1452 | r = Z_DATA_ERROR; 1453 | 1454 | that.bitb = b; 1455 | that.bitk = k; 1456 | z.avail_in = n; 1457 | z.total_in += p - z.next_in_index; 1458 | z.next_in_index = p; 1459 | that.write = q; 1460 | return that.inflate_flush(z, r); 1461 | } 1462 | t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); 1463 | if (!blens || blens.length < t) { 1464 | blens = []; // new Array(t); 1465 | } else { 1466 | for (i = 0; i < t; i++) { 1467 | blens[i] = 0; 1468 | } 1469 | } 1470 | 1471 | // { 1472 | b >>>= (14); 1473 | k -= (14); 1474 | // } 1475 | 1476 | index = 0; 1477 | mode = BTREE; 1478 | case BTREE: 1479 | while (index < 4 + (table >>> 10)) { 1480 | while (k < (3)) { 1481 | if (n !== 0) { 1482 | r = Z_OK; 1483 | } else { 1484 | that.bitb = b; 1485 | that.bitk = k; 1486 | z.avail_in = n; 1487 | z.total_in += p - z.next_in_index; 1488 | z.next_in_index = p; 1489 | that.write = q; 1490 | return that.inflate_flush(z, r); 1491 | } 1492 | n--; 1493 | b |= (z.read_byte(p++) & 0xff) << k; 1494 | k += 8; 1495 | } 1496 | 1497 | blens[border[index++]] = b & 7; 1498 | 1499 | // { 1500 | b >>>= (3); 1501 | k -= (3); 1502 | // } 1503 | } 1504 | 1505 | while (index < 19) { 1506 | blens[border[index++]] = 0; 1507 | } 1508 | 1509 | bb[0] = 7; 1510 | t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); 1511 | if (t != Z_OK) { 1512 | r = t; 1513 | if (r == Z_DATA_ERROR) { 1514 | blens = null; 1515 | mode = BADBLOCKS; 1516 | } 1517 | 1518 | that.bitb = b; 1519 | that.bitk = k; 1520 | z.avail_in = n; 1521 | z.total_in += p - z.next_in_index; 1522 | z.next_in_index = p; 1523 | that.write = q; 1524 | return that.inflate_flush(z, r); 1525 | } 1526 | 1527 | index = 0; 1528 | mode = DTREE; 1529 | case DTREE: 1530 | while (true) { 1531 | t = table; 1532 | if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) { 1533 | break; 1534 | } 1535 | 1536 | var h; 1537 | var j, c; 1538 | 1539 | t = bb[0]; 1540 | 1541 | while (k < (t)) { 1542 | if (n !== 0) { 1543 | r = Z_OK; 1544 | } else { 1545 | that.bitb = b; 1546 | that.bitk = k; 1547 | z.avail_in = n; 1548 | z.total_in += p - z.next_in_index; 1549 | z.next_in_index = p; 1550 | that.write = q; 1551 | return that.inflate_flush(z, r); 1552 | } 1553 | n--; 1554 | b |= (z.read_byte(p++) & 0xff) << k; 1555 | k += 8; 1556 | } 1557 | 1558 | // if (tb[0] == -1) { 1559 | // System.err.println("null..."); 1560 | // } 1561 | 1562 | t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1]; 1563 | c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2]; 1564 | 1565 | if (c < 16) { 1566 | b >>>= (t); 1567 | k -= (t); 1568 | blens[index++] = c; 1569 | } else { // c == 16..18 1570 | i = c == 18 ? 7 : c - 14; 1571 | j = c == 18 ? 11 : 3; 1572 | 1573 | while (k < (t + i)) { 1574 | if (n !== 0) { 1575 | r = Z_OK; 1576 | } else { 1577 | that.bitb = b; 1578 | that.bitk = k; 1579 | z.avail_in = n; 1580 | z.total_in += p - z.next_in_index; 1581 | z.next_in_index = p; 1582 | that.write = q; 1583 | return that.inflate_flush(z, r); 1584 | } 1585 | n--; 1586 | b |= (z.read_byte(p++) & 0xff) << k; 1587 | k += 8; 1588 | } 1589 | 1590 | b >>>= (t); 1591 | k -= (t); 1592 | 1593 | j += (b & inflate_mask[i]); 1594 | 1595 | b >>>= (i); 1596 | k -= (i); 1597 | 1598 | i = index; 1599 | t = table; 1600 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { 1601 | blens = null; 1602 | mode = BADBLOCKS; 1603 | z.msg = "invalid bit length repeat"; 1604 | r = Z_DATA_ERROR; 1605 | 1606 | that.bitb = b; 1607 | that.bitk = k; 1608 | z.avail_in = n; 1609 | z.total_in += p - z.next_in_index; 1610 | z.next_in_index = p; 1611 | that.write = q; 1612 | return that.inflate_flush(z, r); 1613 | } 1614 | 1615 | c = c == 16 ? blens[i - 1] : 0; 1616 | do { 1617 | blens[i++] = c; 1618 | } while (--j !== 0); 1619 | index = i; 1620 | } 1621 | } 1622 | 1623 | tb[0] = -1; 1624 | // { 1625 | var bl_ = []; // new Array(1); 1626 | var bd_ = []; // new Array(1); 1627 | var tl_ = []; // new Array(1); 1628 | var td_ = []; // new Array(1); 1629 | bl_[0] = 9; // must be <= 9 for lookahead assumptions 1630 | bd_[0] = 6; // must be <= 9 for lookahead assumptions 1631 | 1632 | t = table; 1633 | t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z); 1634 | 1635 | if (t != Z_OK) { 1636 | if (t == Z_DATA_ERROR) { 1637 | blens = null; 1638 | mode = BADBLOCKS; 1639 | } 1640 | r = t; 1641 | 1642 | that.bitb = b; 1643 | that.bitk = k; 1644 | z.avail_in = n; 1645 | z.total_in += p - z.next_in_index; 1646 | z.next_in_index = p; 1647 | that.write = q; 1648 | return that.inflate_flush(z, r); 1649 | } 1650 | codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0], z); 1651 | // } 1652 | mode = CODES; 1653 | case CODES: 1654 | that.bitb = b; 1655 | that.bitk = k; 1656 | z.avail_in = n; 1657 | z.total_in += p - z.next_in_index; 1658 | z.next_in_index = p; 1659 | that.write = q; 1660 | 1661 | if ((r = codes.proc(that, z, r)) != Z_STREAM_END) { 1662 | return that.inflate_flush(z, r); 1663 | } 1664 | r = Z_OK; 1665 | codes.free(z); 1666 | 1667 | p = z.next_in_index; 1668 | n = z.avail_in; 1669 | b = that.bitb; 1670 | k = that.bitk; 1671 | q = that.write; 1672 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1673 | 1674 | if (last === 0) { 1675 | mode = TYPE; 1676 | break; 1677 | } 1678 | mode = DRY; 1679 | case DRY: 1680 | that.write = q; 1681 | r = that.inflate_flush(z, r); 1682 | q = that.write; 1683 | m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q); 1684 | if (that.read != that.write) { 1685 | that.bitb = b; 1686 | that.bitk = k; 1687 | z.avail_in = n; 1688 | z.total_in += p - z.next_in_index; 1689 | z.next_in_index = p; 1690 | that.write = q; 1691 | return that.inflate_flush(z, r); 1692 | } 1693 | mode = DONELOCKS; 1694 | case DONELOCKS: 1695 | r = Z_STREAM_END; 1696 | 1697 | that.bitb = b; 1698 | that.bitk = k; 1699 | z.avail_in = n; 1700 | z.total_in += p - z.next_in_index; 1701 | z.next_in_index = p; 1702 | that.write = q; 1703 | return that.inflate_flush(z, r); 1704 | case BADBLOCKS: 1705 | r = Z_DATA_ERROR; 1706 | 1707 | that.bitb = b; 1708 | that.bitk = k; 1709 | z.avail_in = n; 1710 | z.total_in += p - z.next_in_index; 1711 | z.next_in_index = p; 1712 | that.write = q; 1713 | return that.inflate_flush(z, r); 1714 | 1715 | default: 1716 | r = Z_STREAM_ERROR; 1717 | 1718 | that.bitb = b; 1719 | that.bitk = k; 1720 | z.avail_in = n; 1721 | z.total_in += p - z.next_in_index; 1722 | z.next_in_index = p; 1723 | that.write = q; 1724 | return that.inflate_flush(z, r); 1725 | } 1726 | } 1727 | }; 1728 | 1729 | that.free = function(z) { 1730 | that.reset(z, null); 1731 | that.window = null; 1732 | hufts = null; 1733 | // ZFREE(z, s); 1734 | }; 1735 | 1736 | that.set_dictionary = function(d, start, n) { 1737 | that.window.set(d.subarray(start, start + n), 0); 1738 | that.read = that.write = n; 1739 | }; 1740 | 1741 | // Returns true if inflate is currently at the end of a block generated 1742 | // by Z_SYNC_FLUSH or Z_FULL_FLUSH. 1743 | that.sync_point = function() { 1744 | return mode == LENS ? 1 : 0; 1745 | }; 1746 | 1747 | } 1748 | 1749 | // Inflate 1750 | 1751 | // preset dictionary flag in zlib header 1752 | var PRESET_DICT = 0x20; 1753 | 1754 | var Z_DEFLATED = 8; 1755 | 1756 | var METHOD = 0; // waiting for method byte 1757 | var FLAG = 1; // waiting for flag byte 1758 | var DICT4 = 2; // four dictionary check bytes to go 1759 | var DICT3 = 3; // three dictionary check bytes to go 1760 | var DICT2 = 4; // two dictionary check bytes to go 1761 | var DICT1 = 5; // one dictionary check byte to go 1762 | var DICT0 = 6; // waiting for inflateSetDictionary 1763 | var BLOCKS = 7; // decompressing blocks 1764 | var DONE = 12; // finished check, done 1765 | var BAD = 13; // got an error--stay here 1766 | 1767 | var mark = [ 0, 0, 0xff, 0xff ]; 1768 | 1769 | function Inflate() { 1770 | var that = this; 1771 | 1772 | that.mode = 0; // current inflate mode 1773 | 1774 | // mode dependent information 1775 | that.method = 0; // if FLAGS, method byte 1776 | 1777 | // if CHECK, check values to compare 1778 | that.was = [ 0 ]; // new Array(1); // computed check value 1779 | that.need = 0; // stream check value 1780 | 1781 | // if BAD, inflateSync's marker bytes count 1782 | that.marker = 0; 1783 | 1784 | // mode independent information 1785 | that.wbits = 0; // log2(window size) (8..15, defaults to 15) 1786 | 1787 | // this.blocks; // current inflate_blocks state 1788 | 1789 | function inflateReset(z) { 1790 | if (!z || !z.istate) 1791 | return Z_STREAM_ERROR; 1792 | 1793 | z.total_in = z.total_out = 0; 1794 | z.msg = null; 1795 | z.istate.mode = BLOCKS; 1796 | z.istate.blocks.reset(z, null); 1797 | return Z_OK; 1798 | } 1799 | 1800 | that.inflateEnd = function(z) { 1801 | if (that.blocks) 1802 | that.blocks.free(z); 1803 | that.blocks = null; 1804 | // ZFREE(z, z->state); 1805 | return Z_OK; 1806 | }; 1807 | 1808 | that.inflateInit = function(z, w) { 1809 | z.msg = null; 1810 | that.blocks = null; 1811 | 1812 | // set window size 1813 | if (w < 8 || w > 15) { 1814 | that.inflateEnd(z); 1815 | return Z_STREAM_ERROR; 1816 | } 1817 | that.wbits = w; 1818 | 1819 | z.istate.blocks = new InfBlocks(z, 1 << w); 1820 | 1821 | // reset state 1822 | inflateReset(z); 1823 | return Z_OK; 1824 | }; 1825 | 1826 | that.inflate = function(z, f) { 1827 | var r; 1828 | var b; 1829 | 1830 | if (!z || !z.istate || !z.next_in) 1831 | return Z_STREAM_ERROR; 1832 | f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 1833 | r = Z_BUF_ERROR; 1834 | while (true) { 1835 | // System.out.println("mode: "+z.istate.mode); 1836 | switch (z.istate.mode) { 1837 | case METHOD: 1838 | 1839 | if (z.avail_in === 0) 1840 | return r; 1841 | r = f; 1842 | 1843 | z.avail_in--; 1844 | z.total_in++; 1845 | if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) { 1846 | z.istate.mode = BAD; 1847 | z.msg = "unknown compression method"; 1848 | z.istate.marker = 5; // can't try inflateSync 1849 | break; 1850 | } 1851 | if ((z.istate.method >> 4) + 8 > z.istate.wbits) { 1852 | z.istate.mode = BAD; 1853 | z.msg = "invalid window size"; 1854 | z.istate.marker = 5; // can't try inflateSync 1855 | break; 1856 | } 1857 | z.istate.mode = FLAG; 1858 | case FLAG: 1859 | 1860 | if (z.avail_in === 0) 1861 | return r; 1862 | r = f; 1863 | 1864 | z.avail_in--; 1865 | z.total_in++; 1866 | b = (z.read_byte(z.next_in_index++)) & 0xff; 1867 | 1868 | if ((((z.istate.method << 8) + b) % 31) !== 0) { 1869 | z.istate.mode = BAD; 1870 | z.msg = "incorrect header check"; 1871 | z.istate.marker = 5; // can't try inflateSync 1872 | break; 1873 | } 1874 | 1875 | if ((b & PRESET_DICT) === 0) { 1876 | z.istate.mode = BLOCKS; 1877 | break; 1878 | } 1879 | z.istate.mode = DICT4; 1880 | case DICT4: 1881 | 1882 | if (z.avail_in === 0) 1883 | return r; 1884 | r = f; 1885 | 1886 | z.avail_in--; 1887 | z.total_in++; 1888 | z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000; 1889 | z.istate.mode = DICT3; 1890 | case DICT3: 1891 | 1892 | if (z.avail_in === 0) 1893 | return r; 1894 | r = f; 1895 | 1896 | z.avail_in--; 1897 | z.total_in++; 1898 | z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000; 1899 | z.istate.mode = DICT2; 1900 | case DICT2: 1901 | 1902 | if (z.avail_in === 0) 1903 | return r; 1904 | r = f; 1905 | 1906 | z.avail_in--; 1907 | z.total_in++; 1908 | z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00; 1909 | z.istate.mode = DICT1; 1910 | case DICT1: 1911 | 1912 | if (z.avail_in === 0) 1913 | return r; 1914 | r = f; 1915 | 1916 | z.avail_in--; 1917 | z.total_in++; 1918 | z.istate.need += (z.read_byte(z.next_in_index++) & 0xff); 1919 | z.istate.mode = DICT0; 1920 | return Z_NEED_DICT; 1921 | case DICT0: 1922 | z.istate.mode = BAD; 1923 | z.msg = "need dictionary"; 1924 | z.istate.marker = 0; // can try inflateSync 1925 | return Z_STREAM_ERROR; 1926 | case BLOCKS: 1927 | 1928 | r = z.istate.blocks.proc(z, r); 1929 | if (r == Z_DATA_ERROR) { 1930 | z.istate.mode = BAD; 1931 | z.istate.marker = 0; // can try inflateSync 1932 | break; 1933 | } 1934 | if (r == Z_OK) { 1935 | r = f; 1936 | } 1937 | if (r != Z_STREAM_END) { 1938 | return r; 1939 | } 1940 | r = f; 1941 | z.istate.blocks.reset(z, z.istate.was); 1942 | z.istate.mode = DONE; 1943 | case DONE: 1944 | return Z_STREAM_END; 1945 | case BAD: 1946 | return Z_DATA_ERROR; 1947 | default: 1948 | return Z_STREAM_ERROR; 1949 | } 1950 | } 1951 | }; 1952 | 1953 | that.inflateSetDictionary = function(z, dictionary, dictLength) { 1954 | var index = 0; 1955 | var length = dictLength; 1956 | if (!z || !z.istate || z.istate.mode != DICT0) 1957 | return Z_STREAM_ERROR; 1958 | 1959 | if (length >= (1 << z.istate.wbits)) { 1960 | length = (1 << z.istate.wbits) - 1; 1961 | index = dictLength - length; 1962 | } 1963 | z.istate.blocks.set_dictionary(dictionary, index, length); 1964 | z.istate.mode = BLOCKS; 1965 | return Z_OK; 1966 | }; 1967 | 1968 | that.inflateSync = function(z) { 1969 | var n; // number of bytes to look at 1970 | var p; // pointer to bytes 1971 | var m; // number of marker bytes found in a row 1972 | var r, w; // temporaries to save total_in and total_out 1973 | 1974 | // set up 1975 | if (!z || !z.istate) 1976 | return Z_STREAM_ERROR; 1977 | if (z.istate.mode != BAD) { 1978 | z.istate.mode = BAD; 1979 | z.istate.marker = 0; 1980 | } 1981 | if ((n = z.avail_in) === 0) 1982 | return Z_BUF_ERROR; 1983 | p = z.next_in_index; 1984 | m = z.istate.marker; 1985 | 1986 | // search 1987 | while (n !== 0 && m < 4) { 1988 | if (z.read_byte(p) == mark[m]) { 1989 | m++; 1990 | } else if (z.read_byte(p) !== 0) { 1991 | m = 0; 1992 | } else { 1993 | m = 4 - m; 1994 | } 1995 | p++; 1996 | n--; 1997 | } 1998 | 1999 | // restore 2000 | z.total_in += p - z.next_in_index; 2001 | z.next_in_index = p; 2002 | z.avail_in = n; 2003 | z.istate.marker = m; 2004 | 2005 | // return no joy or set up to restart on a new block 2006 | if (m != 4) { 2007 | return Z_DATA_ERROR; 2008 | } 2009 | r = z.total_in; 2010 | w = z.total_out; 2011 | inflateReset(z); 2012 | z.total_in = r; 2013 | z.total_out = w; 2014 | z.istate.mode = BLOCKS; 2015 | return Z_OK; 2016 | }; 2017 | 2018 | // Returns true if inflate is currently at the end of a block generated 2019 | // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 2020 | // implementation to provide an additional safety check. PPP uses 2021 | // Z_SYNC_FLUSH 2022 | // but removes the length bytes of the resulting empty stored block. When 2023 | // decompressing, PPP checks that at the end of input packet, inflate is 2024 | // waiting for these length bytes. 2025 | that.inflateSyncPoint = function(z) { 2026 | if (!z || !z.istate || !z.istate.blocks) 2027 | return Z_STREAM_ERROR; 2028 | return z.istate.blocks.sync_point(); 2029 | }; 2030 | } 2031 | 2032 | // ZStream 2033 | 2034 | function ZStream() { 2035 | } 2036 | 2037 | ZStream.prototype = { 2038 | inflateInit : function(bits) { 2039 | var that = this; 2040 | that.istate = new Inflate(); 2041 | if (!bits) 2042 | bits = MAX_BITS; 2043 | return that.istate.inflateInit(that, bits); 2044 | }, 2045 | 2046 | inflate : function(f) { 2047 | var that = this; 2048 | if (!that.istate) 2049 | return Z_STREAM_ERROR; 2050 | return that.istate.inflate(that, f); 2051 | }, 2052 | 2053 | inflateEnd : function() { 2054 | var that = this; 2055 | if (!that.istate) 2056 | return Z_STREAM_ERROR; 2057 | var ret = that.istate.inflateEnd(that); 2058 | that.istate = null; 2059 | return ret; 2060 | }, 2061 | 2062 | inflateSync : function() { 2063 | var that = this; 2064 | if (!that.istate) 2065 | return Z_STREAM_ERROR; 2066 | return that.istate.inflateSync(that); 2067 | }, 2068 | inflateSetDictionary : function(dictionary, dictLength) { 2069 | var that = this; 2070 | if (!that.istate) 2071 | return Z_STREAM_ERROR; 2072 | return that.istate.inflateSetDictionary(that, dictionary, dictLength); 2073 | }, 2074 | read_byte : function(start) { 2075 | var that = this; 2076 | return that.next_in.subarray(start, start + 1)[0]; 2077 | }, 2078 | read_buf : function(start, size) { 2079 | var that = this; 2080 | return that.next_in.subarray(start, start + size); 2081 | } 2082 | }; 2083 | 2084 | // Inflater 2085 | 2086 | function Inflater() { 2087 | var that = this; 2088 | var z = new ZStream(); 2089 | var bufsize = 512; 2090 | var flush = Z_NO_FLUSH; 2091 | var buf = new Uint8Array(bufsize); 2092 | var nomoreinput = false; 2093 | 2094 | z.inflateInit(); 2095 | z.next_out = buf; 2096 | 2097 | that.append = function(data, onprogress) { 2098 | var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array; 2099 | if (data.length === 0) 2100 | return; 2101 | z.next_in_index = 0; 2102 | z.next_in = data; 2103 | z.avail_in = data.length; 2104 | do { 2105 | z.next_out_index = 0; 2106 | z.avail_out = bufsize; 2107 | if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it 2108 | z.next_in_index = 0; 2109 | nomoreinput = true; 2110 | } 2111 | err = z.inflate(flush); 2112 | if (nomoreinput && (err == Z_BUF_ERROR)) 2113 | return -1; 2114 | if (err != Z_OK && err != Z_STREAM_END) 2115 | throw "inflating: " + z.msg; 2116 | if ((nomoreinput || err == Z_STREAM_END) && (z.avail_out == data.length)) 2117 | return -1; 2118 | if (z.next_out_index) 2119 | if (z.next_out_index == bufsize) 2120 | buffers.push(new Uint8Array(buf)); 2121 | else 2122 | buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index))); 2123 | bufferSize += z.next_out_index; 2124 | if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) { 2125 | onprogress(z.next_in_index); 2126 | lastIndex = z.next_in_index; 2127 | } 2128 | } while (z.avail_in > 0 || z.avail_out === 0); 2129 | array = new Uint8Array(bufferSize); 2130 | buffers.forEach(function(chunk) { 2131 | array.set(chunk, bufferIndex); 2132 | bufferIndex += chunk.length; 2133 | }); 2134 | return array; 2135 | }; 2136 | that.flush = function() { 2137 | z.inflateEnd(); 2138 | }; 2139 | } 2140 | 2141 | var inflater; 2142 | 2143 | if (obj.zip) 2144 | obj.zip.Inflater = Inflater; 2145 | else { 2146 | inflater = new Inflater(); 2147 | obj.addEventListener("message", function(event) { 2148 | var message = event.data; 2149 | 2150 | if (message.append) 2151 | obj.postMessage({ 2152 | onappend : true, 2153 | data : inflater.append(message.data, function(current) { 2154 | obj.postMessage({ 2155 | progress : true, 2156 | current : current 2157 | }); 2158 | }) 2159 | }); 2160 | if (message.flush) { 2161 | inflater.flush(); 2162 | obj.postMessage({ 2163 | onflush : true 2164 | }); 2165 | } 2166 | }, false); 2167 | } 2168 | 2169 | })(this); 2170 | -------------------------------------------------------------------------------- /WebContent/scripts/popup.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Gildas Lormeau 3 | * contact : gildas.lormeau gmail.com 4 | * 5 | * This file is part of ZipTabs. 6 | * 7 | * ZipTabs is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * ZipTabs is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with ZipTabs. If not, see . 19 | */ 20 | 21 | (function(globalObject) { 22 | 23 | var ziptabs = chrome.extension.getBackgroundPage().ziptabs; 24 | 25 | function display(tabs) { 26 | var tempElement = document.createElement("ul"), ulElement = document.getElementById("tabs-list"); 27 | tabs.forEach(function(tab) { 28 | var liElement, cbElement, aElement, favicoElement; 29 | if (tab.url.indexOf("https://chrome.google.com") == 0 || !(tab.url.indexOf("http://") == 0 || tab.url.indexOf("https://") == 0)) 30 | return; 31 | aElement = document.createElement("a"); 32 | favicoElement = document.createElement("img"); 33 | liElement = document.createElement("li"); 34 | cbElement = document.createElement("input"); 35 | progressElement = document.createElement("progress"); 36 | liElement.appendChild(cbElement); 37 | liElement.appendChild(favicoElement); 38 | liElement.appendChild(aElement); 39 | liElement.appendChild(progressElement); 40 | tempElement.appendChild(liElement); 41 | aElement.className = "tabs-tab-title"; 42 | aElement.href = "#"; 43 | aElement.title = tab.title; 44 | aElement.addEventListener("click", function() { 45 | chrome.tabs.update(tab.id, { 46 | selected : true 47 | }); 48 | }, false); 49 | favicoElement.src = tab.favIconUrl ? tab.favIconUrl : "../resources/default-favico.gif"; 50 | favicoElement.className = "tabs-tab-favico"; 51 | liElement.id = "tabs-tab-" + tab.id; 52 | cbElement.type = "checkbox"; 53 | cbElement.title = "select a tab to archive"; 54 | cbElement.checked = true; 55 | aElement.textContent = tab.title; 56 | progressElement.className = "tabs-tab-progress"; 57 | progressElement.hidden = true; 58 | }); 59 | tempElement.id = ulElement.id; 60 | tempElement.className = ulElement.className; 61 | ulElement.parentElement.replaceChild(tempElement, ulElement); 62 | ulElement = tempElement; 63 | } 64 | 65 | globalObject.ziptabs = { 66 | onTabProgress : function(tabId, state, index, max) { 67 | console.log("onTabProgress", tabId, state, index, max); 68 | var progressElement, checkboxElement, titleElement, tabElement = document.getElementById("tabs-tab-" + tabId); 69 | if (tabElement) { 70 | progressElement = tabElement.querySelector("progress"); 71 | checkboxElement = tabElement.querySelector("input[type=checkbox]"); 72 | titleElement = tabElement.querySelector(".tabs-tab-title"); 73 | checkboxElement.checked = false; 74 | if (progressElement.hidden) 75 | progressElement.hidden = false; 76 | // FIXME weird bug : hack to force progress bars to be displayed/hidden 77 | document.getElementById("main").style.height = "auto"; 78 | checkboxElement.disabled = true; 79 | titleElement.className = "tabs-tab-title saving"; 80 | if ((state == 1 || state == 2) && max) { 81 | index = state == 1 ? index : state == 2 ? max + index : 0; 82 | max = max * 2; 83 | progressElement.value = index; 84 | progressElement.max = max; 85 | progressElement.title = "progress: " + Math.floor((index * 100) / max) + "%"; 86 | progressElement.className = "tabs-tab-progress " + (state == 1 ? "pass-one" : state == 2 ? "pass-two" : ""); 87 | } else { 88 | checkboxElement.disabled = false; 89 | titleElement.className = "tabs-tab-title"; 90 | progressElement.hidden = true; 91 | } 92 | } 93 | } 94 | }; 95 | document.getElementById("tabs-open-action").addEventListener("change", function() { 96 | if (ziptabs.idle()) 97 | ziptabs.importTabs(event.target.files[0]); 98 | }, false); 99 | document.getElementById("tabs-zip-action").addEventListener("click", function() { 100 | var selectedIds = [], filename; 101 | Array.prototype.forEach.call(document.querySelectorAll("input[type=checkbox]"), function(inputElement) { 102 | if (inputElement.checked) 103 | selectedIds.push(Number(inputElement.parentElement.id.split("tabs-tab-")[1])); 104 | }); 105 | if (selectedIds.length && ziptabs.idle()) { 106 | filename = prompt("Filename:", "ZipTabs - " + (new Date()).toDateString() + ".zip"); 107 | if (filename) 108 | ziptabs.exportTabs(selectedIds, filename); 109 | } 110 | }, false); 111 | ziptabs.detectSingleFile(function(detected) { 112 | var main = document.getElementById("main"); 113 | if (!detected) { 114 | main.hidden = true; 115 | document.getElementById("error").hidden = false; 116 | } else 117 | chrome.tabs.getAllInWindow(null, function(tabs) { 118 | display(tabs); 119 | ziptabs.refreshPopup(); 120 | main.hidden = false; 121 | }); 122 | }); 123 | 124 | })(window); -------------------------------------------------------------------------------- /WebContent/scripts/zip.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Gildas Lormeau. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution. 13 | 14 | 3. The names of the authors may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, 20 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 23 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | (function(obj) { 30 | 31 | var ERR_BAD_FORMAT = "File format is not recognized."; 32 | var ERR_ENCRYPTED = "File contains encrypted entry."; 33 | var ERR_ZIP64 = "File is using Zip64 (4gb+ file size)."; 34 | var ERR_READ = "Error while reading zip file."; 35 | var ERR_WRITE = "Error while writing zip file."; 36 | var ERR_WRITE_DATA = "Error while writing file data."; 37 | var ERR_READ_DATA = "Error while reading file data."; 38 | var ERR_DUPLICATED_NAME = "File already exists."; 39 | var ERR_HTTP_RANGE = "HTTP Range not supported."; 40 | var CHUNK_SIZE = 512 * 1024; 41 | 42 | var INFLATE_JS = "inflate.js"; 43 | var DEFLATE_JS = "deflate.js"; 44 | 45 | var BlobBuilder = obj.WebKitBlobBuilder || obj.MozBlobBuilder || obj.MSBlobBuilder || obj.BlobBuilder; 46 | 47 | var appendABViewSupported; 48 | 49 | function isAppendABViewSupported() { 50 | if (typeof appendABViewSupported == "undefined") { 51 | var blobBuilder; 52 | blobBuilder = new BlobBuilder(); 53 | blobBuilder.append(getDataHelper(0).view); 54 | appendABViewSupported = blobBuilder.getBlob().size == 0; 55 | } 56 | return appendABViewSupported; 57 | } 58 | 59 | function Crc32() { 60 | var crc = -1, that = this; 61 | that.append = function(data) { 62 | var offset, table = that.table; 63 | for (offset = 0; offset < data.length; offset++) 64 | crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF]; 65 | }; 66 | that.get = function() { 67 | return ~crc; 68 | }; 69 | } 70 | Crc32.prototype.table = (function() { 71 | var i, j, t, table = []; 72 | for (i = 0; i < 256; i++) { 73 | t = i; 74 | for (j = 0; j < 8; j++) 75 | if (t & 1) 76 | t = (t >>> 1) ^ 0xEDB88320; 77 | else 78 | t = t >>> 1; 79 | table[i] = t; 80 | } 81 | return table; 82 | })(); 83 | 84 | function blobSlice(blob, index, length) { 85 | if (blob.slice) 86 | return blob.slice(index, index + length); 87 | else if (blob.webkitSlice) 88 | return blob.webkitSlice(index, index + length); 89 | else if (blob.mozSlice) 90 | return blob.mozSlice(index, index + length); 91 | else if (blob.msSlice) 92 | return blob.msSlice(index, index + length); 93 | } 94 | 95 | function getDataHelper(byteLength, bytes) { 96 | var dataBuffer, dataArray; 97 | dataBuffer = new ArrayBuffer(byteLength); 98 | dataArray = new Uint8Array(dataBuffer); 99 | if (bytes) 100 | dataArray.set(bytes, 0); 101 | return { 102 | buffer : dataBuffer, 103 | array : dataArray, 104 | view : new DataView(dataBuffer) 105 | }; 106 | } 107 | 108 | // Readers 109 | function Reader() { 110 | } 111 | 112 | function TextReader(text) { 113 | var that = this, blobReader; 114 | 115 | function init(callback, onerror) { 116 | var blobBuilder = new BlobBuilder(); 117 | blobBuilder.append(text); 118 | blobReader = new BlobReader(blobBuilder.getBlob("text/plain")); 119 | blobReader.init(function() { 120 | that.size = blobReader.size; 121 | callback(); 122 | }, onerror); 123 | } 124 | 125 | function readUint8Array(index, length, callback, onerror) { 126 | blobReader.readUint8Array(index, length, callback, onerror); 127 | } 128 | 129 | that.size = 0; 130 | that.init = init; 131 | that.readUint8Array = readUint8Array; 132 | } 133 | TextReader.prototype = new Reader(); 134 | TextReader.prototype.constructor = TextReader; 135 | 136 | function Data64URIReader(dataURI) { 137 | var that = this, dataStart; 138 | 139 | function init(callback, onerror) { 140 | var dataEnd = dataURI.length; 141 | while (dataURI.charAt(dataEnd - 1) == "=") 142 | dataEnd--; 143 | dataStart = dataURI.indexOf(",") + 1; 144 | that.size = Math.floor((dataEnd - dataStart) * 0.75); 145 | callback(); 146 | } 147 | 148 | function readUint8Array(index, length, callback, onerror) { 149 | var i, data = getDataHelper(length); 150 | var start = Math.floor(index / 3) * 4; 151 | var end = Math.ceil((index + length) / 3) * 4; 152 | var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart)); 153 | var delta = index - Math.floor(start / 4) * 3; 154 | for (i = delta; i < delta + length; i++) 155 | data.array[i - delta] = bytes.charCodeAt(i); 156 | callback(data.array); 157 | } 158 | 159 | that.size = 0; 160 | that.init = init; 161 | that.readUint8Array = readUint8Array; 162 | } 163 | Data64URIReader.prototype = new Reader(); 164 | Data64URIReader.prototype.constructor = Data64URIReader; 165 | 166 | function BlobReader(blob) { 167 | var that = this; 168 | 169 | function init(callback, onerror) { 170 | this.size = blob.size; 171 | callback(); 172 | } 173 | 174 | function readUint8Array(index, length, callback, onerror) { 175 | var reader = new FileReader(); 176 | reader.onload = function(e) { 177 | callback(new Uint8Array(e.target.result)); 178 | }; 179 | reader.onerror = onerror; 180 | reader.readAsArrayBuffer(blobSlice(blob, index, length)); 181 | } 182 | 183 | that.size = 0; 184 | that.init = init; 185 | that.readUint8Array = readUint8Array; 186 | } 187 | BlobReader.prototype = new Reader(); 188 | BlobReader.prototype.constructor = BlobReader; 189 | 190 | function HttpReader(url) { 191 | var that = this; 192 | 193 | function getData(callback, onerror) { 194 | var request; 195 | if (!that.data) { 196 | request = new XMLHttpRequest(); 197 | request.addEventListener("load", function() { 198 | if (!that.size) 199 | that.size = Number(request.getResponseHeader("Content-Length")); 200 | that.data = new Uint8Array(request.response); 201 | callback(); 202 | }, false); 203 | request.addEventListener("error", onerror, false); 204 | request.open("GET", url); 205 | request.responseType = "arraybuffer"; 206 | request.send(); 207 | } else 208 | callback(); 209 | } 210 | 211 | function init(callback, onerror) { 212 | var request = new XMLHttpRequest(); 213 | request.addEventListener("load", function() { 214 | that.size = Number(request.getResponseHeader("Content-Length")); 215 | callback(); 216 | }, false); 217 | request.addEventListener("error", onerror, false); 218 | request.open("HEAD", url); 219 | request.send(); 220 | } 221 | 222 | function readUint8Array(index, length, callback, onerror) { 223 | getData(function() { 224 | callback(new Uint8Array(that.data.subarray(index, index + length))); 225 | }, onerror); 226 | } 227 | 228 | that.size = 0; 229 | that.init = init; 230 | that.readUint8Array = readUint8Array; 231 | } 232 | HttpReader.prototype = new Reader(); 233 | HttpReader.prototype.constructor = HttpReader; 234 | 235 | function HttpRangeReader(url) { 236 | var that = this; 237 | 238 | function init(callback, onerror) { 239 | var request = new XMLHttpRequest(); 240 | request.addEventListener("load", function() { 241 | that.size = Number(request.getResponseHeader("Content-Length")); 242 | if (request.getResponseHeader("Accept-Ranges") == "bytes") 243 | callback(); 244 | else 245 | onerror(ERR_HTTP_RANGE); 246 | }, false); 247 | request.addEventListener("error", onerror, false); 248 | request.open("HEAD", url); 249 | request.send(); 250 | } 251 | 252 | function readArrayBuffer(index, length, callback, onerror) { 253 | var request = new XMLHttpRequest(); 254 | request.open("GET", url); 255 | request.responseType = "arraybuffer"; 256 | request.setRequestHeader("Range", "bytes=" + index + "-" + (index + length - 1)); 257 | request.addEventListener("load", function() { 258 | callback(request.response); 259 | }, false); 260 | request.addEventListener("error", onerror, false); 261 | request.send(); 262 | } 263 | 264 | function readUint8Array(index, length, callback, onerror) { 265 | readArrayBuffer(index, length, function(arraybuffer) { 266 | callback(new Uint8Array(arraybuffer)); 267 | }, onerror); 268 | } 269 | 270 | that.size = 0; 271 | that.init = init; 272 | that.readUint8Array = readUint8Array; 273 | } 274 | HttpRangeReader.prototype = new Reader(); 275 | HttpRangeReader.prototype.constructor = HttpRangeReader; 276 | 277 | // Writers 278 | 279 | function Writer() { 280 | } 281 | Writer.prototype.getData = function(callback) { 282 | callback(this.data); 283 | }; 284 | 285 | function TextWriter() { 286 | var that = this, blobBuilder; 287 | 288 | function init(callback, onerror) { 289 | blobBuilder = new BlobBuilder(); 290 | callback(); 291 | } 292 | 293 | function writeUint8Array(array, callback, onerror) { 294 | blobBuilder.append(isAppendABViewSupported() ? array : array.buffer); 295 | callback(); 296 | } 297 | 298 | function getData(callback) { 299 | var reader = new FileReader(); 300 | reader.onload = function(e) { 301 | callback(e.target.result); 302 | }; 303 | reader.onerror = onerror; 304 | reader.readAsText(blobBuilder.getBlob("text/plain")); 305 | } 306 | 307 | that.init = init; 308 | that.writeUint8Array = writeUint8Array; 309 | that.getData = getData; 310 | } 311 | TextWriter.prototype = new Writer(); 312 | TextWriter.prototype.constructor = TextWriter; 313 | 314 | function Data64URIWriter(contentType) { 315 | var that = this, data = "", pending = ""; 316 | 317 | function init(callback, onerror) { 318 | data += "data:" + (contentType || "") + ";base64,"; 319 | callback(); 320 | } 321 | 322 | function writeUint8Array(array, callback, onerror) { 323 | var i, delta = pending.length, dataString = pending; 324 | pending = ""; 325 | for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++) 326 | dataString += String.fromCharCode(array[i]); 327 | for (; i < array.length; i++) 328 | pending += String.fromCharCode(array[i]); 329 | if (dataString.length > 2) 330 | data += obj.btoa(dataString); 331 | else 332 | pending = dataString; 333 | callback(); 334 | } 335 | 336 | function getData(callback) { 337 | callback(data + obj.btoa(pending)); 338 | } 339 | 340 | that.init = init; 341 | that.writeUint8Array = writeUint8Array; 342 | that.getData = getData; 343 | } 344 | Data64URIWriter.prototype = new Writer(); 345 | Data64URIWriter.prototype.constructor = Data64URIWriter; 346 | 347 | function FileWriter(fileEntry, contentType) { 348 | var writer, that = this; 349 | 350 | function init(callback, onerror) { 351 | fileEntry.createWriter(function(fileWriter) { 352 | writer = fileWriter; 353 | callback(); 354 | }, onerror); 355 | } 356 | 357 | function writeUint8Array(array, callback, onerror) { 358 | var blobBuilder = new BlobBuilder(); 359 | blobBuilder.append(isAppendABViewSupported() ? array : array.buffer); 360 | writer.onwrite = function() { 361 | writer.onwrite = null; 362 | callback(); 363 | }; 364 | writer.onerror = onerror; 365 | writer.write(blobBuilder.getBlob(contentType)); 366 | } 367 | 368 | function getData(callback) { 369 | fileEntry.file(callback); 370 | } 371 | 372 | that.init = init; 373 | that.writeUint8Array = writeUint8Array; 374 | that.getData = getData; 375 | } 376 | FileWriter.prototype = new Writer(); 377 | FileWriter.prototype.constructor = FileWriter; 378 | 379 | function BlobWriter(contentType) { 380 | var blobBuilder, that = this; 381 | 382 | function init(callback, onerror) { 383 | blobBuilder = new BlobBuilder(); 384 | callback(); 385 | } 386 | 387 | function writeUint8Array(array, callback, onerror) { 388 | blobBuilder.append(isAppendABViewSupported() ? array : array.buffer); 389 | callback(); 390 | } 391 | 392 | function getData(callback) { 393 | callback(blobBuilder.getBlob(contentType)); 394 | } 395 | 396 | that.init = init; 397 | that.writeUint8Array = writeUint8Array; 398 | that.getData = getData; 399 | } 400 | BlobWriter.prototype = new Writer(); 401 | BlobWriter.prototype.constructor = BlobWriter; 402 | 403 | // inflate/deflate core functions 404 | 405 | function launchWorkerProcess(worker, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { 406 | var chunkIndex = 0, index, outputSize; 407 | 408 | function onflush() { 409 | worker.removeEventListener("message", onmessage, false); 410 | onend(outputSize); 411 | } 412 | 413 | function onmessage(event) { 414 | var message = event.data, data = message.data; 415 | 416 | if (message.onappend) { 417 | outputSize += data.length; 418 | writer.writeUint8Array(data, function() { 419 | onappend(false, data); 420 | step(); 421 | }, onwriteerror); 422 | } 423 | if (message.onflush) 424 | if (data) { 425 | outputSize += data.length; 426 | writer.writeUint8Array(data, function() { 427 | onappend(false, data); 428 | onflush(); 429 | }, onwriteerror); 430 | } else 431 | onflush(); 432 | if (message.progress && onprogress) 433 | onprogress(index + message.current, size); 434 | } 435 | 436 | function step() { 437 | index = chunkIndex * CHUNK_SIZE; 438 | if (index < size) 439 | reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { 440 | worker.postMessage({ 441 | append : true, 442 | data : array 443 | }); 444 | chunkIndex++; 445 | if (onprogress) 446 | onprogress(index, size); 447 | onappend(true, array); 448 | }, onreaderror); 449 | else 450 | worker.postMessage({ 451 | flush : true 452 | }); 453 | } 454 | 455 | outputSize = 0; 456 | worker.addEventListener("message", onmessage, false); 457 | step(); 458 | } 459 | 460 | function launchProcess(process, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) { 461 | var chunkIndex = 0, index, outputSize = 0; 462 | 463 | function step() { 464 | var outputData; 465 | index = chunkIndex * CHUNK_SIZE; 466 | if (index < size) 467 | reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) { 468 | var outputData = process.append(inputData, function() { 469 | if (onprogress) 470 | onprogress(offset + index, size); 471 | }); 472 | outputSize += outputData.length; 473 | onappend(true, inputData); 474 | writer.writeUint8Array(outputData, function() { 475 | onappend(false, outputData); 476 | chunkIndex++; 477 | setTimeout(step, 1); 478 | }, onwriteerror); 479 | if (onprogress) 480 | onprogress(index, size); 481 | }, onreaderror); 482 | else { 483 | outputData = process.flush(); 484 | if (outputData) { 485 | outputSize += outputData.length; 486 | writer.writeUint8Array(outputData, function() { 487 | onappend(false, outputData); 488 | onend(outputSize); 489 | }, onwriteerror); 490 | } else 491 | onend(outputSize); 492 | } 493 | } 494 | 495 | step(); 496 | } 497 | 498 | function inflate(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { 499 | var worker, crc32 = new Crc32(); 500 | 501 | function oninflateappend(sending, array) { 502 | if (computeCrc32 && !sending) 503 | crc32.append(array); 504 | } 505 | 506 | function oninflateend(outputSize) { 507 | onend(outputSize, crc32.get()); 508 | } 509 | 510 | if (obj.zip.useWebWorkers) { 511 | worker = new Worker(obj.zip.workerScriptsPath + INFLATE_JS); 512 | launchWorkerProcess(worker, reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); 513 | } else 514 | launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror); 515 | return worker; 516 | } 517 | 518 | function deflate(reader, writer, level, onend, onprogress, onreaderror, onwriteerror) { 519 | var worker, crc32 = new Crc32(); 520 | 521 | function ondeflateappend(sending, array) { 522 | if (sending) 523 | crc32.append(array); 524 | } 525 | 526 | function ondeflateend(outputSize) { 527 | onend(outputSize, crc32.get()); 528 | } 529 | 530 | function onmessage() { 531 | worker.removeEventListener("message", onmessage, false); 532 | launchWorkerProcess(worker, reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); 533 | } 534 | 535 | if (obj.zip.useWebWorkers) { 536 | worker = new Worker(obj.zip.workerScriptsPath + DEFLATE_JS); 537 | worker.addEventListener("message", onmessage, false); 538 | worker.postMessage({ 539 | init : true, 540 | level : level 541 | }); 542 | } else 543 | launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror); 544 | return worker; 545 | } 546 | 547 | function copy(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { 548 | var chunkIndex = 0, crc32 = new Crc32(); 549 | 550 | function step() { 551 | var index = chunkIndex * CHUNK_SIZE; 552 | if (index < size) 553 | reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) { 554 | if (computeCrc32) 555 | crc32.append(array); 556 | if (onprogress) 557 | onprogress(index, size, array); 558 | writer.writeUint8Array(array, function() { 559 | chunkIndex++; 560 | step(); 561 | }, onwriteerror); 562 | }, onreaderror); 563 | else 564 | onend(size, crc32.get()); 565 | } 566 | 567 | step(); 568 | } 569 | 570 | // ZipReader 571 | 572 | function decodeASCII(str) { 573 | var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', 574 | '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', 575 | '\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', 576 | '\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6', 577 | '\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3', 578 | '\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE', 579 | '\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE', 580 | '\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7', 581 | '\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ]; 582 | for (i = 0; i < str.length; i++) { 583 | charCode = str.charCodeAt(i) & 0xFF; 584 | if (charCode > 127) 585 | out += extendedASCII[charCode - 128]; 586 | else 587 | out += String.fromCharCode(charCode); 588 | } 589 | return out; 590 | } 591 | 592 | function decodeUTF8(str_data) { 593 | var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0; 594 | 595 | str_data += ''; 596 | 597 | while (i < str_data.length) { 598 | c1 = str_data.charCodeAt(i); 599 | if (c1 < 128) { 600 | tmp_arr[ac++] = String.fromCharCode(c1); 601 | i++; 602 | } else if (c1 > 191 && c1 < 224) { 603 | c2 = str_data.charCodeAt(i + 1); 604 | tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); 605 | i += 2; 606 | } else { 607 | c2 = str_data.charCodeAt(i + 1); 608 | c3 = str_data.charCodeAt(i + 2); 609 | tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 610 | i += 3; 611 | } 612 | } 613 | 614 | return tmp_arr.join(''); 615 | } 616 | 617 | function getString(bytes) { 618 | var i, str = ""; 619 | for (i = 0; i < bytes.length; i++) 620 | str += String.fromCharCode(bytes[i]); 621 | return str; 622 | } 623 | 624 | function getDate(timeRaw) { 625 | var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff; 626 | try { 627 | return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, 628 | (time & 0x001F) * 2, 0); 629 | } catch (e) { 630 | } 631 | } 632 | 633 | function readCommonHeader(entry, data, index, centralDirectory, onerror) { 634 | entry.version = data.view.getUint16(index, true); 635 | entry.bitFlag = data.view.getUint16(index + 2, true); 636 | entry.compressionMethod = data.view.getUint16(index + 4, true); 637 | entry.lastModDateRaw = data.view.getUint32(index + 6, true); 638 | entry.lastModDate = getDate(entry.lastModDateRaw); 639 | if ((entry.bitFlag & 0x01) === 0x01) { 640 | onerror(ERR_ENCRYPTED); 641 | return; 642 | } 643 | if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) { 644 | entry.crc32 = data.view.getUint32(index + 10, true); 645 | entry.compressedSize = data.view.getUint32(index + 14, true); 646 | entry.uncompressedSize = data.view.getUint32(index + 18, true); 647 | } 648 | if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) { 649 | onerror(ERR_ZIP64); 650 | return; 651 | } 652 | entry.filenameLength = data.view.getUint16(index + 22, true); 653 | entry.extraFieldLength = data.view.getUint16(index + 24, true); 654 | } 655 | 656 | function createZipReader(reader, onerror) { 657 | function Entry() { 658 | } 659 | 660 | Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) { 661 | var that = this, worker; 662 | 663 | function terminate(callback, param) { 664 | if (worker) 665 | worker.terminate(); 666 | worker = null; 667 | if (callback) 668 | callback(param); 669 | } 670 | 671 | function testCrc32(crc32) { 672 | var dataCrc32 = getDataHelper(4); 673 | dataCrc32.view.setUint32(0, crc32); 674 | return that.crc32 == dataCrc32.view.getUint32(0); 675 | } 676 | 677 | function getWriterData(uncompressedSize, crc32) { 678 | if (checkCrc32 && !testCrc32(crc32)) 679 | onreaderror(); 680 | else 681 | writer.getData(function(data) { 682 | terminate(onend, data); 683 | }); 684 | } 685 | 686 | function onreaderror() { 687 | terminate(onerror, ERR_READ_DATA); 688 | } 689 | 690 | function onwriteerror() { 691 | terminate(onerror, ERR_WRITE_DATA); 692 | } 693 | 694 | reader.readUint8Array(that.offset, 30, function(bytes) { 695 | var data = getDataHelper(bytes.length, bytes), dataOffset; 696 | if (data.view.getUint32(0) != 0x504b0304) { 697 | onerror(ERR_BAD_FORMAT); 698 | return; 699 | } 700 | readCommonHeader(that, data, 4, false, function(error) { 701 | onerror(error); 702 | return; 703 | }); 704 | dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength; 705 | writer.init(function() { 706 | if (that.compressionMethod === 0) 707 | copy(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); 708 | else 709 | worker = inflate(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); 710 | }, onwriteerror); 711 | }, onreaderror); 712 | }; 713 | 714 | function seekEOCDR(offset, entriesCallback) { 715 | reader.readUint8Array(reader.size - offset, offset, function(bytes) { 716 | var dataView = getDataHelper(bytes.length, bytes).view, datalength, fileslength; 717 | if (dataView.getUint32(0) != 0x504b0506) { 718 | seekEOCDR(offset+1, entriesCallback); 719 | } else { 720 | entriesCallback(dataView); 721 | } 722 | }, function() { 723 | onerror(ERR_READ); 724 | }); 725 | } 726 | 727 | return { 728 | getEntries : function(callback) { 729 | if (reader.size < 22) { 730 | onerror(ERR_BAD_FORMAT); 731 | return; 732 | } 733 | // look for End of central directory record 734 | seekEOCDR(22, function(dataView) { 735 | datalength = dataView.getUint32(16, true); 736 | fileslength = dataView.getUint16(8, true); 737 | reader.readUint8Array(datalength, reader.size - datalength, function(bytes) { 738 | var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes); 739 | for (i = 0; i < fileslength; i++) { 740 | entry = new Entry(); 741 | if (data.view.getUint32(index) != 0x504b0102) { 742 | onerror(ERR_BAD_FORMAT); 743 | return; 744 | } 745 | readCommonHeader(entry, data, index + 6, true, function(error) { 746 | onerror(error); 747 | return; 748 | }); 749 | entry.commentLength = data.view.getUint16(index + 32, true); 750 | entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10); 751 | entry.offset = data.view.getUint32(index + 42, true); 752 | filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength)); 753 | entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename); 754 | if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/") 755 | entry.directory = true; 756 | comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46 757 | + entry.filenameLength + entry.extraFieldLength + entry.commentLength)); 758 | entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment); 759 | entries.push(entry); 760 | index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength; 761 | } 762 | callback(entries); 763 | }, function() { 764 | onerror(ERR_READ); 765 | }); 766 | }); 767 | }, 768 | close : function(callback) { 769 | if (callback) 770 | callback(); 771 | } 772 | }; 773 | } 774 | 775 | // ZipWriter 776 | 777 | function encodeUTF8(string) { 778 | var n, c1, enc, utftext = [], start = 0, end = 0, stringl = string.length; 779 | for (n = 0; n < stringl; n++) { 780 | c1 = string.charCodeAt(n); 781 | enc = null; 782 | if (c1 < 128) 783 | end++; 784 | else if (c1 > 127 && c1 < 2048) 785 | enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128); 786 | else 787 | enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128); 788 | if (enc != null) { 789 | if (end > start) 790 | utftext += string.slice(start, end); 791 | utftext += enc; 792 | start = end = n + 1; 793 | } 794 | } 795 | if (end > start) 796 | utftext += string.slice(start, stringl); 797 | return utftext; 798 | } 799 | 800 | function getBytes(str) { 801 | var i, array = []; 802 | for (i = 0; i < str.length; i++) 803 | array.push(str.charCodeAt(i)); 804 | return array; 805 | } 806 | 807 | function createZipWriter(writer, onerror, dontDeflate) { 808 | var worker, files = [], filenames = [], datalength = 0; 809 | 810 | function terminate(callback, message) { 811 | if (worker) 812 | worker.terminate(); 813 | worker = null; 814 | if (callback) 815 | callback(message); 816 | } 817 | 818 | function onwriteerror() { 819 | terminate(onerror, ERR_WRITE); 820 | } 821 | 822 | function onreaderror() { 823 | terminate(onerror, ERR_READ_DATA); 824 | } 825 | 826 | return { 827 | add : function(name, reader, onend, onprogress, options) { 828 | var header, filename, date; 829 | 830 | function writeHeader(callback) { 831 | var data; 832 | date = options.lastModDate || new Date(); 833 | header = getDataHelper(26); 834 | files[name] = { 835 | headerArray : header.array, 836 | directory : options.directory, 837 | filename : filename, 838 | offset : datalength, 839 | comment : getBytes(encodeUTF8(options.comment || "")) 840 | }; 841 | header.view.setUint32(0, 0x14000808); 842 | if (options.version) 843 | header.view.setUint8(0, options.version); 844 | if (!dontDeflate && options.level != 0) 845 | header.view.setUint16(4, 0x0800); 846 | header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true); 847 | header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true); 848 | header.view.setUint16(22, filename.length, true); 849 | data = getDataHelper(30 + filename.length); 850 | data.view.setUint32(0, 0x504b0304); 851 | data.array.set(header.array, 4); 852 | data.array.set([], 30); // FIXME: remove when chrome 18 will be stable (14: OK, 16: KO, 17: OK) 853 | data.array.set(filename, 30); 854 | datalength += data.array.length; 855 | writer.writeUint8Array(data.array, callback, onwriteerror); 856 | } 857 | 858 | function writeFooter(compressedLength, crc32) { 859 | var footer = getDataHelper(16); 860 | datalength += compressedLength || 0; 861 | footer.view.setUint32(0, 0x504b0708); 862 | if (typeof crc32 != "undefined") { 863 | header.view.setUint32(10, crc32, true); 864 | footer.view.setUint32(4, crc32, true); 865 | } 866 | if (reader) { 867 | footer.view.setUint32(8, compressedLength, true); 868 | header.view.setUint32(14, compressedLength, true); 869 | footer.view.setUint32(12, reader.size, true); 870 | header.view.setUint32(18, reader.size, true); 871 | } 872 | writer.writeUint8Array(footer.array, function() { 873 | datalength += 16; 874 | terminate(onend); 875 | }, onwriteerror); 876 | } 877 | 878 | function writeFile() { 879 | options = options || {}; 880 | name = name.trim(); 881 | if (options.directory && name.charAt(name.length - 1) != "/") 882 | name += "/"; 883 | if (files[name]) 884 | throw ERR_DUPLICATED_NAME; 885 | filename = getBytes(encodeUTF8(name)); 886 | filenames.push(name); 887 | writeHeader(function() { 888 | if (reader) 889 | if (dontDeflate || options.level == 0) 890 | copy(reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror); 891 | else 892 | worker = deflate(reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror); 893 | else 894 | writeFooter(); 895 | }, onwriteerror); 896 | } 897 | 898 | if (reader) 899 | reader.init(writeFile, onreaderror); 900 | else 901 | writeFile(); 902 | }, 903 | close : function(callback) { 904 | var data, length = 0, index = 0; 905 | filenames.forEach(function(name) { 906 | var file = files[name]; 907 | length += 46 + file.filename.length + file.comment.length; 908 | }); 909 | data = getDataHelper(length + 22); 910 | filenames.forEach(function(name) { 911 | var file = files[name]; 912 | data.view.setUint32(index, 0x504b0102); 913 | data.view.setUint16(index + 4, 0x1400); 914 | data.array.set(file.headerArray, index + 6); 915 | data.view.setUint16(index + 32, file.comment.length, true); 916 | if (file.directory) 917 | data.view.setUint8(index + 38, 0x10); 918 | data.view.setUint32(index + 42, file.offset, true); 919 | data.array.set(file.filename, index + 46); 920 | data.array.set(file.comment, index + 46 + file.filename.length); 921 | index += 46 + file.filename.length + file.comment.length; 922 | }); 923 | data.view.setUint32(index, 0x504b0506); 924 | data.view.setUint16(index + 8, filenames.length, true); 925 | data.view.setUint16(index + 10, filenames.length, true); 926 | data.view.setUint32(index + 12, length, true); 927 | data.view.setUint32(index + 16, datalength, true); 928 | writer.writeUint8Array(data.array, function() { 929 | terminate(function() { 930 | writer.getData(callback); 931 | }); 932 | }, onwriteerror); 933 | } 934 | }; 935 | } 936 | 937 | if (typeof BlobBuilder == "undefined") { 938 | BlobBuilder = function() { 939 | var that = this, blobParts; 940 | 941 | function initBlobParts() { 942 | if (!blobParts) { 943 | blobParts = [ new Blob() ]; 944 | } 945 | } 946 | 947 | that.append = function(data) { 948 | initBlobParts(); 949 | blobParts.push(data); 950 | }; 951 | that.getBlob = function(contentType) { 952 | initBlobParts(); 953 | if (blobParts.length > 1 || blobParts[0].type != contentType) { 954 | blobParts = [ contentType ? new Blob(blobParts, { 955 | type : contentType 956 | }) : new Blob(blobParts) ]; 957 | } 958 | return blobParts[0]; 959 | }; 960 | }; 961 | } 962 | 963 | obj.zip = { 964 | Reader : Reader, 965 | Writer : Writer, 966 | BlobReader : BlobReader, 967 | HttpReader : HttpReader, 968 | HttpRangeReader : HttpRangeReader, 969 | Data64URIReader : Data64URIReader, 970 | TextReader : TextReader, 971 | BlobWriter : BlobWriter, 972 | FileWriter : FileWriter, 973 | Data64URIWriter : Data64URIWriter, 974 | TextWriter : TextWriter, 975 | createReader : function(reader, callback, onerror) { 976 | reader.init(function() { 977 | callback(createZipReader(reader, onerror)); 978 | }, onerror); 979 | }, 980 | createWriter : function(writer, callback, onerror, dontDeflate) { 981 | writer.init(function() { 982 | callback(createZipWriter(writer, onerror, dontDeflate)); 983 | }, onerror); 984 | }, 985 | workerScriptsPath : "", 986 | useWebWorkers : true 987 | }; 988 | 989 | })(this); 990 | --------------------------------------------------------------------------------