From f210ef42ea19b0778c84b544e4b297b4e3193d1a Mon Sep 17 00:00:00 2001
From: ange
Date: Sun, 3 Jun 2018 15:25:33 +0200
Subject: [PATCH 01/19] created branch xpplannot
---
app/static/css/style.css | 8 ++++++
app/templates/annotations.html | 42 +++++++++++++++++++++++++++++
app/templates/show_book_detail.html | 4 +++
app/views.py | 4 +++
4 files changed, 58 insertions(+)
create mode 100644 app/templates/annotations.html
diff --git a/app/static/css/style.css b/app/static/css/style.css
index 2e26275..4a6588f 100755
--- a/app/static/css/style.css
+++ b/app/static/css/style.css
@@ -196,6 +196,14 @@ font-size: 12px;
background-color: yellow;
}
+#annotindication{
+ width: 30%;
+ margin: 0;
+ padding: 3px;
+ font-size: 14px;
+ background-color: red;
+}
+
div.marquee {
white-space:no-wrap;
overflow:hidden;
diff --git a/app/templates/annotations.html b/app/templates/annotations.html
new file mode 100644
index 0000000..6088203
--- /dev/null
+++ b/app/templates/annotations.html
@@ -0,0 +1,42 @@
+
+{% block main %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
+
+
+
+
+
+
+
+
diff --git a/app/templates/show_book_detail.html b/app/templates/show_book_detail.html
index 42cd67d..4724d36 100755
--- a/app/templates/show_book_detail.html
+++ b/app/templates/show_book_detail.html
@@ -20,6 +20,10 @@
{% endfor %}
download {{ book.fileformat }}
+
+
+ --> Feel free to annotate
+
edit
diff --git a/app/views.py b/app/views.py
index da6ee43..1858a74 100755
--- a/app/views.py
+++ b/app/views.py
@@ -338,6 +338,10 @@ def send_text_file(file_name):
file_dot_text = file_name + '.txt'
return app.send_static_file(file_dot_text)
+@app.route('/annotations')
+def annotations():
+ """Render annotations page."""
+ return render_template('annotations.html')
@app.after_request
def add_header(response):
From 1ee3996ea748ed1895e089aa757c78fe76d2a943 Mon Sep 17 00:00:00 2001
From: ange
Date: Wed, 6 Jun 2018 18:54:07 +0200
Subject: [PATCH 02/19] viewer pdf
---
app/getannot.py | 29 +
app/static/viewer/LICENSE | 177 +
app/static/viewer/build/pdf.js | 8011 ++++
app/static/viewer/build/pdf.worker.js | 39321 ++++++++++++++++
app/static/viewer/web/cmaps/78-EUC-H.bcmap | Bin 0 -> 2404 bytes
app/static/viewer/web/cmaps/78-EUC-V.bcmap | Bin 0 -> 173 bytes
app/static/viewer/web/cmaps/78-H.bcmap | Bin 0 -> 2379 bytes
app/static/viewer/web/cmaps/78-RKSJ-H.bcmap | Bin 0 -> 2398 bytes
app/static/viewer/web/cmaps/78-RKSJ-V.bcmap | Bin 0 -> 173 bytes
app/static/viewer/web/cmaps/78-V.bcmap | Bin 0 -> 169 bytes
app/static/viewer/web/cmaps/78ms-RKSJ-H.bcmap | Bin 0 -> 2651 bytes
app/static/viewer/web/cmaps/78ms-RKSJ-V.bcmap | Bin 0 -> 290 bytes
app/static/viewer/web/cmaps/83pv-RKSJ-H.bcmap | Bin 0 -> 905 bytes
app/static/viewer/web/cmaps/90ms-RKSJ-H.bcmap | Bin 0 -> 721 bytes
app/static/viewer/web/cmaps/90ms-RKSJ-V.bcmap | Bin 0 -> 290 bytes
.../viewer/web/cmaps/90msp-RKSJ-H.bcmap | Bin 0 -> 715 bytes
.../viewer/web/cmaps/90msp-RKSJ-V.bcmap | Bin 0 -> 291 bytes
app/static/viewer/web/cmaps/90pv-RKSJ-H.bcmap | Bin 0 -> 982 bytes
app/static/viewer/web/cmaps/90pv-RKSJ-V.bcmap | Bin 0 -> 260 bytes
app/static/viewer/web/cmaps/Add-H.bcmap | Bin 0 -> 2419 bytes
app/static/viewer/web/cmaps/Add-RKSJ-H.bcmap | Bin 0 -> 2413 bytes
app/static/viewer/web/cmaps/Add-RKSJ-V.bcmap | Bin 0 -> 287 bytes
app/static/viewer/web/cmaps/Add-V.bcmap | Bin 0 -> 282 bytes
.../viewer/web/cmaps/Adobe-CNS1-0.bcmap | Bin 0 -> 317 bytes
.../viewer/web/cmaps/Adobe-CNS1-1.bcmap | Bin 0 -> 371 bytes
.../viewer/web/cmaps/Adobe-CNS1-2.bcmap | Bin 0 -> 376 bytes
.../viewer/web/cmaps/Adobe-CNS1-3.bcmap | Bin 0 -> 401 bytes
.../viewer/web/cmaps/Adobe-CNS1-4.bcmap | Bin 0 -> 405 bytes
.../viewer/web/cmaps/Adobe-CNS1-5.bcmap | Bin 0 -> 406 bytes
.../viewer/web/cmaps/Adobe-CNS1-6.bcmap | Bin 0 -> 406 bytes
.../viewer/web/cmaps/Adobe-CNS1-UCS2.bcmap | Bin 0 -> 41193 bytes
app/static/viewer/web/cmaps/Adobe-GB1-0.bcmap | Bin 0 -> 217 bytes
app/static/viewer/web/cmaps/Adobe-GB1-1.bcmap | Bin 0 -> 250 bytes
app/static/viewer/web/cmaps/Adobe-GB1-2.bcmap | Bin 0 -> 465 bytes
app/static/viewer/web/cmaps/Adobe-GB1-3.bcmap | Bin 0 -> 470 bytes
app/static/viewer/web/cmaps/Adobe-GB1-4.bcmap | Bin 0 -> 601 bytes
app/static/viewer/web/cmaps/Adobe-GB1-5.bcmap | Bin 0 -> 625 bytes
.../viewer/web/cmaps/Adobe-GB1-UCS2.bcmap | Bin 0 -> 33974 bytes
.../viewer/web/cmaps/Adobe-Japan1-0.bcmap | Bin 0 -> 225 bytes
.../viewer/web/cmaps/Adobe-Japan1-1.bcmap | Bin 0 -> 226 bytes
.../viewer/web/cmaps/Adobe-Japan1-2.bcmap | Bin 0 -> 233 bytes
.../viewer/web/cmaps/Adobe-Japan1-3.bcmap | Bin 0 -> 242 bytes
.../viewer/web/cmaps/Adobe-Japan1-4.bcmap | Bin 0 -> 337 bytes
.../viewer/web/cmaps/Adobe-Japan1-5.bcmap | Bin 0 -> 430 bytes
.../viewer/web/cmaps/Adobe-Japan1-6.bcmap | Bin 0 -> 485 bytes
.../viewer/web/cmaps/Adobe-Japan1-UCS2.bcmap | Bin 0 -> 40951 bytes
.../viewer/web/cmaps/Adobe-Korea1-0.bcmap | Bin 0 -> 241 bytes
.../viewer/web/cmaps/Adobe-Korea1-1.bcmap | Bin 0 -> 386 bytes
.../viewer/web/cmaps/Adobe-Korea1-2.bcmap | Bin 0 -> 391 bytes
.../viewer/web/cmaps/Adobe-Korea1-UCS2.bcmap | Bin 0 -> 23293 bytes
app/static/viewer/web/cmaps/B5-H.bcmap | Bin 0 -> 1086 bytes
app/static/viewer/web/cmaps/B5-V.bcmap | Bin 0 -> 142 bytes
app/static/viewer/web/cmaps/B5pc-H.bcmap | Bin 0 -> 1099 bytes
app/static/viewer/web/cmaps/B5pc-V.bcmap | Bin 0 -> 144 bytes
app/static/viewer/web/cmaps/CNS-EUC-H.bcmap | Bin 0 -> 1780 bytes
app/static/viewer/web/cmaps/CNS-EUC-V.bcmap | Bin 0 -> 1920 bytes
app/static/viewer/web/cmaps/CNS1-H.bcmap | Bin 0 -> 706 bytes
app/static/viewer/web/cmaps/CNS1-V.bcmap | Bin 0 -> 143 bytes
app/static/viewer/web/cmaps/CNS2-H.bcmap | Bin 0 -> 504 bytes
app/static/viewer/web/cmaps/CNS2-V.bcmap | 3 +
app/static/viewer/web/cmaps/ETHK-B5-H.bcmap | Bin 0 -> 4426 bytes
app/static/viewer/web/cmaps/ETHK-B5-V.bcmap | Bin 0 -> 158 bytes
app/static/viewer/web/cmaps/ETen-B5-H.bcmap | Bin 0 -> 1125 bytes
app/static/viewer/web/cmaps/ETen-B5-V.bcmap | Bin 0 -> 158 bytes
app/static/viewer/web/cmaps/ETenms-B5-H.bcmap | 3 +
app/static/viewer/web/cmaps/ETenms-B5-V.bcmap | Bin 0 -> 172 bytes
app/static/viewer/web/cmaps/EUC-H.bcmap | Bin 0 -> 578 bytes
app/static/viewer/web/cmaps/EUC-V.bcmap | Bin 0 -> 170 bytes
app/static/viewer/web/cmaps/Ext-H.bcmap | Bin 0 -> 2536 bytes
app/static/viewer/web/cmaps/Ext-RKSJ-H.bcmap | Bin 0 -> 2542 bytes
app/static/viewer/web/cmaps/Ext-RKSJ-V.bcmap | Bin 0 -> 218 bytes
app/static/viewer/web/cmaps/Ext-V.bcmap | Bin 0 -> 215 bytes
app/static/viewer/web/cmaps/GB-EUC-H.bcmap | Bin 0 -> 549 bytes
app/static/viewer/web/cmaps/GB-EUC-V.bcmap | Bin 0 -> 179 bytes
app/static/viewer/web/cmaps/GB-H.bcmap | 4 +
app/static/viewer/web/cmaps/GB-V.bcmap | Bin 0 -> 175 bytes
app/static/viewer/web/cmaps/GBK-EUC-H.bcmap | Bin 0 -> 14692 bytes
app/static/viewer/web/cmaps/GBK-EUC-V.bcmap | Bin 0 -> 180 bytes
app/static/viewer/web/cmaps/GBK2K-H.bcmap | Bin 0 -> 19662 bytes
app/static/viewer/web/cmaps/GBK2K-V.bcmap | Bin 0 -> 219 bytes
app/static/viewer/web/cmaps/GBKp-EUC-H.bcmap | Bin 0 -> 14686 bytes
app/static/viewer/web/cmaps/GBKp-EUC-V.bcmap | Bin 0 -> 181 bytes
app/static/viewer/web/cmaps/GBT-EUC-H.bcmap | Bin 0 -> 7290 bytes
app/static/viewer/web/cmaps/GBT-EUC-V.bcmap | Bin 0 -> 180 bytes
app/static/viewer/web/cmaps/GBT-H.bcmap | Bin 0 -> 7269 bytes
app/static/viewer/web/cmaps/GBT-V.bcmap | Bin 0 -> 176 bytes
app/static/viewer/web/cmaps/GBTpc-EUC-H.bcmap | Bin 0 -> 7298 bytes
app/static/viewer/web/cmaps/GBTpc-EUC-V.bcmap | Bin 0 -> 182 bytes
app/static/viewer/web/cmaps/GBpc-EUC-H.bcmap | Bin 0 -> 557 bytes
app/static/viewer/web/cmaps/GBpc-EUC-V.bcmap | Bin 0 -> 181 bytes
app/static/viewer/web/cmaps/H.bcmap | Bin 0 -> 553 bytes
app/static/viewer/web/cmaps/HKdla-B5-H.bcmap | Bin 0 -> 2654 bytes
app/static/viewer/web/cmaps/HKdla-B5-V.bcmap | Bin 0 -> 148 bytes
app/static/viewer/web/cmaps/HKdlb-B5-H.bcmap | Bin 0 -> 2414 bytes
app/static/viewer/web/cmaps/HKdlb-B5-V.bcmap | Bin 0 -> 148 bytes
app/static/viewer/web/cmaps/HKgccs-B5-H.bcmap | Bin 0 -> 2292 bytes
app/static/viewer/web/cmaps/HKgccs-B5-V.bcmap | Bin 0 -> 149 bytes
app/static/viewer/web/cmaps/HKm314-B5-H.bcmap | Bin 0 -> 1772 bytes
app/static/viewer/web/cmaps/HKm314-B5-V.bcmap | Bin 0 -> 149 bytes
app/static/viewer/web/cmaps/HKm471-B5-H.bcmap | Bin 0 -> 2171 bytes
app/static/viewer/web/cmaps/HKm471-B5-V.bcmap | Bin 0 -> 149 bytes
app/static/viewer/web/cmaps/HKscs-B5-H.bcmap | Bin 0 -> 4437 bytes
app/static/viewer/web/cmaps/HKscs-B5-V.bcmap | Bin 0 -> 159 bytes
app/static/viewer/web/cmaps/Hankaku.bcmap | Bin 0 -> 132 bytes
app/static/viewer/web/cmaps/Hiragana.bcmap | Bin 0 -> 124 bytes
app/static/viewer/web/cmaps/KSC-EUC-H.bcmap | Bin 0 -> 1848 bytes
app/static/viewer/web/cmaps/KSC-EUC-V.bcmap | Bin 0 -> 164 bytes
app/static/viewer/web/cmaps/KSC-H.bcmap | Bin 0 -> 1831 bytes
app/static/viewer/web/cmaps/KSC-Johab-H.bcmap | Bin 0 -> 16791 bytes
app/static/viewer/web/cmaps/KSC-Johab-V.bcmap | Bin 0 -> 166 bytes
app/static/viewer/web/cmaps/KSC-V.bcmap | Bin 0 -> 160 bytes
app/static/viewer/web/cmaps/KSCms-UHC-H.bcmap | Bin 0 -> 2787 bytes
.../viewer/web/cmaps/KSCms-UHC-HW-H.bcmap | Bin 0 -> 2789 bytes
.../viewer/web/cmaps/KSCms-UHC-HW-V.bcmap | Bin 0 -> 169 bytes
app/static/viewer/web/cmaps/KSCms-UHC-V.bcmap | Bin 0 -> 166 bytes
app/static/viewer/web/cmaps/KSCpc-EUC-H.bcmap | Bin 0 -> 2024 bytes
app/static/viewer/web/cmaps/KSCpc-EUC-V.bcmap | Bin 0 -> 166 bytes
app/static/viewer/web/cmaps/Katakana.bcmap | Bin 0 -> 100 bytes
app/static/viewer/web/cmaps/LICENSE | 36 +
app/static/viewer/web/cmaps/NWP-H.bcmap | Bin 0 -> 2765 bytes
app/static/viewer/web/cmaps/NWP-V.bcmap | Bin 0 -> 252 bytes
app/static/viewer/web/cmaps/RKSJ-H.bcmap | Bin 0 -> 534 bytes
app/static/viewer/web/cmaps/RKSJ-V.bcmap | Bin 0 -> 170 bytes
app/static/viewer/web/cmaps/Roman.bcmap | Bin 0 -> 96 bytes
.../viewer/web/cmaps/UniCNS-UCS2-H.bcmap | Bin 0 -> 48280 bytes
.../viewer/web/cmaps/UniCNS-UCS2-V.bcmap | Bin 0 -> 156 bytes
.../viewer/web/cmaps/UniCNS-UTF16-H.bcmap | Bin 0 -> 50419 bytes
.../viewer/web/cmaps/UniCNS-UTF16-V.bcmap | Bin 0 -> 156 bytes
.../viewer/web/cmaps/UniCNS-UTF32-H.bcmap | Bin 0 -> 52679 bytes
.../viewer/web/cmaps/UniCNS-UTF32-V.bcmap | Bin 0 -> 160 bytes
.../viewer/web/cmaps/UniCNS-UTF8-H.bcmap | Bin 0 -> 53629 bytes
.../viewer/web/cmaps/UniCNS-UTF8-V.bcmap | Bin 0 -> 157 bytes
.../viewer/web/cmaps/UniGB-UCS2-H.bcmap | Bin 0 -> 43366 bytes
.../viewer/web/cmaps/UniGB-UCS2-V.bcmap | Bin 0 -> 193 bytes
.../viewer/web/cmaps/UniGB-UTF16-H.bcmap | Bin 0 -> 44086 bytes
.../viewer/web/cmaps/UniGB-UTF16-V.bcmap | Bin 0 -> 178 bytes
.../viewer/web/cmaps/UniGB-UTF32-H.bcmap | Bin 0 -> 45738 bytes
.../viewer/web/cmaps/UniGB-UTF32-V.bcmap | Bin 0 -> 182 bytes
.../viewer/web/cmaps/UniGB-UTF8-H.bcmap | Bin 0 -> 46837 bytes
.../viewer/web/cmaps/UniGB-UTF8-V.bcmap | Bin 0 -> 181 bytes
.../viewer/web/cmaps/UniJIS-UCS2-H.bcmap | Bin 0 -> 25439 bytes
.../viewer/web/cmaps/UniJIS-UCS2-HW-H.bcmap | Bin 0 -> 119 bytes
.../viewer/web/cmaps/UniJIS-UCS2-HW-V.bcmap | Bin 0 -> 680 bytes
.../viewer/web/cmaps/UniJIS-UCS2-V.bcmap | Bin 0 -> 664 bytes
.../viewer/web/cmaps/UniJIS-UTF16-H.bcmap | Bin 0 -> 39443 bytes
.../viewer/web/cmaps/UniJIS-UTF16-V.bcmap | Bin 0 -> 643 bytes
.../viewer/web/cmaps/UniJIS-UTF32-H.bcmap | Bin 0 -> 40539 bytes
.../viewer/web/cmaps/UniJIS-UTF32-V.bcmap | Bin 0 -> 677 bytes
.../viewer/web/cmaps/UniJIS-UTF8-H.bcmap | Bin 0 -> 41695 bytes
.../viewer/web/cmaps/UniJIS-UTF8-V.bcmap | Bin 0 -> 678 bytes
.../viewer/web/cmaps/UniJIS2004-UTF16-H.bcmap | Bin 0 -> 39534 bytes
.../viewer/web/cmaps/UniJIS2004-UTF16-V.bcmap | Bin 0 -> 647 bytes
.../viewer/web/cmaps/UniJIS2004-UTF32-H.bcmap | Bin 0 -> 40630 bytes
.../viewer/web/cmaps/UniJIS2004-UTF32-V.bcmap | Bin 0 -> 681 bytes
.../viewer/web/cmaps/UniJIS2004-UTF8-H.bcmap | Bin 0 -> 41779 bytes
.../viewer/web/cmaps/UniJIS2004-UTF8-V.bcmap | Bin 0 -> 682 bytes
.../web/cmaps/UniJISPro-UCS2-HW-V.bcmap | Bin 0 -> 705 bytes
.../viewer/web/cmaps/UniJISPro-UCS2-V.bcmap | Bin 0 -> 689 bytes
.../viewer/web/cmaps/UniJISPro-UTF8-V.bcmap | Bin 0 -> 726 bytes
.../web/cmaps/UniJISX0213-UTF32-H.bcmap | Bin 0 -> 40517 bytes
.../web/cmaps/UniJISX0213-UTF32-V.bcmap | Bin 0 -> 684 bytes
.../web/cmaps/UniJISX02132004-UTF32-H.bcmap | Bin 0 -> 40608 bytes
.../web/cmaps/UniJISX02132004-UTF32-V.bcmap | Bin 0 -> 688 bytes
.../viewer/web/cmaps/UniKS-UCS2-H.bcmap | Bin 0 -> 25783 bytes
.../viewer/web/cmaps/UniKS-UCS2-V.bcmap | Bin 0 -> 178 bytes
.../viewer/web/cmaps/UniKS-UTF16-H.bcmap | Bin 0 -> 26327 bytes
.../viewer/web/cmaps/UniKS-UTF16-V.bcmap | Bin 0 -> 164 bytes
.../viewer/web/cmaps/UniKS-UTF32-H.bcmap | Bin 0 -> 26451 bytes
.../viewer/web/cmaps/UniKS-UTF32-V.bcmap | Bin 0 -> 168 bytes
.../viewer/web/cmaps/UniKS-UTF8-H.bcmap | Bin 0 -> 27790 bytes
.../viewer/web/cmaps/UniKS-UTF8-V.bcmap | Bin 0 -> 169 bytes
app/static/viewer/web/cmaps/V.bcmap | Bin 0 -> 166 bytes
app/static/viewer/web/cmaps/WP-Symbol.bcmap | Bin 0 -> 179 bytes
app/static/viewer/web/compatibility.js | 577 +
.../web/compressed.tracemonkey-pldi-09.pdf | Bin 0 -> 1016315 bytes
app/static/viewer/web/debugger.js | 620 +
.../viewer/web/images/annotation-check.svg | 11 +
.../viewer/web/images/annotation-comment.svg | 16 +
.../viewer/web/images/annotation-help.svg | 26 +
.../viewer/web/images/annotation-insert.svg | 10 +
.../viewer/web/images/annotation-key.svg | 11 +
.../web/images/annotation-newparagraph.svg | 11 +
.../viewer/web/images/annotation-noicon.svg | 7 +
.../viewer/web/images/annotation-note.svg | 42 +
.../web/images/annotation-paragraph.svg | 16 +
.../web/images/findbarButton-next-rtl.png | Bin 0 -> 199 bytes
.../web/images/findbarButton-next-rtl@2x.png | Bin 0 -> 304 bytes
.../viewer/web/images/findbarButton-next.png | Bin 0 -> 193 bytes
.../web/images/findbarButton-next@2x.png | Bin 0 -> 296 bytes
.../web/images/findbarButton-previous-rtl.png | Bin 0 -> 193 bytes
.../images/findbarButton-previous-rtl@2x.png | Bin 0 -> 296 bytes
.../web/images/findbarButton-previous.png | Bin 0 -> 199 bytes
.../web/images/findbarButton-previous@2x.png | Bin 0 -> 304 bytes
app/static/viewer/web/images/grab.cur | Bin 0 -> 326 bytes
app/static/viewer/web/images/grabbing.cur | Bin 0 -> 326 bytes
app/static/viewer/web/images/loading-icon.gif | Bin 0 -> 2545 bytes
.../viewer/web/images/loading-small.png | Bin 0 -> 7402 bytes
.../viewer/web/images/loading-small@2x.png | Bin 0 -> 16131 bytes
...ondaryToolbarButton-documentProperties.png | Bin 0 -> 403 bytes
...aryToolbarButton-documentProperties@2x.png | Bin 0 -> 933 bytes
.../secondaryToolbarButton-firstPage.png | Bin 0 -> 179 bytes
.../secondaryToolbarButton-firstPage@2x.png | Bin 0 -> 266 bytes
.../secondaryToolbarButton-handTool.png | Bin 0 -> 301 bytes
.../secondaryToolbarButton-handTool@2x.png | Bin 0 -> 583 bytes
.../secondaryToolbarButton-lastPage.png | Bin 0 -> 175 bytes
.../secondaryToolbarButton-lastPage@2x.png | Bin 0 -> 276 bytes
.../secondaryToolbarButton-rotateCcw.png | Bin 0 -> 360 bytes
.../secondaryToolbarButton-rotateCcw@2x.png | Bin 0 -> 731 bytes
.../secondaryToolbarButton-rotateCw.png | Bin 0 -> 359 bytes
.../secondaryToolbarButton-rotateCw@2x.png | Bin 0 -> 714 bytes
app/static/viewer/web/images/shadow.png | Bin 0 -> 290 bytes
app/static/viewer/web/images/texture.png | Bin 0 -> 2418 bytes
.../web/images/toolbarButton-bookmark.png | Bin 0 -> 174 bytes
.../web/images/toolbarButton-bookmark@2x.png | Bin 0 -> 260 bytes
.../web/images/toolbarButton-download.png | Bin 0 -> 259 bytes
.../web/images/toolbarButton-download@2x.png | Bin 0 -> 425 bytes
.../web/images/toolbarButton-menuArrows.png | Bin 0 -> 108 bytes
.../images/toolbarButton-menuArrows@2x.png | Bin 0 -> 152 bytes
.../web/images/toolbarButton-openFile.png | Bin 0 -> 295 bytes
.../web/images/toolbarButton-openFile@2x.png | Bin 0 -> 550 bytes
.../web/images/toolbarButton-pageDown-rtl.png | Bin 0 -> 242 bytes
.../images/toolbarButton-pageDown-rtl@2x.png | Bin 0 -> 398 bytes
.../web/images/toolbarButton-pageDown.png | Bin 0 -> 238 bytes
.../web/images/toolbarButton-pageDown@2x.png | Bin 0 -> 396 bytes
.../web/images/toolbarButton-pageUp-rtl.png | Bin 0 -> 245 bytes
.../images/toolbarButton-pageUp-rtl@2x.png | Bin 0 -> 405 bytes
.../web/images/toolbarButton-pageUp.png | Bin 0 -> 246 bytes
.../web/images/toolbarButton-pageUp@2x.png | Bin 0 -> 403 bytes
.../images/toolbarButton-presentationMode.png | Bin 0 -> 321 bytes
.../toolbarButton-presentationMode@2x.png | Bin 0 -> 586 bytes
.../viewer/web/images/toolbarButton-print.png | Bin 0 -> 257 bytes
.../web/images/toolbarButton-print@2x.png | Bin 0 -> 464 bytes
.../web/images/toolbarButton-search.png | Bin 0 -> 309 bytes
.../web/images/toolbarButton-search@2x.png | Bin 0 -> 653 bytes
...olbarButton-secondaryToolbarToggle-rtl.png | Bin 0 -> 246 bytes
...arButton-secondaryToolbarToggle-rtl@2x.png | Bin 0 -> 456 bytes
.../toolbarButton-secondaryToolbarToggle.png | Bin 0 -> 243 bytes
...oolbarButton-secondaryToolbarToggle@2x.png | Bin 0 -> 458 bytes
.../toolbarButton-sidebarToggle-rtl.png | Bin 0 -> 225 bytes
.../toolbarButton-sidebarToggle-rtl@2x.png | Bin 0 -> 344 bytes
.../images/toolbarButton-sidebarToggle.png | Bin 0 -> 225 bytes
.../images/toolbarButton-sidebarToggle@2x.png | Bin 0 -> 331 bytes
.../images/toolbarButton-viewAttachments.png | Bin 0 -> 384 bytes
.../toolbarButton-viewAttachments@2x.png | Bin 0 -> 871 bytes
.../images/toolbarButton-viewOutline-rtl.png | Bin 0 -> 177 bytes
.../toolbarButton-viewOutline-rtl@2x.png | Bin 0 -> 394 bytes
.../web/images/toolbarButton-viewOutline.png | Bin 0 -> 178 bytes
.../images/toolbarButton-viewOutline@2x.png | Bin 0 -> 331 bytes
.../images/toolbarButton-viewThumbnail.png | Bin 0 -> 185 bytes
.../images/toolbarButton-viewThumbnail@2x.png | Bin 0 -> 220 bytes
.../web/images/toolbarButton-zoomIn.png | Bin 0 -> 136 bytes
.../web/images/toolbarButton-zoomIn@2x.png | Bin 0 -> 160 bytes
.../web/images/toolbarButton-zoomOut.png | Bin 0 -> 88 bytes
.../web/images/toolbarButton-zoomOut@2x.png | Bin 0 -> 109 bytes
app/static/viewer/web/l10n.js | 1033 +
.../viewer/web/locale/ach/viewer.properties | 167 +
.../viewer/web/locale/af/viewer.properties | 167 +
.../viewer/web/locale/ak/viewer.properties | 123 +
.../viewer/web/locale/an/viewer.properties | 167 +
.../viewer/web/locale/ar/viewer.properties | 167 +
.../viewer/web/locale/as/viewer.properties | 164 +
.../viewer/web/locale/ast/viewer.properties | 111 +
.../viewer/web/locale/az/viewer.properties | 167 +
.../viewer/web/locale/be/viewer.properties | 105 +
.../viewer/web/locale/bg/viewer.properties | 167 +
.../viewer/web/locale/bn-BD/viewer.properties | 139 +
.../viewer/web/locale/bn-IN/viewer.properties | 167 +
.../viewer/web/locale/br/viewer.properties | 167 +
.../viewer/web/locale/bs/viewer.properties | 125 +
.../viewer/web/locale/ca/viewer.properties | 167 +
.../viewer/web/locale/cs/viewer.properties | 167 +
.../viewer/web/locale/csb/viewer.properties | 134 +
.../viewer/web/locale/cy/viewer.properties | 167 +
.../viewer/web/locale/da/viewer.properties | 167 +
.../viewer/web/locale/de/viewer.properties | 167 +
.../viewer/web/locale/el/viewer.properties | 131 +
.../viewer/web/locale/en-GB/viewer.properties | 167 +
.../viewer/web/locale/en-US/viewer.properties | 167 +
.../viewer/web/locale/en-ZA/viewer.properties | 163 +
.../viewer/web/locale/eo/viewer.properties | 167 +
.../viewer/web/locale/es-AR/viewer.properties | 167 +
.../viewer/web/locale/es-CL/viewer.properties | 130 +
.../viewer/web/locale/es-ES/viewer.properties | 111 +
.../viewer/web/locale/es-MX/viewer.properties | 167 +
.../viewer/web/locale/es/viewer.properties | 136 +
.../viewer/web/locale/et/viewer.properties | 167 +
.../viewer/web/locale/eu/viewer.properties | 167 +
.../viewer/web/locale/fa/viewer.properties | 167 +
.../viewer/web/locale/ff/viewer.properties | 167 +
.../viewer/web/locale/fi/viewer.properties | 167 +
.../viewer/web/locale/fr/viewer.properties | 167 +
.../viewer/web/locale/fy-NL/viewer.properties | 173 +
.../viewer/web/locale/ga-IE/viewer.properties | 167 +
.../viewer/web/locale/gd/viewer.properties | 167 +
.../viewer/web/locale/gl/viewer.properties | 164 +
.../viewer/web/locale/gu-IN/viewer.properties | 149 +
.../viewer/web/locale/he/viewer.properties | 152 +
.../viewer/web/locale/hi-IN/viewer.properties | 166 +
.../viewer/web/locale/hr/viewer.properties | 167 +
.../viewer/web/locale/hu/viewer.properties | 167 +
.../viewer/web/locale/hy-AM/viewer.properties | 167 +
.../viewer/web/locale/id/viewer.properties | 167 +
.../viewer/web/locale/is/viewer.properties | 167 +
.../viewer/web/locale/it/viewer.properties | 111 +
.../viewer/web/locale/ja/viewer.properties | 167 +
.../viewer/web/locale/ka/viewer.properties | 124 +
.../viewer/web/locale/kk/viewer.properties | 167 +
.../viewer/web/locale/km/viewer.properties | 167 +
.../viewer/web/locale/kn/viewer.properties | 167 +
.../viewer/web/locale/ko/viewer.properties | 167 +
.../viewer/web/locale/ku/viewer.properties | 139 +
.../viewer/web/locale/lg/viewer.properties | 103 +
.../viewer/web/locale/lij/viewer.properties | 116 +
.../viewer/web/locale/locale.properties | 312 +
.../viewer/web/locale/lt/viewer.properties | 167 +
.../viewer/web/locale/lv/viewer.properties | 167 +
.../viewer/web/locale/mai/viewer.properties | 165 +
.../viewer/web/locale/mk/viewer.properties | 126 +
.../viewer/web/locale/ml/viewer.properties | 167 +
.../viewer/web/locale/mn/viewer.properties | 65 +
.../viewer/web/locale/mr/viewer.properties | 165 +
.../viewer/web/locale/ms/viewer.properties | 165 +
.../viewer/web/locale/my/viewer.properties | 166 +
.../viewer/web/locale/nb-NO/viewer.properties | 167 +
.../viewer/web/locale/nl/viewer.properties | 167 +
.../viewer/web/locale/nn-NO/viewer.properties | 167 +
.../viewer/web/locale/no/viewer.properties | 134 +
.../viewer/web/locale/nso/viewer.properties | 123 +
.../viewer/web/locale/oc/viewer.properties | 165 +
.../viewer/web/locale/or/viewer.properties | 164 +
.../viewer/web/locale/pa-IN/viewer.properties | 181 +
.../viewer/web/locale/pl/viewer.properties | 152 +
.../viewer/web/locale/pt-BR/viewer.properties | 167 +
.../viewer/web/locale/pt-PT/viewer.properties | 167 +
.../viewer/web/locale/rm/viewer.properties | 157 +
.../viewer/web/locale/ro/viewer.properties | 167 +
.../viewer/web/locale/ru/viewer.properties | 111 +
.../viewer/web/locale/rw/viewer.properties | 73 +
.../viewer/web/locale/sah/viewer.properties | 163 +
.../viewer/web/locale/si/viewer.properties | 167 +
.../viewer/web/locale/sk/viewer.properties | 167 +
.../viewer/web/locale/sl/viewer.properties | 167 +
.../viewer/web/locale/son/viewer.properties | 167 +
.../viewer/web/locale/sq/viewer.properties | 165 +
.../viewer/web/locale/sr/viewer.properties | 167 +
.../viewer/web/locale/sv-SE/viewer.properties | 167 +
.../viewer/web/locale/sv/viewer.properties | 137 +
.../viewer/web/locale/sw/viewer.properties | 123 +
.../viewer/web/locale/ta-LK/viewer.properties | 64 +
.../viewer/web/locale/ta/viewer.properties | 167 +
.../viewer/web/locale/te/viewer.properties | 167 +
.../viewer/web/locale/th/viewer.properties | 167 +
.../viewer/web/locale/tl/viewer.properties | 83 +
.../viewer/web/locale/tn/viewer.properties | 74 +
.../viewer/web/locale/tr/viewer.properties | 167 +
.../viewer/web/locale/uk/viewer.properties | 167 +
.../viewer/web/locale/ur/viewer.properties | 161 +
.../viewer/web/locale/vi/viewer.properties | 145 +
.../viewer/web/locale/wo/viewer.properties | 118 +
.../viewer/web/locale/xh/viewer.properties | 167 +
.../viewer/web/locale/zh-CN/viewer.properties | 167 +
.../viewer/web/locale/zh-TW/viewer.properties | 168 +
.../viewer/web/locale/zu/viewer.properties | 124 +
app/static/viewer/web/viewer.css | 2001 +
app/static/viewer/web/viewer.html | 426 +
app/static/viewer/web/viewer.js | 7560 +++
app/templates/annotations.html | 31 +-
app/templates/show_book_detail.html | 6 +-
app/views.py | 12 +-
369 files changed, 76597 insertions(+), 7 deletions(-)
create mode 100644 app/getannot.py
create mode 100644 app/static/viewer/LICENSE
create mode 100755 app/static/viewer/build/pdf.js
create mode 100755 app/static/viewer/build/pdf.worker.js
create mode 100755 app/static/viewer/web/cmaps/78-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/78-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/78-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/78-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/78-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/78-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/78ms-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/78ms-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/83pv-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/90ms-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/90ms-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/90msp-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/90msp-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/90pv-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/90pv-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Add-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/Add-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/Add-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Add-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-0.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-1.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-3.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-4.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-5.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-6.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-CNS1-UCS2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-0.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-1.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-3.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-4.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-5.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-GB1-UCS2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-0.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-1.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-3.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-4.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-5.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-6.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Japan1-UCS2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Korea1-0.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Korea1-1.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Korea1-2.bcmap
create mode 100755 app/static/viewer/web/cmaps/Adobe-Korea1-UCS2.bcmap
create mode 100755 app/static/viewer/web/cmaps/B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/B5pc-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/B5pc-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/CNS-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/CNS-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/CNS1-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/CNS1-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/CNS2-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/CNS2-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/ETHK-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/ETHK-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/ETen-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/ETen-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/ETenms-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/ETenms-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Ext-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/Ext-RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/Ext-RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Ext-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GB-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GB-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GB-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GB-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBK-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBK-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBK2K-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBK2K-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBKp-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBKp-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBT-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBT-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBT-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBT-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBTpc-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBTpc-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBpc-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/GBpc-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKdla-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKdla-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKdlb-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKdlb-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKgccs-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKgccs-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKm314-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKm314-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKm471-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKm471-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKscs-B5-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/HKscs-B5-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Hankaku.bcmap
create mode 100755 app/static/viewer/web/cmaps/Hiragana.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSC-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSC-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSC-Johab-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSC-Johab-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSCms-UHC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSCms-UHC-HW-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSCms-UHC-HW-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSCms-UHC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSCpc-EUC-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/KSCpc-EUC-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Katakana.bcmap
create mode 100755 app/static/viewer/web/cmaps/LICENSE
create mode 100755 app/static/viewer/web/cmaps/NWP-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/NWP-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/RKSJ-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/RKSJ-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/Roman.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UCS2-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UCS2-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UTF16-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UTF16-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UTF8-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniCNS-UTF8-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UCS2-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UCS2-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UTF16-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UTF16-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UTF8-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniGB-UTF8-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UCS2-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UCS2-HW-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UCS2-HW-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UCS2-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UTF16-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UTF16-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UTF8-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS-UTF8-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS2004-UTF16-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS2004-UTF16-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS2004-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS2004-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS2004-UTF8-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJIS2004-UTF8-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISPro-UCS2-HW-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISPro-UCS2-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISPro-UTF8-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISX0213-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISX0213-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISX02132004-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniJISX02132004-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UCS2-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UCS2-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UTF16-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UTF16-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UTF32-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UTF32-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UTF8-H.bcmap
create mode 100755 app/static/viewer/web/cmaps/UniKS-UTF8-V.bcmap
create mode 100755 app/static/viewer/web/cmaps/V.bcmap
create mode 100755 app/static/viewer/web/cmaps/WP-Symbol.bcmap
create mode 100755 app/static/viewer/web/compatibility.js
create mode 100755 app/static/viewer/web/compressed.tracemonkey-pldi-09.pdf
create mode 100755 app/static/viewer/web/debugger.js
create mode 100755 app/static/viewer/web/images/annotation-check.svg
create mode 100755 app/static/viewer/web/images/annotation-comment.svg
create mode 100755 app/static/viewer/web/images/annotation-help.svg
create mode 100755 app/static/viewer/web/images/annotation-insert.svg
create mode 100755 app/static/viewer/web/images/annotation-key.svg
create mode 100755 app/static/viewer/web/images/annotation-newparagraph.svg
create mode 100755 app/static/viewer/web/images/annotation-noicon.svg
create mode 100755 app/static/viewer/web/images/annotation-note.svg
create mode 100755 app/static/viewer/web/images/annotation-paragraph.svg
create mode 100755 app/static/viewer/web/images/findbarButton-next-rtl.png
create mode 100755 app/static/viewer/web/images/findbarButton-next-rtl@2x.png
create mode 100755 app/static/viewer/web/images/findbarButton-next.png
create mode 100755 app/static/viewer/web/images/findbarButton-next@2x.png
create mode 100755 app/static/viewer/web/images/findbarButton-previous-rtl.png
create mode 100755 app/static/viewer/web/images/findbarButton-previous-rtl@2x.png
create mode 100755 app/static/viewer/web/images/findbarButton-previous.png
create mode 100755 app/static/viewer/web/images/findbarButton-previous@2x.png
create mode 100755 app/static/viewer/web/images/grab.cur
create mode 100755 app/static/viewer/web/images/grabbing.cur
create mode 100755 app/static/viewer/web/images/loading-icon.gif
create mode 100755 app/static/viewer/web/images/loading-small.png
create mode 100644 app/static/viewer/web/images/loading-small@2x.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-documentProperties.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-documentProperties@2x.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-firstPage.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-firstPage@2x.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-handTool.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-handTool@2x.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-lastPage.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-lastPage@2x.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-rotateCcw.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-rotateCcw@2x.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-rotateCw.png
create mode 100755 app/static/viewer/web/images/secondaryToolbarButton-rotateCw@2x.png
create mode 100755 app/static/viewer/web/images/shadow.png
create mode 100755 app/static/viewer/web/images/texture.png
create mode 100755 app/static/viewer/web/images/toolbarButton-bookmark.png
create mode 100755 app/static/viewer/web/images/toolbarButton-bookmark@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-download.png
create mode 100755 app/static/viewer/web/images/toolbarButton-download@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-menuArrows.png
create mode 100755 app/static/viewer/web/images/toolbarButton-menuArrows@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-openFile.png
create mode 100755 app/static/viewer/web/images/toolbarButton-openFile@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageDown-rtl.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageDown-rtl@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageDown.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageDown@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageUp-rtl.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageUp-rtl@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageUp.png
create mode 100755 app/static/viewer/web/images/toolbarButton-pageUp@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-presentationMode.png
create mode 100755 app/static/viewer/web/images/toolbarButton-presentationMode@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-print.png
create mode 100755 app/static/viewer/web/images/toolbarButton-print@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-search.png
create mode 100755 app/static/viewer/web/images/toolbarButton-search@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-secondaryToolbarToggle-rtl.png
create mode 100755 app/static/viewer/web/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-secondaryToolbarToggle.png
create mode 100755 app/static/viewer/web/images/toolbarButton-secondaryToolbarToggle@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-sidebarToggle-rtl.png
create mode 100755 app/static/viewer/web/images/toolbarButton-sidebarToggle-rtl@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-sidebarToggle.png
create mode 100755 app/static/viewer/web/images/toolbarButton-sidebarToggle@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewAttachments.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewAttachments@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewOutline-rtl.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewOutline-rtl@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewOutline.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewOutline@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewThumbnail.png
create mode 100755 app/static/viewer/web/images/toolbarButton-viewThumbnail@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-zoomIn.png
create mode 100755 app/static/viewer/web/images/toolbarButton-zoomIn@2x.png
create mode 100755 app/static/viewer/web/images/toolbarButton-zoomOut.png
create mode 100755 app/static/viewer/web/images/toolbarButton-zoomOut@2x.png
create mode 100755 app/static/viewer/web/l10n.js
create mode 100755 app/static/viewer/web/locale/ach/viewer.properties
create mode 100755 app/static/viewer/web/locale/af/viewer.properties
create mode 100755 app/static/viewer/web/locale/ak/viewer.properties
create mode 100755 app/static/viewer/web/locale/an/viewer.properties
create mode 100755 app/static/viewer/web/locale/ar/viewer.properties
create mode 100755 app/static/viewer/web/locale/as/viewer.properties
create mode 100755 app/static/viewer/web/locale/ast/viewer.properties
create mode 100755 app/static/viewer/web/locale/az/viewer.properties
create mode 100755 app/static/viewer/web/locale/be/viewer.properties
create mode 100755 app/static/viewer/web/locale/bg/viewer.properties
create mode 100755 app/static/viewer/web/locale/bn-BD/viewer.properties
create mode 100755 app/static/viewer/web/locale/bn-IN/viewer.properties
create mode 100755 app/static/viewer/web/locale/br/viewer.properties
create mode 100755 app/static/viewer/web/locale/bs/viewer.properties
create mode 100755 app/static/viewer/web/locale/ca/viewer.properties
create mode 100755 app/static/viewer/web/locale/cs/viewer.properties
create mode 100755 app/static/viewer/web/locale/csb/viewer.properties
create mode 100755 app/static/viewer/web/locale/cy/viewer.properties
create mode 100755 app/static/viewer/web/locale/da/viewer.properties
create mode 100755 app/static/viewer/web/locale/de/viewer.properties
create mode 100755 app/static/viewer/web/locale/el/viewer.properties
create mode 100755 app/static/viewer/web/locale/en-GB/viewer.properties
create mode 100755 app/static/viewer/web/locale/en-US/viewer.properties
create mode 100755 app/static/viewer/web/locale/en-ZA/viewer.properties
create mode 100755 app/static/viewer/web/locale/eo/viewer.properties
create mode 100755 app/static/viewer/web/locale/es-AR/viewer.properties
create mode 100755 app/static/viewer/web/locale/es-CL/viewer.properties
create mode 100755 app/static/viewer/web/locale/es-ES/viewer.properties
create mode 100755 app/static/viewer/web/locale/es-MX/viewer.properties
create mode 100644 app/static/viewer/web/locale/es/viewer.properties
create mode 100755 app/static/viewer/web/locale/et/viewer.properties
create mode 100755 app/static/viewer/web/locale/eu/viewer.properties
create mode 100755 app/static/viewer/web/locale/fa/viewer.properties
create mode 100755 app/static/viewer/web/locale/ff/viewer.properties
create mode 100755 app/static/viewer/web/locale/fi/viewer.properties
create mode 100755 app/static/viewer/web/locale/fr/viewer.properties
create mode 100755 app/static/viewer/web/locale/fy-NL/viewer.properties
create mode 100755 app/static/viewer/web/locale/ga-IE/viewer.properties
create mode 100755 app/static/viewer/web/locale/gd/viewer.properties
create mode 100755 app/static/viewer/web/locale/gl/viewer.properties
create mode 100755 app/static/viewer/web/locale/gu-IN/viewer.properties
create mode 100755 app/static/viewer/web/locale/he/viewer.properties
create mode 100755 app/static/viewer/web/locale/hi-IN/viewer.properties
create mode 100755 app/static/viewer/web/locale/hr/viewer.properties
create mode 100755 app/static/viewer/web/locale/hu/viewer.properties
create mode 100755 app/static/viewer/web/locale/hy-AM/viewer.properties
create mode 100755 app/static/viewer/web/locale/id/viewer.properties
create mode 100755 app/static/viewer/web/locale/is/viewer.properties
create mode 100755 app/static/viewer/web/locale/it/viewer.properties
create mode 100755 app/static/viewer/web/locale/ja/viewer.properties
create mode 100755 app/static/viewer/web/locale/ka/viewer.properties
create mode 100755 app/static/viewer/web/locale/kk/viewer.properties
create mode 100755 app/static/viewer/web/locale/km/viewer.properties
create mode 100755 app/static/viewer/web/locale/kn/viewer.properties
create mode 100755 app/static/viewer/web/locale/ko/viewer.properties
create mode 100755 app/static/viewer/web/locale/ku/viewer.properties
create mode 100755 app/static/viewer/web/locale/lg/viewer.properties
create mode 100755 app/static/viewer/web/locale/lij/viewer.properties
create mode 100755 app/static/viewer/web/locale/locale.properties
create mode 100755 app/static/viewer/web/locale/lt/viewer.properties
create mode 100755 app/static/viewer/web/locale/lv/viewer.properties
create mode 100755 app/static/viewer/web/locale/mai/viewer.properties
create mode 100755 app/static/viewer/web/locale/mk/viewer.properties
create mode 100755 app/static/viewer/web/locale/ml/viewer.properties
create mode 100755 app/static/viewer/web/locale/mn/viewer.properties
create mode 100755 app/static/viewer/web/locale/mr/viewer.properties
create mode 100755 app/static/viewer/web/locale/ms/viewer.properties
create mode 100755 app/static/viewer/web/locale/my/viewer.properties
create mode 100755 app/static/viewer/web/locale/nb-NO/viewer.properties
create mode 100755 app/static/viewer/web/locale/nl/viewer.properties
create mode 100755 app/static/viewer/web/locale/nn-NO/viewer.properties
create mode 100644 app/static/viewer/web/locale/no/viewer.properties
create mode 100755 app/static/viewer/web/locale/nso/viewer.properties
create mode 100755 app/static/viewer/web/locale/oc/viewer.properties
create mode 100755 app/static/viewer/web/locale/or/viewer.properties
create mode 100755 app/static/viewer/web/locale/pa-IN/viewer.properties
create mode 100755 app/static/viewer/web/locale/pl/viewer.properties
create mode 100755 app/static/viewer/web/locale/pt-BR/viewer.properties
create mode 100755 app/static/viewer/web/locale/pt-PT/viewer.properties
create mode 100755 app/static/viewer/web/locale/rm/viewer.properties
create mode 100755 app/static/viewer/web/locale/ro/viewer.properties
create mode 100755 app/static/viewer/web/locale/ru/viewer.properties
create mode 100755 app/static/viewer/web/locale/rw/viewer.properties
create mode 100755 app/static/viewer/web/locale/sah/viewer.properties
create mode 100755 app/static/viewer/web/locale/si/viewer.properties
create mode 100755 app/static/viewer/web/locale/sk/viewer.properties
create mode 100755 app/static/viewer/web/locale/sl/viewer.properties
create mode 100755 app/static/viewer/web/locale/son/viewer.properties
create mode 100755 app/static/viewer/web/locale/sq/viewer.properties
create mode 100755 app/static/viewer/web/locale/sr/viewer.properties
create mode 100755 app/static/viewer/web/locale/sv-SE/viewer.properties
create mode 100644 app/static/viewer/web/locale/sv/viewer.properties
create mode 100755 app/static/viewer/web/locale/sw/viewer.properties
create mode 100755 app/static/viewer/web/locale/ta-LK/viewer.properties
create mode 100755 app/static/viewer/web/locale/ta/viewer.properties
create mode 100755 app/static/viewer/web/locale/te/viewer.properties
create mode 100755 app/static/viewer/web/locale/th/viewer.properties
create mode 100755 app/static/viewer/web/locale/tl/viewer.properties
create mode 100755 app/static/viewer/web/locale/tn/viewer.properties
create mode 100755 app/static/viewer/web/locale/tr/viewer.properties
create mode 100755 app/static/viewer/web/locale/uk/viewer.properties
create mode 100755 app/static/viewer/web/locale/ur/viewer.properties
create mode 100755 app/static/viewer/web/locale/vi/viewer.properties
create mode 100755 app/static/viewer/web/locale/wo/viewer.properties
create mode 100755 app/static/viewer/web/locale/xh/viewer.properties
create mode 100755 app/static/viewer/web/locale/zh-CN/viewer.properties
create mode 100755 app/static/viewer/web/locale/zh-TW/viewer.properties
create mode 100755 app/static/viewer/web/locale/zu/viewer.properties
create mode 100755 app/static/viewer/web/viewer.css
create mode 100755 app/static/viewer/web/viewer.html
create mode 100755 app/static/viewer/web/viewer.js
diff --git a/app/getannot.py b/app/getannot.py
new file mode 100644
index 0000000..78fd698
--- /dev/null
+++ b/app/getannot.py
@@ -0,0 +1,29 @@
+#https://gist.github.com/mjlavin80/186a6395c5819dbe25a8a0e001d5acfd
+import requests
+import json
+
+
+
+# This script demonstrates how to query annotations for a particular URL using the hypothes.is API. An API key is required.
+# The end result of this script is a Python dictionary with annotation data in it. Top save to csv or other format, further parsing would be required
+def get_annotations():
+ KEY = "6879-GqSSbtmCoLUb8u9f6Gxh6DuScIkFKj321HSYzYZnjxc"
+ # here is the viewer pdf from each pdf
+ URL = "https://monoskop.org/Monoskop"
+
+ #a dictionary containing necessary http headers
+ headers = {
+ "Host": "hypothes.is",
+ "Accept": "application/json",
+ "Authorization": "Bearer %s" % KEY
+ }
+
+ base_url = "https://hypothes.is/api/search"
+
+ search_url = "".join([base_url, "?uri=", URL])
+
+ r = requests.get(search_url, headers=headers)
+ #data is a python dictionary
+ return json.loads(r.text)
+
+
diff --git a/app/static/viewer/LICENSE b/app/static/viewer/LICENSE
new file mode 100644
index 0000000..f433b1a
--- /dev/null
+++ b/app/static/viewer/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/app/static/viewer/build/pdf.js b/app/static/viewer/build/pdf.js
new file mode 100755
index 0000000..fb57286
--- /dev/null
+++ b/app/static/viewer/build/pdf.js
@@ -0,0 +1,8011 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jshint globalstrict: false */
+/* globals PDFJS */
+
+// Initializing PDFJS global object (if still undefined)
+if (typeof PDFJS === 'undefined') {
+ (typeof window !== 'undefined' ? window : this).PDFJS = {};
+}
+
+PDFJS.version = '1.1.114';
+PDFJS.build = '3fd44fd';
+
+(function pdfjsWrapper() {
+ // Use strict in our context only - users might not want it
+ 'use strict';
+
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL,
+ Promise */
+
+'use strict';
+
+var globalScope = (typeof window === 'undefined') ? this : window;
+
+var isWorker = (typeof window === 'undefined');
+
+var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
+
+var TextRenderingMode = {
+ FILL: 0,
+ STROKE: 1,
+ FILL_STROKE: 2,
+ INVISIBLE: 3,
+ FILL_ADD_TO_PATH: 4,
+ STROKE_ADD_TO_PATH: 5,
+ FILL_STROKE_ADD_TO_PATH: 6,
+ ADD_TO_PATH: 7,
+ FILL_STROKE_MASK: 3,
+ ADD_TO_PATH_FLAG: 4
+};
+
+var ImageKind = {
+ GRAYSCALE_1BPP: 1,
+ RGB_24BPP: 2,
+ RGBA_32BPP: 3
+};
+
+var AnnotationType = {
+ WIDGET: 1,
+ TEXT: 2,
+ LINK: 3
+};
+
+var StreamType = {
+ UNKNOWN: 0,
+ FLATE: 1,
+ LZW: 2,
+ DCT: 3,
+ JPX: 4,
+ JBIG: 5,
+ A85: 6,
+ AHX: 7,
+ CCF: 8,
+ RL: 9
+};
+
+var FontType = {
+ UNKNOWN: 0,
+ TYPE1: 1,
+ TYPE1C: 2,
+ CIDFONTTYPE0: 3,
+ CIDFONTTYPE0C: 4,
+ TRUETYPE: 5,
+ CIDFONTTYPE2: 6,
+ TYPE3: 7,
+ OPENTYPE: 8,
+ TYPE0: 9,
+ MMTYPE1: 10
+};
+
+// The global PDFJS object exposes the API
+// In production, it will be declared outside a global wrapper
+// In development, it will be declared here
+if (!globalScope.PDFJS) {
+ globalScope.PDFJS = {};
+}
+
+globalScope.PDFJS.pdfBug = false;
+
+PDFJS.VERBOSITY_LEVELS = {
+ errors: 0,
+ warnings: 1,
+ infos: 5
+};
+
+// All the possible operations for an operator list.
+var OPS = PDFJS.OPS = {
+ // Intentionally start from 1 so it is easy to spot bad operators that will be
+ // 0's.
+ dependency: 1,
+ setLineWidth: 2,
+ setLineCap: 3,
+ setLineJoin: 4,
+ setMiterLimit: 5,
+ setDash: 6,
+ setRenderingIntent: 7,
+ setFlatness: 8,
+ setGState: 9,
+ save: 10,
+ restore: 11,
+ transform: 12,
+ moveTo: 13,
+ lineTo: 14,
+ curveTo: 15,
+ curveTo2: 16,
+ curveTo3: 17,
+ closePath: 18,
+ rectangle: 19,
+ stroke: 20,
+ closeStroke: 21,
+ fill: 22,
+ eoFill: 23,
+ fillStroke: 24,
+ eoFillStroke: 25,
+ closeFillStroke: 26,
+ closeEOFillStroke: 27,
+ endPath: 28,
+ clip: 29,
+ eoClip: 30,
+ beginText: 31,
+ endText: 32,
+ setCharSpacing: 33,
+ setWordSpacing: 34,
+ setHScale: 35,
+ setLeading: 36,
+ setFont: 37,
+ setTextRenderingMode: 38,
+ setTextRise: 39,
+ moveText: 40,
+ setLeadingMoveText: 41,
+ setTextMatrix: 42,
+ nextLine: 43,
+ showText: 44,
+ showSpacedText: 45,
+ nextLineShowText: 46,
+ nextLineSetSpacingShowText: 47,
+ setCharWidth: 48,
+ setCharWidthAndBounds: 49,
+ setStrokeColorSpace: 50,
+ setFillColorSpace: 51,
+ setStrokeColor: 52,
+ setStrokeColorN: 53,
+ setFillColor: 54,
+ setFillColorN: 55,
+ setStrokeGray: 56,
+ setFillGray: 57,
+ setStrokeRGBColor: 58,
+ setFillRGBColor: 59,
+ setStrokeCMYKColor: 60,
+ setFillCMYKColor: 61,
+ shadingFill: 62,
+ beginInlineImage: 63,
+ beginImageData: 64,
+ endInlineImage: 65,
+ paintXObject: 66,
+ markPoint: 67,
+ markPointProps: 68,
+ beginMarkedContent: 69,
+ beginMarkedContentProps: 70,
+ endMarkedContent: 71,
+ beginCompat: 72,
+ endCompat: 73,
+ paintFormXObjectBegin: 74,
+ paintFormXObjectEnd: 75,
+ beginGroup: 76,
+ endGroup: 77,
+ beginAnnotations: 78,
+ endAnnotations: 79,
+ beginAnnotation: 80,
+ endAnnotation: 81,
+ paintJpegXObject: 82,
+ paintImageMaskXObject: 83,
+ paintImageMaskXObjectGroup: 84,
+ paintImageXObject: 85,
+ paintInlineImageXObject: 86,
+ paintInlineImageXObjectGroup: 87,
+ paintImageXObjectRepeat: 88,
+ paintImageMaskXObjectRepeat: 89,
+ paintSolidColorImageMask: 90,
+ constructPath: 91
+};
+
+// A notice for devs. These are good for things that are helpful to devs, such
+// as warning that Workers were disabled, which is important to devs but not
+// end users.
+function info(msg) {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.infos) {
+ console.log('Info: ' + msg);
+ }
+}
+
+// Non-fatal warnings.
+function warn(msg) {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.warnings) {
+ console.log('Warning: ' + msg);
+ }
+}
+
+// Fatal errors that should trigger the fallback UI and halt execution by
+// throwing an exception.
+function error(msg) {
+ if (PDFJS.verbosity >= PDFJS.VERBOSITY_LEVELS.errors) {
+ console.log('Error: ' + msg);
+ console.log(backtrace());
+ }
+ UnsupportedManager.notify(UNSUPPORTED_FEATURES.unknown);
+ throw new Error(msg);
+}
+
+function backtrace() {
+ try {
+ throw new Error();
+ } catch (e) {
+ return e.stack ? e.stack.split('\n').slice(2).join('\n') : '';
+ }
+}
+
+function assert(cond, msg) {
+ if (!cond) {
+ error(msg);
+ }
+}
+
+var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
+ unknown: 'unknown',
+ forms: 'forms',
+ javaScript: 'javaScript',
+ smask: 'smask',
+ shadingPattern: 'shadingPattern',
+ font: 'font'
+};
+
+var UnsupportedManager = PDFJS.UnsupportedManager =
+ (function UnsupportedManagerClosure() {
+ var listeners = [];
+ return {
+ listen: function (cb) {
+ listeners.push(cb);
+ },
+ notify: function (featureId) {
+ warn('Unsupported feature "' + featureId + '"');
+ for (var i = 0, ii = listeners.length; i < ii; i++) {
+ listeners[i](featureId);
+ }
+ }
+ };
+})();
+
+// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
+// absolute URL, it will be returned as is.
+function combineUrl(baseUrl, url) {
+ if (!url) {
+ return baseUrl;
+ }
+ if (/^[a-z][a-z0-9+\-.]*:/i.test(url)) {
+ return url;
+ }
+ var i;
+ if (url.charAt(0) === '/') {
+ // absolute path
+ i = baseUrl.indexOf('://');
+ if (url.charAt(1) === '/') {
+ ++i;
+ } else {
+ i = baseUrl.indexOf('/', i + 3);
+ }
+ return baseUrl.substring(0, i) + url;
+ } else {
+ // relative path
+ var pathLength = baseUrl.length;
+ i = baseUrl.lastIndexOf('#');
+ pathLength = i >= 0 ? i : pathLength;
+ i = baseUrl.lastIndexOf('?', pathLength);
+ pathLength = i >= 0 ? i : pathLength;
+ var prefixLength = baseUrl.lastIndexOf('/', pathLength);
+ return baseUrl.substring(0, prefixLength + 1) + url;
+ }
+}
+
+// Validates if URL is safe and allowed, e.g. to avoid XSS.
+function isValidUrl(url, allowRelative) {
+ if (!url) {
+ return false;
+ }
+ // RFC 3986 (http://tools.ietf.org/html/rfc3986#section-3.1)
+ // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ var protocol = /^[a-z][a-z0-9+\-.]*(?=:)/i.exec(url);
+ if (!protocol) {
+ return allowRelative;
+ }
+ protocol = protocol[0].toLowerCase();
+ switch (protocol) {
+ case 'http':
+ case 'https':
+ case 'ftp':
+ case 'mailto':
+ case 'tel':
+ return true;
+ default:
+ return false;
+ }
+}
+PDFJS.isValidUrl = isValidUrl;
+
+function shadow(obj, prop, value) {
+ Object.defineProperty(obj, prop, { value: value,
+ enumerable: true,
+ configurable: true,
+ writable: false });
+ return value;
+}
+PDFJS.shadow = shadow;
+
+var PasswordResponses = PDFJS.PasswordResponses = {
+ NEED_PASSWORD: 1,
+ INCORRECT_PASSWORD: 2
+};
+
+var PasswordException = (function PasswordExceptionClosure() {
+ function PasswordException(msg, code) {
+ this.name = 'PasswordException';
+ this.message = msg;
+ this.code = code;
+ }
+
+ PasswordException.prototype = new Error();
+ PasswordException.constructor = PasswordException;
+
+ return PasswordException;
+})();
+PDFJS.PasswordException = PasswordException;
+
+var UnknownErrorException = (function UnknownErrorExceptionClosure() {
+ function UnknownErrorException(msg, details) {
+ this.name = 'UnknownErrorException';
+ this.message = msg;
+ this.details = details;
+ }
+
+ UnknownErrorException.prototype = new Error();
+ UnknownErrorException.constructor = UnknownErrorException;
+
+ return UnknownErrorException;
+})();
+PDFJS.UnknownErrorException = UnknownErrorException;
+
+var InvalidPDFException = (function InvalidPDFExceptionClosure() {
+ function InvalidPDFException(msg) {
+ this.name = 'InvalidPDFException';
+ this.message = msg;
+ }
+
+ InvalidPDFException.prototype = new Error();
+ InvalidPDFException.constructor = InvalidPDFException;
+
+ return InvalidPDFException;
+})();
+PDFJS.InvalidPDFException = InvalidPDFException;
+
+var MissingPDFException = (function MissingPDFExceptionClosure() {
+ function MissingPDFException(msg) {
+ this.name = 'MissingPDFException';
+ this.message = msg;
+ }
+
+ MissingPDFException.prototype = new Error();
+ MissingPDFException.constructor = MissingPDFException;
+
+ return MissingPDFException;
+})();
+PDFJS.MissingPDFException = MissingPDFException;
+
+var UnexpectedResponseException =
+ (function UnexpectedResponseExceptionClosure() {
+ function UnexpectedResponseException(msg, status) {
+ this.name = 'UnexpectedResponseException';
+ this.message = msg;
+ this.status = status;
+ }
+
+ UnexpectedResponseException.prototype = new Error();
+ UnexpectedResponseException.constructor = UnexpectedResponseException;
+
+ return UnexpectedResponseException;
+})();
+PDFJS.UnexpectedResponseException = UnexpectedResponseException;
+
+var NotImplementedException = (function NotImplementedExceptionClosure() {
+ function NotImplementedException(msg) {
+ this.message = msg;
+ }
+
+ NotImplementedException.prototype = new Error();
+ NotImplementedException.prototype.name = 'NotImplementedException';
+ NotImplementedException.constructor = NotImplementedException;
+
+ return NotImplementedException;
+})();
+
+var MissingDataException = (function MissingDataExceptionClosure() {
+ function MissingDataException(begin, end) {
+ this.begin = begin;
+ this.end = end;
+ this.message = 'Missing data [' + begin + ', ' + end + ')';
+ }
+
+ MissingDataException.prototype = new Error();
+ MissingDataException.prototype.name = 'MissingDataException';
+ MissingDataException.constructor = MissingDataException;
+
+ return MissingDataException;
+})();
+
+var XRefParseException = (function XRefParseExceptionClosure() {
+ function XRefParseException(msg) {
+ this.message = msg;
+ }
+
+ XRefParseException.prototype = new Error();
+ XRefParseException.prototype.name = 'XRefParseException';
+ XRefParseException.constructor = XRefParseException;
+
+ return XRefParseException;
+})();
+
+
+function bytesToString(bytes) {
+ assert(bytes !== null && typeof bytes === 'object' &&
+ bytes.length !== undefined, 'Invalid argument for bytesToString');
+ var length = bytes.length;
+ var MAX_ARGUMENT_COUNT = 8192;
+ if (length < MAX_ARGUMENT_COUNT) {
+ return String.fromCharCode.apply(null, bytes);
+ }
+ var strBuf = [];
+ for (var i = 0; i < length; i += MAX_ARGUMENT_COUNT) {
+ var chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);
+ var chunk = bytes.subarray(i, chunkEnd);
+ strBuf.push(String.fromCharCode.apply(null, chunk));
+ }
+ return strBuf.join('');
+}
+
+function stringToBytes(str) {
+ assert(typeof str === 'string', 'Invalid argument for stringToBytes');
+ var length = str.length;
+ var bytes = new Uint8Array(length);
+ for (var i = 0; i < length; ++i) {
+ bytes[i] = str.charCodeAt(i) & 0xFF;
+ }
+ return bytes;
+}
+
+function string32(value) {
+ return String.fromCharCode((value >> 24) & 0xff, (value >> 16) & 0xff,
+ (value >> 8) & 0xff, value & 0xff);
+}
+
+function log2(x) {
+ var n = 1, i = 0;
+ while (x > n) {
+ n <<= 1;
+ i++;
+ }
+ return i;
+}
+
+function readInt8(data, start) {
+ return (data[start] << 24) >> 24;
+}
+
+function readUint16(data, offset) {
+ return (data[offset] << 8) | data[offset + 1];
+}
+
+function readUint32(data, offset) {
+ return ((data[offset] << 24) | (data[offset + 1] << 16) |
+ (data[offset + 2] << 8) | data[offset + 3]) >>> 0;
+}
+
+// Lazy test the endianness of the platform
+// NOTE: This will be 'true' for simulated TypedArrays
+function isLittleEndian() {
+ var buffer8 = new Uint8Array(2);
+ buffer8[0] = 1;
+ var buffer16 = new Uint16Array(buffer8.buffer);
+ return (buffer16[0] === 1);
+}
+
+Object.defineProperty(PDFJS, 'isLittleEndian', {
+ configurable: true,
+ get: function PDFJS_isLittleEndian() {
+ return shadow(PDFJS, 'isLittleEndian', isLittleEndian());
+ }
+});
+
+ // Lazy test if the userAgant support CanvasTypedArrays
+function hasCanvasTypedArrays() {
+ var canvas = document.createElement('canvas');
+ canvas.width = canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+ var imageData = ctx.createImageData(1, 1);
+ return (typeof imageData.data.buffer !== 'undefined');
+}
+
+Object.defineProperty(PDFJS, 'hasCanvasTypedArrays', {
+ configurable: true,
+ get: function PDFJS_hasCanvasTypedArrays() {
+ return shadow(PDFJS, 'hasCanvasTypedArrays', hasCanvasTypedArrays());
+ }
+});
+
+var Uint32ArrayView = (function Uint32ArrayViewClosure() {
+
+ function Uint32ArrayView(buffer, length) {
+ this.buffer = buffer;
+ this.byteLength = buffer.length;
+ this.length = length === undefined ? (this.byteLength >> 2) : length;
+ ensureUint32ArrayViewProps(this.length);
+ }
+ Uint32ArrayView.prototype = Object.create(null);
+
+ var uint32ArrayViewSetters = 0;
+ function createUint32ArrayProp(index) {
+ return {
+ get: function () {
+ var buffer = this.buffer, offset = index << 2;
+ return (buffer[offset] | (buffer[offset + 1] << 8) |
+ (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24)) >>> 0;
+ },
+ set: function (value) {
+ var buffer = this.buffer, offset = index << 2;
+ buffer[offset] = value & 255;
+ buffer[offset + 1] = (value >> 8) & 255;
+ buffer[offset + 2] = (value >> 16) & 255;
+ buffer[offset + 3] = (value >>> 24) & 255;
+ }
+ };
+ }
+
+ function ensureUint32ArrayViewProps(length) {
+ while (uint32ArrayViewSetters < length) {
+ Object.defineProperty(Uint32ArrayView.prototype,
+ uint32ArrayViewSetters,
+ createUint32ArrayProp(uint32ArrayViewSetters));
+ uint32ArrayViewSetters++;
+ }
+ }
+
+ return Uint32ArrayView;
+})();
+
+var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+
+var Util = PDFJS.Util = (function UtilClosure() {
+ function Util() {}
+
+ var rgbBuf = ['rgb(', 0, ',', 0, ',', 0, ')'];
+
+ // makeCssRgb() can be called thousands of times. Using |rgbBuf| avoids
+ // creating many intermediate strings.
+ Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
+ rgbBuf[1] = r;
+ rgbBuf[3] = g;
+ rgbBuf[5] = b;
+ return rgbBuf.join('');
+ };
+
+ // Concatenates two transformation matrices together and returns the result.
+ Util.transform = function Util_transform(m1, m2) {
+ return [
+ m1[0] * m2[0] + m1[2] * m2[1],
+ m1[1] * m2[0] + m1[3] * m2[1],
+ m1[0] * m2[2] + m1[2] * m2[3],
+ m1[1] * m2[2] + m1[3] * m2[3],
+ m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
+ m1[1] * m2[4] + m1[3] * m2[5] + m1[5]
+ ];
+ };
+
+ // For 2d affine transforms
+ Util.applyTransform = function Util_applyTransform(p, m) {
+ var xt = p[0] * m[0] + p[1] * m[2] + m[4];
+ var yt = p[0] * m[1] + p[1] * m[3] + m[5];
+ return [xt, yt];
+ };
+
+ Util.applyInverseTransform = function Util_applyInverseTransform(p, m) {
+ var d = m[0] * m[3] - m[1] * m[2];
+ var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;
+ var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;
+ return [xt, yt];
+ };
+
+ // Applies the transform to the rectangle and finds the minimum axially
+ // aligned bounding box.
+ Util.getAxialAlignedBoundingBox =
+ function Util_getAxialAlignedBoundingBox(r, m) {
+
+ var p1 = Util.applyTransform(r, m);
+ var p2 = Util.applyTransform(r.slice(2, 4), m);
+ var p3 = Util.applyTransform([r[0], r[3]], m);
+ var p4 = Util.applyTransform([r[2], r[1]], m);
+ return [
+ Math.min(p1[0], p2[0], p3[0], p4[0]),
+ Math.min(p1[1], p2[1], p3[1], p4[1]),
+ Math.max(p1[0], p2[0], p3[0], p4[0]),
+ Math.max(p1[1], p2[1], p3[1], p4[1])
+ ];
+ };
+
+ Util.inverseTransform = function Util_inverseTransform(m) {
+ var d = m[0] * m[3] - m[1] * m[2];
+ return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d,
+ (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];
+ };
+
+ // Apply a generic 3d matrix M on a 3-vector v:
+ // | a b c | | X |
+ // | d e f | x | Y |
+ // | g h i | | Z |
+ // M is assumed to be serialized as [a,b,c,d,e,f,g,h,i],
+ // with v as [X,Y,Z]
+ Util.apply3dTransform = function Util_apply3dTransform(m, v) {
+ return [
+ m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
+ m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
+ m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
+ ];
+ };
+
+ // This calculation uses Singular Value Decomposition.
+ // The SVD can be represented with formula A = USV. We are interested in the
+ // matrix S here because it represents the scale values.
+ Util.singularValueDecompose2dScale =
+ function Util_singularValueDecompose2dScale(m) {
+
+ var transpose = [m[0], m[2], m[1], m[3]];
+
+ // Multiply matrix m with its transpose.
+ var a = m[0] * transpose[0] + m[1] * transpose[2];
+ var b = m[0] * transpose[1] + m[1] * transpose[3];
+ var c = m[2] * transpose[0] + m[3] * transpose[2];
+ var d = m[2] * transpose[1] + m[3] * transpose[3];
+
+ // Solve the second degree polynomial to get roots.
+ var first = (a + d) / 2;
+ var second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2;
+ var sx = first + second || 1;
+ var sy = first - second || 1;
+
+ // Scale values are the square roots of the eigenvalues.
+ return [Math.sqrt(sx), Math.sqrt(sy)];
+ };
+
+ // Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
+ // For coordinate systems whose origin lies in the bottom-left, this
+ // means normalization to (BL,TR) ordering. For systems with origin in the
+ // top-left, this means (TL,BR) ordering.
+ Util.normalizeRect = function Util_normalizeRect(rect) {
+ var r = rect.slice(0); // clone rect
+ if (rect[0] > rect[2]) {
+ r[0] = rect[2];
+ r[2] = rect[0];
+ }
+ if (rect[1] > rect[3]) {
+ r[1] = rect[3];
+ r[3] = rect[1];
+ }
+ return r;
+ };
+
+ // Returns a rectangle [x1, y1, x2, y2] corresponding to the
+ // intersection of rect1 and rect2. If no intersection, returns 'false'
+ // The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
+ Util.intersect = function Util_intersect(rect1, rect2) {
+ function compare(a, b) {
+ return a - b;
+ }
+
+ // Order points along the axes
+ var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare),
+ orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare),
+ result = [];
+
+ rect1 = Util.normalizeRect(rect1);
+ rect2 = Util.normalizeRect(rect2);
+
+ // X: first and second points belong to different rectangles?
+ if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
+ (orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) {
+ // Intersection must be between second and third points
+ result[0] = orderedX[1];
+ result[2] = orderedX[2];
+ } else {
+ return false;
+ }
+
+ // Y: first and second points belong to different rectangles?
+ if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
+ (orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) {
+ // Intersection must be between second and third points
+ result[1] = orderedY[1];
+ result[3] = orderedY[2];
+ } else {
+ return false;
+ }
+
+ return result;
+ };
+
+ Util.sign = function Util_sign(num) {
+ return num < 0 ? -1 : 1;
+ };
+
+ Util.appendToArray = function Util_appendToArray(arr1, arr2) {
+ Array.prototype.push.apply(arr1, arr2);
+ };
+
+ Util.prependToArray = function Util_prependToArray(arr1, arr2) {
+ Array.prototype.unshift.apply(arr1, arr2);
+ };
+
+ Util.extendObj = function extendObj(obj1, obj2) {
+ for (var key in obj2) {
+ obj1[key] = obj2[key];
+ }
+ };
+
+ Util.getInheritableProperty = function Util_getInheritableProperty(dict,
+ name) {
+ while (dict && !dict.has(name)) {
+ dict = dict.get('Parent');
+ }
+ if (!dict) {
+ return null;
+ }
+ return dict.get(name);
+ };
+
+ Util.inherit = function Util_inherit(sub, base, prototype) {
+ sub.prototype = Object.create(base.prototype);
+ sub.prototype.constructor = sub;
+ for (var prop in prototype) {
+ sub.prototype[prop] = prototype[prop];
+ }
+ };
+
+ Util.loadScript = function Util_loadScript(src, callback) {
+ var script = document.createElement('script');
+ var loaded = false;
+ script.setAttribute('src', src);
+ if (callback) {
+ script.onload = function() {
+ if (!loaded) {
+ callback();
+ }
+ loaded = true;
+ };
+ }
+ document.getElementsByTagName('head')[0].appendChild(script);
+ };
+
+ return Util;
+})();
+
+/**
+ * PDF page viewport created based on scale, rotation and offset.
+ * @class
+ * @alias PDFJS.PageViewport
+ */
+var PageViewport = PDFJS.PageViewport = (function PageViewportClosure() {
+ /**
+ * @constructor
+ * @private
+ * @param viewBox {Array} xMin, yMin, xMax and yMax coordinates.
+ * @param scale {number} scale of the viewport.
+ * @param rotation {number} rotations of the viewport in degrees.
+ * @param offsetX {number} offset X
+ * @param offsetY {number} offset Y
+ * @param dontFlip {boolean} if true, axis Y will not be flipped.
+ */
+ function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) {
+ this.viewBox = viewBox;
+ this.scale = scale;
+ this.rotation = rotation;
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+
+ // creating transform to convert pdf coordinate system to the normal
+ // canvas like coordinates taking in account scale and rotation
+ var centerX = (viewBox[2] + viewBox[0]) / 2;
+ var centerY = (viewBox[3] + viewBox[1]) / 2;
+ var rotateA, rotateB, rotateC, rotateD;
+ rotation = rotation % 360;
+ rotation = rotation < 0 ? rotation + 360 : rotation;
+ switch (rotation) {
+ case 180:
+ rotateA = -1; rotateB = 0; rotateC = 0; rotateD = 1;
+ break;
+ case 90:
+ rotateA = 0; rotateB = 1; rotateC = 1; rotateD = 0;
+ break;
+ case 270:
+ rotateA = 0; rotateB = -1; rotateC = -1; rotateD = 0;
+ break;
+ //case 0:
+ default:
+ rotateA = 1; rotateB = 0; rotateC = 0; rotateD = -1;
+ break;
+ }
+
+ if (dontFlip) {
+ rotateC = -rotateC; rotateD = -rotateD;
+ }
+
+ var offsetCanvasX, offsetCanvasY;
+ var width, height;
+ if (rotateA === 0) {
+ offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
+ offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
+ width = Math.abs(viewBox[3] - viewBox[1]) * scale;
+ height = Math.abs(viewBox[2] - viewBox[0]) * scale;
+ } else {
+ offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
+ offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
+ width = Math.abs(viewBox[2] - viewBox[0]) * scale;
+ height = Math.abs(viewBox[3] - viewBox[1]) * scale;
+ }
+ // creating transform for the following operations:
+ // translate(-centerX, -centerY), rotate and flip vertically,
+ // scale, and translate(offsetCanvasX, offsetCanvasY)
+ this.transform = [
+ rotateA * scale,
+ rotateB * scale,
+ rotateC * scale,
+ rotateD * scale,
+ offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
+ offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
+ ];
+
+ this.width = width;
+ this.height = height;
+ this.fontScale = scale;
+ }
+ PageViewport.prototype = /** @lends PDFJS.PageViewport.prototype */ {
+ /**
+ * Clones viewport with additional properties.
+ * @param args {Object} (optional) If specified, may contain the 'scale' or
+ * 'rotation' properties to override the corresponding properties in
+ * the cloned viewport.
+ * @returns {PDFJS.PageViewport} Cloned viewport.
+ */
+ clone: function PageViewPort_clone(args) {
+ args = args || {};
+ var scale = 'scale' in args ? args.scale : this.scale;
+ var rotation = 'rotation' in args ? args.rotation : this.rotation;
+ return new PageViewport(this.viewBox.slice(), scale, rotation,
+ this.offsetX, this.offsetY, args.dontFlip);
+ },
+ /**
+ * Converts PDF point to the viewport coordinates. For examples, useful for
+ * converting PDF location into canvas pixel coordinates.
+ * @param x {number} X coordinate.
+ * @param y {number} Y coordinate.
+ * @returns {Object} Object that contains 'x' and 'y' properties of the
+ * point in the viewport coordinate space.
+ * @see {@link convertToPdfPoint}
+ * @see {@link convertToViewportRectangle}
+ */
+ convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
+ return Util.applyTransform([x, y], this.transform);
+ },
+ /**
+ * Converts PDF rectangle to the viewport coordinates.
+ * @param rect {Array} xMin, yMin, xMax and yMax coordinates.
+ * @returns {Array} Contains corresponding coordinates of the rectangle
+ * in the viewport coordinate space.
+ * @see {@link convertToViewportPoint}
+ */
+ convertToViewportRectangle:
+ function PageViewport_convertToViewportRectangle(rect) {
+ var tl = Util.applyTransform([rect[0], rect[1]], this.transform);
+ var br = Util.applyTransform([rect[2], rect[3]], this.transform);
+ return [tl[0], tl[1], br[0], br[1]];
+ },
+ /**
+ * Converts viewport coordinates to the PDF location. For examples, useful
+ * for converting canvas pixel location into PDF one.
+ * @param x {number} X coordinate.
+ * @param y {number} Y coordinate.
+ * @returns {Object} Object that contains 'x' and 'y' properties of the
+ * point in the PDF coordinate space.
+ * @see {@link convertToViewportPoint}
+ */
+ convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) {
+ return Util.applyInverseTransform([x, y], this.transform);
+ }
+ };
+ return PageViewport;
+})();
+
+var PDFStringTranslateTable = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014,
+ 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C,
+ 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160,
+ 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC
+];
+
+function stringToPDFString(str) {
+ var i, n = str.length, strBuf = [];
+ if (str[0] === '\xFE' && str[1] === '\xFF') {
+ // UTF16BE BOM
+ for (i = 2; i < n; i += 2) {
+ strBuf.push(String.fromCharCode(
+ (str.charCodeAt(i) << 8) | str.charCodeAt(i + 1)));
+ }
+ } else {
+ for (i = 0; i < n; ++i) {
+ var code = PDFStringTranslateTable[str.charCodeAt(i)];
+ strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));
+ }
+ }
+ return strBuf.join('');
+}
+
+function stringToUTF8String(str) {
+ return decodeURIComponent(escape(str));
+}
+
+function isEmptyObj(obj) {
+ for (var key in obj) {
+ return false;
+ }
+ return true;
+}
+
+function isBool(v) {
+ return typeof v === 'boolean';
+}
+
+function isInt(v) {
+ return typeof v === 'number' && ((v | 0) === v);
+}
+
+function isNum(v) {
+ return typeof v === 'number';
+}
+
+function isString(v) {
+ return typeof v === 'string';
+}
+
+function isName(v) {
+ return v instanceof Name;
+}
+
+function isCmd(v, cmd) {
+ return v instanceof Cmd && (cmd === undefined || v.cmd === cmd);
+}
+
+function isDict(v, type) {
+ if (!(v instanceof Dict)) {
+ return false;
+ }
+ if (!type) {
+ return true;
+ }
+ var dictType = v.get('Type');
+ return isName(dictType) && dictType.name === type;
+}
+
+function isArray(v) {
+ return v instanceof Array;
+}
+
+function isStream(v) {
+ return typeof v === 'object' && v !== null && v.getBytes !== undefined;
+}
+
+function isArrayBuffer(v) {
+ return typeof v === 'object' && v !== null && v.byteLength !== undefined;
+}
+
+function isRef(v) {
+ return v instanceof Ref;
+}
+
+/**
+ * Promise Capability object.
+ *
+ * @typedef {Object} PromiseCapability
+ * @property {Promise} promise - A promise object.
+ * @property {function} resolve - Fullfills the promise.
+ * @property {function} reject - Rejects the promise.
+ */
+
+/**
+ * Creates a promise capability object.
+ * @alias PDFJS.createPromiseCapability
+ *
+ * @return {PromiseCapability} A capability object contains:
+ * - a Promise, resolve and reject methods.
+ */
+function createPromiseCapability() {
+ var capability = {};
+ capability.promise = new Promise(function (resolve, reject) {
+ capability.resolve = resolve;
+ capability.reject = reject;
+ });
+ return capability;
+}
+
+PDFJS.createPromiseCapability = createPromiseCapability;
+
+/**
+ * Polyfill for Promises:
+ * The following promise implementation tries to generally implement the
+ * Promise/A+ spec. Some notable differences from other promise libaries are:
+ * - There currently isn't a seperate deferred and promise object.
+ * - Unhandled rejections eventually show an error if they aren't handled.
+ *
+ * Based off of the work in:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=810490
+ */
+(function PromiseClosure() {
+ if (globalScope.Promise) {
+ // Promises existing in the DOM/Worker, checking presence of all/resolve
+ if (typeof globalScope.Promise.all !== 'function') {
+ globalScope.Promise.all = function (iterable) {
+ var count = 0, results = [], resolve, reject;
+ var promise = new globalScope.Promise(function (resolve_, reject_) {
+ resolve = resolve_;
+ reject = reject_;
+ });
+ iterable.forEach(function (p, i) {
+ count++;
+ p.then(function (result) {
+ results[i] = result;
+ count--;
+ if (count === 0) {
+ resolve(results);
+ }
+ }, reject);
+ });
+ if (count === 0) {
+ resolve(results);
+ }
+ return promise;
+ };
+ }
+ if (typeof globalScope.Promise.resolve !== 'function') {
+ globalScope.Promise.resolve = function (value) {
+ return new globalScope.Promise(function (resolve) { resolve(value); });
+ };
+ }
+ if (typeof globalScope.Promise.reject !== 'function') {
+ globalScope.Promise.reject = function (reason) {
+ return new globalScope.Promise(function (resolve, reject) {
+ reject(reason);
+ });
+ };
+ }
+ if (typeof globalScope.Promise.prototype.catch !== 'function') {
+ globalScope.Promise.prototype.catch = function (onReject) {
+ return globalScope.Promise.prototype.then(undefined, onReject);
+ };
+ }
+ return;
+ }
+ var STATUS_PENDING = 0;
+ var STATUS_RESOLVED = 1;
+ var STATUS_REJECTED = 2;
+
+ // In an attempt to avoid silent exceptions, unhandled rejections are
+ // tracked and if they aren't handled in a certain amount of time an
+ // error is logged.
+ var REJECTION_TIMEOUT = 500;
+
+ var HandlerManager = {
+ handlers: [],
+ running: false,
+ unhandledRejections: [],
+ pendingRejectionCheck: false,
+
+ scheduleHandlers: function scheduleHandlers(promise) {
+ if (promise._status === STATUS_PENDING) {
+ return;
+ }
+
+ this.handlers = this.handlers.concat(promise._handlers);
+ promise._handlers = [];
+
+ if (this.running) {
+ return;
+ }
+ this.running = true;
+
+ setTimeout(this.runHandlers.bind(this), 0);
+ },
+
+ runHandlers: function runHandlers() {
+ var RUN_TIMEOUT = 1; // ms
+ var timeoutAt = Date.now() + RUN_TIMEOUT;
+ while (this.handlers.length > 0) {
+ var handler = this.handlers.shift();
+
+ var nextStatus = handler.thisPromise._status;
+ var nextValue = handler.thisPromise._value;
+
+ try {
+ if (nextStatus === STATUS_RESOLVED) {
+ if (typeof handler.onResolve === 'function') {
+ nextValue = handler.onResolve(nextValue);
+ }
+ } else if (typeof handler.onReject === 'function') {
+ nextValue = handler.onReject(nextValue);
+ nextStatus = STATUS_RESOLVED;
+
+ if (handler.thisPromise._unhandledRejection) {
+ this.removeUnhandeledRejection(handler.thisPromise);
+ }
+ }
+ } catch (ex) {
+ nextStatus = STATUS_REJECTED;
+ nextValue = ex;
+ }
+
+ handler.nextPromise._updateStatus(nextStatus, nextValue);
+ if (Date.now() >= timeoutAt) {
+ break;
+ }
+ }
+
+ if (this.handlers.length > 0) {
+ setTimeout(this.runHandlers.bind(this), 0);
+ return;
+ }
+
+ this.running = false;
+ },
+
+ addUnhandledRejection: function addUnhandledRejection(promise) {
+ this.unhandledRejections.push({
+ promise: promise,
+ time: Date.now()
+ });
+ this.scheduleRejectionCheck();
+ },
+
+ removeUnhandeledRejection: function removeUnhandeledRejection(promise) {
+ promise._unhandledRejection = false;
+ for (var i = 0; i < this.unhandledRejections.length; i++) {
+ if (this.unhandledRejections[i].promise === promise) {
+ this.unhandledRejections.splice(i);
+ i--;
+ }
+ }
+ },
+
+ scheduleRejectionCheck: function scheduleRejectionCheck() {
+ if (this.pendingRejectionCheck) {
+ return;
+ }
+ this.pendingRejectionCheck = true;
+ setTimeout(function rejectionCheck() {
+ this.pendingRejectionCheck = false;
+ var now = Date.now();
+ for (var i = 0; i < this.unhandledRejections.length; i++) {
+ if (now - this.unhandledRejections[i].time > REJECTION_TIMEOUT) {
+ var unhandled = this.unhandledRejections[i].promise._value;
+ var msg = 'Unhandled rejection: ' + unhandled;
+ if (unhandled.stack) {
+ msg += '\n' + unhandled.stack;
+ }
+ warn(msg);
+ this.unhandledRejections.splice(i);
+ i--;
+ }
+ }
+ if (this.unhandledRejections.length) {
+ this.scheduleRejectionCheck();
+ }
+ }.bind(this), REJECTION_TIMEOUT);
+ }
+ };
+
+ function Promise(resolver) {
+ this._status = STATUS_PENDING;
+ this._handlers = [];
+ try {
+ resolver.call(this, this._resolve.bind(this), this._reject.bind(this));
+ } catch (e) {
+ this._reject(e);
+ }
+ }
+ /**
+ * Builds a promise that is resolved when all the passed in promises are
+ * resolved.
+ * @param {array} array of data and/or promises to wait for.
+ * @return {Promise} New dependant promise.
+ */
+ Promise.all = function Promise_all(promises) {
+ var resolveAll, rejectAll;
+ var deferred = new Promise(function (resolve, reject) {
+ resolveAll = resolve;
+ rejectAll = reject;
+ });
+ var unresolved = promises.length;
+ var results = [];
+ if (unresolved === 0) {
+ resolveAll(results);
+ return deferred;
+ }
+ function reject(reason) {
+ if (deferred._status === STATUS_REJECTED) {
+ return;
+ }
+ results = [];
+ rejectAll(reason);
+ }
+ for (var i = 0, ii = promises.length; i < ii; ++i) {
+ var promise = promises[i];
+ var resolve = (function(i) {
+ return function(value) {
+ if (deferred._status === STATUS_REJECTED) {
+ return;
+ }
+ results[i] = value;
+ unresolved--;
+ if (unresolved === 0) {
+ resolveAll(results);
+ }
+ };
+ })(i);
+ if (Promise.isPromise(promise)) {
+ promise.then(resolve, reject);
+ } else {
+ resolve(promise);
+ }
+ }
+ return deferred;
+ };
+
+ /**
+ * Checks if the value is likely a promise (has a 'then' function).
+ * @return {boolean} true if value is thenable
+ */
+ Promise.isPromise = function Promise_isPromise(value) {
+ return value && typeof value.then === 'function';
+ };
+
+ /**
+ * Creates resolved promise
+ * @param value resolve value
+ * @returns {Promise}
+ */
+ Promise.resolve = function Promise_resolve(value) {
+ return new Promise(function (resolve) { resolve(value); });
+ };
+
+ /**
+ * Creates rejected promise
+ * @param reason rejection value
+ * @returns {Promise}
+ */
+ Promise.reject = function Promise_reject(reason) {
+ return new Promise(function (resolve, reject) { reject(reason); });
+ };
+
+ Promise.prototype = {
+ _status: null,
+ _value: null,
+ _handlers: null,
+ _unhandledRejection: null,
+
+ _updateStatus: function Promise__updateStatus(status, value) {
+ if (this._status === STATUS_RESOLVED ||
+ this._status === STATUS_REJECTED) {
+ return;
+ }
+
+ if (status === STATUS_RESOLVED &&
+ Promise.isPromise(value)) {
+ value.then(this._updateStatus.bind(this, STATUS_RESOLVED),
+ this._updateStatus.bind(this, STATUS_REJECTED));
+ return;
+ }
+
+ this._status = status;
+ this._value = value;
+
+ if (status === STATUS_REJECTED && this._handlers.length === 0) {
+ this._unhandledRejection = true;
+ HandlerManager.addUnhandledRejection(this);
+ }
+
+ HandlerManager.scheduleHandlers(this);
+ },
+
+ _resolve: function Promise_resolve(value) {
+ this._updateStatus(STATUS_RESOLVED, value);
+ },
+
+ _reject: function Promise_reject(reason) {
+ this._updateStatus(STATUS_REJECTED, reason);
+ },
+
+ then: function Promise_then(onResolve, onReject) {
+ var nextPromise = new Promise(function (resolve, reject) {
+ this.resolve = resolve;
+ this.reject = reject;
+ });
+ this._handlers.push({
+ thisPromise: this,
+ onResolve: onResolve,
+ onReject: onReject,
+ nextPromise: nextPromise
+ });
+ HandlerManager.scheduleHandlers(this);
+ return nextPromise;
+ },
+
+ catch: function Promise_catch(onReject) {
+ return this.then(undefined, onReject);
+ }
+ };
+
+ globalScope.Promise = Promise;
+})();
+
+var StatTimer = (function StatTimerClosure() {
+ function rpad(str, pad, length) {
+ while (str.length < length) {
+ str += pad;
+ }
+ return str;
+ }
+ function StatTimer() {
+ this.started = {};
+ this.times = [];
+ this.enabled = true;
+ }
+ StatTimer.prototype = {
+ time: function StatTimer_time(name) {
+ if (!this.enabled) {
+ return;
+ }
+ if (name in this.started) {
+ warn('Timer is already running for ' + name);
+ }
+ this.started[name] = Date.now();
+ },
+ timeEnd: function StatTimer_timeEnd(name) {
+ if (!this.enabled) {
+ return;
+ }
+ if (!(name in this.started)) {
+ warn('Timer has not been started for ' + name);
+ }
+ this.times.push({
+ 'name': name,
+ 'start': this.started[name],
+ 'end': Date.now()
+ });
+ // Remove timer from started so it can be called again.
+ delete this.started[name];
+ },
+ toString: function StatTimer_toString() {
+ var i, ii;
+ var times = this.times;
+ var out = '';
+ // Find the longest name for padding purposes.
+ var longest = 0;
+ for (i = 0, ii = times.length; i < ii; ++i) {
+ var name = times[i]['name'];
+ if (name.length > longest) {
+ longest = name.length;
+ }
+ }
+ for (i = 0, ii = times.length; i < ii; ++i) {
+ var span = times[i];
+ var duration = span.end - span.start;
+ out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
+ }
+ return out;
+ }
+ };
+ return StatTimer;
+})();
+
+PDFJS.createBlob = function createBlob(data, contentType) {
+ if (typeof Blob !== 'undefined') {
+ return new Blob([data], { type: contentType });
+ }
+ // Blob builder is deprecated in FF14 and removed in FF18.
+ var bb = new MozBlobBuilder();
+ bb.append(data);
+ return bb.getBlob(contentType);
+};
+
+PDFJS.createObjectURL = (function createObjectURLClosure() {
+ // Blob/createObjectURL is not available, falling back to data schema.
+ var digits =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+
+ return function createObjectURL(data, contentType) {
+ if (!PDFJS.disableCreateObjectURL &&
+ typeof URL !== 'undefined' && URL.createObjectURL) {
+ var blob = PDFJS.createBlob(data, contentType);
+ return URL.createObjectURL(blob);
+ }
+
+ var buffer = 'data:' + contentType + ';base64,';
+ for (var i = 0, ii = data.length; i < ii; i += 3) {
+ var b1 = data[i] & 0xFF;
+ var b2 = data[i + 1] & 0xFF;
+ var b3 = data[i + 2] & 0xFF;
+ var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
+ var d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
+ var d4 = i + 2 < ii ? (b3 & 0x3F) : 64;
+ buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
+ }
+ return buffer;
+ };
+})();
+
+function MessageHandler(name, comObj) {
+ this.name = name;
+ this.comObj = comObj;
+ this.callbackIndex = 1;
+ this.postMessageTransfers = true;
+ var callbacksCapabilities = this.callbacksCapabilities = {};
+ var ah = this.actionHandler = {};
+
+ ah['console_log'] = [function ahConsoleLog(data) {
+ console.log.apply(console, data);
+ }];
+ ah['console_error'] = [function ahConsoleError(data) {
+ console.error.apply(console, data);
+ }];
+ ah['_unsupported_feature'] = [function ah_unsupportedFeature(data) {
+ UnsupportedManager.notify(data);
+ }];
+
+ comObj.onmessage = function messageHandlerComObjOnMessage(event) {
+ var data = event.data;
+ if (data.isReply) {
+ var callbackId = data.callbackId;
+ if (data.callbackId in callbacksCapabilities) {
+ var callback = callbacksCapabilities[callbackId];
+ delete callbacksCapabilities[callbackId];
+ if ('error' in data) {
+ callback.reject(data.error);
+ } else {
+ callback.resolve(data.data);
+ }
+ } else {
+ error('Cannot resolve callback ' + callbackId);
+ }
+ } else if (data.action in ah) {
+ var action = ah[data.action];
+ if (data.callbackId) {
+ Promise.resolve().then(function () {
+ return action[0].call(action[1], data.data);
+ }).then(function (result) {
+ comObj.postMessage({
+ isReply: true,
+ callbackId: data.callbackId,
+ data: result
+ });
+ }, function (reason) {
+ comObj.postMessage({
+ isReply: true,
+ callbackId: data.callbackId,
+ error: reason
+ });
+ });
+ } else {
+ action[0].call(action[1], data.data);
+ }
+ } else {
+ error('Unknown action from worker: ' + data.action);
+ }
+ };
+}
+
+MessageHandler.prototype = {
+ on: function messageHandlerOn(actionName, handler, scope) {
+ var ah = this.actionHandler;
+ if (ah[actionName]) {
+ error('There is already an actionName called "' + actionName + '"');
+ }
+ ah[actionName] = [handler, scope];
+ },
+ /**
+ * Sends a message to the comObj to invoke the action with the supplied data.
+ * @param {String} actionName Action to call.
+ * @param {JSON} data JSON data to send.
+ * @param {Array} [transfers] Optional list of transfers/ArrayBuffers
+ */
+ send: function messageHandlerSend(actionName, data, transfers) {
+ var message = {
+ action: actionName,
+ data: data
+ };
+ this.postMessage(message, transfers);
+ },
+ /**
+ * Sends a message to the comObj to invoke the action with the supplied data.
+ * Expects that other side will callback with the response.
+ * @param {String} actionName Action to call.
+ * @param {JSON} data JSON data to send.
+ * @param {Array} [transfers] Optional list of transfers/ArrayBuffers.
+ * @returns {Promise} Promise to be resolved with response data.
+ */
+ sendWithPromise:
+ function messageHandlerSendWithPromise(actionName, data, transfers) {
+ var callbackId = this.callbackIndex++;
+ var message = {
+ action: actionName,
+ data: data,
+ callbackId: callbackId
+ };
+ var capability = createPromiseCapability();
+ this.callbacksCapabilities[callbackId] = capability;
+ try {
+ this.postMessage(message, transfers);
+ } catch (e) {
+ capability.reject(e);
+ }
+ return capability.promise;
+ },
+ /**
+ * Sends raw message to the comObj.
+ * @private
+ * @param message {Object} Raw message.
+ * @param transfers List of transfers/ArrayBuffers, or undefined.
+ */
+ postMessage: function (message, transfers) {
+ if (transfers && this.postMessageTransfers) {
+ this.comObj.postMessage(message, transfers);
+ } else {
+ this.comObj.postMessage(message);
+ }
+ }
+};
+
+function loadJpegStream(id, imageUrl, objs) {
+ var img = new Image();
+ img.onload = (function loadJpegStream_onloadClosure() {
+ objs.resolve(id, img);
+ });
+ img.onerror = (function loadJpegStream_onerrorClosure() {
+ objs.resolve(id, null);
+ warn('Error during JPEG image loading');
+ });
+ img.src = imageUrl;
+}
+
+
+/**
+ * The maximum allowed image size in total pixels e.g. width * height. Images
+ * above this value will not be drawn. Use -1 for no limit.
+ * @var {number}
+ */
+PDFJS.maxImageSize = (PDFJS.maxImageSize === undefined ?
+ -1 : PDFJS.maxImageSize);
+
+/**
+ * The url of where the predefined Adobe CMaps are located. Include trailing
+ * slash.
+ * @var {string}
+ */
+PDFJS.cMapUrl = (PDFJS.cMapUrl === undefined ? null : PDFJS.cMapUrl);
+
+/**
+ * Specifies if CMaps are binary packed.
+ * @var {boolean}
+ */
+PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked;
+
+/**
+ * By default fonts are converted to OpenType fonts and loaded via font face
+ * rules. If disabled, the font will be rendered using a built in font renderer
+ * that constructs the glyphs with primitive path commands.
+ * @var {boolean}
+ */
+PDFJS.disableFontFace = (PDFJS.disableFontFace === undefined ?
+ false : PDFJS.disableFontFace);
+
+/**
+ * Path for image resources, mainly for annotation icons. Include trailing
+ * slash.
+ * @var {string}
+ */
+PDFJS.imageResourcesPath = (PDFJS.imageResourcesPath === undefined ?
+ '' : PDFJS.imageResourcesPath);
+
+/**
+ * Disable the web worker and run all code on the main thread. This will happen
+ * automatically if the browser doesn't support workers or sending typed arrays
+ * to workers.
+ * @var {boolean}
+ */
+PDFJS.disableWorker = (PDFJS.disableWorker === undefined ?
+ false : PDFJS.disableWorker);
+
+/**
+ * Path and filename of the worker file. Required when the worker is enabled in
+ * development mode. If unspecified in the production build, the worker will be
+ * loaded based on the location of the pdf.js file.
+ * @var {string}
+ */
+PDFJS.workerSrc = (PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc);
+
+/**
+ * Disable range request loading of PDF files. When enabled and if the server
+ * supports partial content requests then the PDF will be fetched in chunks.
+ * Enabled (false) by default.
+ * @var {boolean}
+ */
+PDFJS.disableRange = (PDFJS.disableRange === undefined ?
+ false : PDFJS.disableRange);
+
+/**
+ * Disable streaming of PDF file data. By default PDF.js attempts to load PDF
+ * in chunks. This default behavior can be disabled.
+ * @var {boolean}
+ */
+PDFJS.disableStream = (PDFJS.disableStream === undefined ?
+ false : PDFJS.disableStream);
+
+/**
+ * Disable pre-fetching of PDF file data. When range requests are enabled PDF.js
+ * will automatically keep fetching more data even if it isn't needed to display
+ * the current page. This default behavior can be disabled.
+ *
+ * NOTE: It is also necessary to disable streaming, see above,
+ * in order for disabling of pre-fetching to work correctly.
+ * @var {boolean}
+ */
+PDFJS.disableAutoFetch = (PDFJS.disableAutoFetch === undefined ?
+ false : PDFJS.disableAutoFetch);
+
+/**
+ * Enables special hooks for debugging PDF.js.
+ * @var {boolean}
+ */
+PDFJS.pdfBug = (PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug);
+
+/**
+ * Enables transfer usage in postMessage for ArrayBuffers.
+ * @var {boolean}
+ */
+PDFJS.postMessageTransfers = (PDFJS.postMessageTransfers === undefined ?
+ true : PDFJS.postMessageTransfers);
+
+/**
+ * Disables URL.createObjectURL usage.
+ * @var {boolean}
+ */
+PDFJS.disableCreateObjectURL = (PDFJS.disableCreateObjectURL === undefined ?
+ false : PDFJS.disableCreateObjectURL);
+
+/**
+ * Disables WebGL usage.
+ * @var {boolean}
+ */
+PDFJS.disableWebGL = (PDFJS.disableWebGL === undefined ?
+ true : PDFJS.disableWebGL);
+
+/**
+ * Disables fullscreen support, and by extension Presentation Mode,
+ * in browsers which support the fullscreen API.
+ * @var {boolean}
+ */
+PDFJS.disableFullscreen = (PDFJS.disableFullscreen === undefined ?
+ false : PDFJS.disableFullscreen);
+
+/**
+ * Enables CSS only zooming.
+ * @var {boolean}
+ */
+PDFJS.useOnlyCssZoom = (PDFJS.useOnlyCssZoom === undefined ?
+ false : PDFJS.useOnlyCssZoom);
+
+/**
+ * Controls the logging level.
+ * The constants from PDFJS.VERBOSITY_LEVELS should be used:
+ * - errors
+ * - warnings [default]
+ * - infos
+ * @var {number}
+ */
+PDFJS.verbosity = (PDFJS.verbosity === undefined ?
+ PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity);
+
+/**
+ * The maximum supported canvas size in total pixels e.g. width * height.
+ * The default value is 4096 * 4096. Use -1 for no limit.
+ * @var {number}
+ */
+PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
+ 16777216 : PDFJS.maxCanvasPixels);
+
+/**
+ * Opens external links in a new window if enabled. The default behavior opens
+ * external links in the PDF.js window.
+ * @var {boolean}
+ */
+PDFJS.openExternalLinksInNewWindow = (
+ PDFJS.openExternalLinksInNewWindow === undefined ?
+ false : PDFJS.openExternalLinksInNewWindow);
+
+/**
+ * Document initialization / loading parameters object.
+ *
+ * @typedef {Object} DocumentInitParameters
+ * @property {string} url - The URL of the PDF.
+ * @property {TypedArray|Array|string} data - Binary PDF data. Use typed arrays
+ * (Uint8Array) to improve the memory usage. If PDF data is BASE64-encoded,
+ * use atob() to convert it to a binary string first.
+ * @property {Object} httpHeaders - Basic authentication headers.
+ * @property {boolean} withCredentials - Indicates whether or not cross-site
+ * Access-Control requests should be made using credentials such as cookies
+ * or authorization headers. The default is false.
+ * @property {string} password - For decrypting password-protected PDFs.
+ * @property {TypedArray} initialData - A typed array with the first portion or
+ * all of the pdf data. Used by the extension since some data is already
+ * loaded before the switch to range requests.
+ * @property {number} length - The PDF file length. It's used for progress
+ * reports and range requests operations.
+ * @property {PDFDataRangeTransport} range
+ */
+
+/**
+ * @typedef {Object} PDFDocumentStats
+ * @property {Array} streamTypes - Used stream types in the document (an item
+ * is set to true if specific stream ID was used in the document).
+ * @property {Array} fontTypes - Used font type in the document (an item is set
+ * to true if specific font ID was used in the document).
+ */
+
+/**
+ * This is the main entry point for loading a PDF and interacting with it.
+ * NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)
+ * is used, which means it must follow the same origin rules that any XHR does
+ * e.g. No cross domain requests without CORS.
+ *
+ * @param {string|TypedArray|DocumentInitParameters|PDFDataRangeTransport} src
+ * Can be a url to where a PDF is located, a typed array (Uint8Array)
+ * already populated with data or parameter object.
+ *
+ * @param {PDFDataRangeTransport} pdfDataRangeTransport (deprecated) It is used
+ * if you want to manually serve range requests for data in the PDF.
+ *
+ * @param {function} passwordCallback (deprecated) It is used to request a
+ * password if wrong or no password was provided. The callback receives two
+ * parameters: function that needs to be called with new password and reason
+ * (see {PasswordResponses}).
+ *
+ * @param {function} progressCallback (deprecated) It is used to be able to
+ * monitor the loading progress of the PDF file (necessary to implement e.g.
+ * a loading bar). The callback receives an {Object} with the properties:
+ * {number} loaded and {number} total.
+ *
+ * @return {PDFDocumentLoadingTask}
+ */
+PDFJS.getDocument = function getDocument(src,
+ pdfDataRangeTransport,
+ passwordCallback,
+ progressCallback) {
+ var task = new PDFDocumentLoadingTask();
+
+ // Support of the obsolete arguments (for compatibility with API v1.0)
+ if (pdfDataRangeTransport) {
+ if (!(pdfDataRangeTransport instanceof PDFDataRangeTransport)) {
+ // Not a PDFDataRangeTransport instance, trying to add missing properties.
+ pdfDataRangeTransport = Object.create(pdfDataRangeTransport);
+ pdfDataRangeTransport.length = src.length;
+ pdfDataRangeTransport.initialData = src.initialData;
+ }
+ src = Object.create(src);
+ src.range = pdfDataRangeTransport;
+ }
+ task.onPassword = passwordCallback || null;
+ task.onProgress = progressCallback || null;
+
+ var workerInitializedCapability, transport;
+ var source;
+ if (typeof src === 'string') {
+ source = { url: src };
+ } else if (isArrayBuffer(src)) {
+ source = { data: src };
+ } else if (src instanceof PDFDataRangeTransport) {
+ source = { range: src };
+ } else {
+ if (typeof src !== 'object') {
+ error('Invalid parameter in getDocument, need either Uint8Array, ' +
+ 'string or a parameter object');
+ }
+ if (!src.url && !src.data && !src.range) {
+ error('Invalid parameter object: need either .data, .range or .url');
+ }
+
+ source = src;
+ }
+
+ var params = {};
+ for (var key in source) {
+ if (key === 'url' && typeof window !== 'undefined') {
+ // The full path is required in the 'url' field.
+ params[key] = combineUrl(window.location.href, source[key]);
+ continue;
+ } else if (key === 'range') {
+ continue;
+ } else if (key === 'data' && !(source[key] instanceof Uint8Array)) {
+ // Converting string or array-like data to Uint8Array.
+ var pdfBytes = source[key];
+ if (typeof pdfBytes === 'string') {
+ params[key] = stringToBytes(pdfBytes);
+ } else if (typeof pdfBytes === 'object' && pdfBytes !== null &&
+ !isNaN(pdfBytes.length)) {
+ params[key] = new Uint8Array(pdfBytes);
+ } else {
+ error('Invalid PDF binary data: either typed array, string or ' +
+ 'array-like object is expected in the data property.');
+ }
+ continue;
+ }
+ params[key] = source[key];
+ }
+
+ workerInitializedCapability = createPromiseCapability();
+ transport = new WorkerTransport(workerInitializedCapability, source.range);
+ workerInitializedCapability.promise.then(function transportInitialized() {
+ transport.fetchDocument(task, params);
+ });
+
+ return task;
+};
+
+/**
+ * PDF document loading operation.
+ * @class
+ */
+var PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() {
+ /** @constructs PDFDocumentLoadingTask */
+ function PDFDocumentLoadingTask() {
+ this._capability = createPromiseCapability();
+
+ /**
+ * Callback to request a password if wrong or no password was provided.
+ * The callback receives two parameters: function that needs to be called
+ * with new password and reason (see {PasswordResponses}).
+ */
+ this.onPassword = null;
+
+ /**
+ * Callback to be able to monitor the loading progress of the PDF file
+ * (necessary to implement e.g. a loading bar). The callback receives
+ * an {Object} with the properties: {number} loaded and {number} total.
+ */
+ this.onProgress = null;
+ }
+
+ PDFDocumentLoadingTask.prototype =
+ /** @lends PDFDocumentLoadingTask.prototype */ {
+ /**
+ * @return {Promise}
+ */
+ get promise() {
+ return this._capability.promise;
+ },
+
+ // TODO add cancel or abort method
+
+ /**
+ * Registers callbacks to indicate the document loading completion.
+ *
+ * @param {function} onFulfilled The callback for the loading completion.
+ * @param {function} onRejected The callback for the loading failure.
+ * @return {Promise} A promise that is resolved after the onFulfilled or
+ * onRejected callback.
+ */
+ then: function PDFDocumentLoadingTask_then(onFulfilled, onRejected) {
+ return this.promise.then.apply(this.promise, arguments);
+ }
+ };
+
+ return PDFDocumentLoadingTask;
+})();
+
+/**
+ * Abstract class to support range requests file loading.
+ * @class
+ */
+var PDFDataRangeTransport = (function pdfDataRangeTransportClosure() {
+ /**
+ * @constructs PDFDataRangeTransport
+ * @param {number} length
+ * @param {Uint8Array} initialData
+ */
+ function PDFDataRangeTransport(length, initialData) {
+ this.length = length;
+ this.initialData = initialData;
+
+ this._rangeListeners = [];
+ this._progressListeners = [];
+ this._progressiveReadListeners = [];
+ this._readyCapability = createPromiseCapability();
+ }
+ PDFDataRangeTransport.prototype =
+ /** @lends PDFDataRangeTransport.prototype */ {
+ addRangeListener:
+ function PDFDataRangeTransport_addRangeListener(listener) {
+ this._rangeListeners.push(listener);
+ },
+
+ addProgressListener:
+ function PDFDataRangeTransport_addProgressListener(listener) {
+ this._progressListeners.push(listener);
+ },
+
+ addProgressiveReadListener:
+ function PDFDataRangeTransport_addProgressiveReadListener(listener) {
+ this._progressiveReadListeners.push(listener);
+ },
+
+ onDataRange: function PDFDataRangeTransport_onDataRange(begin, chunk) {
+ var listeners = this._rangeListeners;
+ for (var i = 0, n = listeners.length; i < n; ++i) {
+ listeners[i](begin, chunk);
+ }
+ },
+
+ onDataProgress: function PDFDataRangeTransport_onDataProgress(loaded) {
+ this._readyCapability.promise.then(function () {
+ var listeners = this._progressListeners;
+ for (var i = 0, n = listeners.length; i < n; ++i) {
+ listeners[i](loaded);
+ }
+ }.bind(this));
+ },
+
+ onDataProgressiveRead:
+ function PDFDataRangeTransport_onDataProgress(chunk) {
+ this._readyCapability.promise.then(function () {
+ var listeners = this._progressiveReadListeners;
+ for (var i = 0, n = listeners.length; i < n; ++i) {
+ listeners[i](chunk);
+ }
+ }.bind(this));
+ },
+
+ transportReady: function PDFDataRangeTransport_transportReady() {
+ this._readyCapability.resolve();
+ },
+
+ requestDataRange:
+ function PDFDataRangeTransport_requestDataRange(begin, end) {
+ throw new Error('Abstract method PDFDataRangeTransport.requestDataRange');
+ }
+ };
+ return PDFDataRangeTransport;
+})();
+
+PDFJS.PDFDataRangeTransport = PDFDataRangeTransport;
+
+/**
+ * Proxy to a PDFDocument in the worker thread. Also, contains commonly used
+ * properties that can be read synchronously.
+ * @class
+ */
+var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
+ function PDFDocumentProxy(pdfInfo, transport) {
+ this.pdfInfo = pdfInfo;
+ this.transport = transport;
+ }
+ PDFDocumentProxy.prototype = /** @lends PDFDocumentProxy.prototype */ {
+ /**
+ * @return {number} Total number of pages the PDF contains.
+ */
+ get numPages() {
+ return this.pdfInfo.numPages;
+ },
+ /**
+ * @return {string} A unique ID to identify a PDF. Not guaranteed to be
+ * unique.
+ */
+ get fingerprint() {
+ return this.pdfInfo.fingerprint;
+ },
+ /**
+ * @param {number} pageNumber The page number to get. The first page is 1.
+ * @return {Promise} A promise that is resolved with a {@link PDFPageProxy}
+ * object.
+ */
+ getPage: function PDFDocumentProxy_getPage(pageNumber) {
+ return this.transport.getPage(pageNumber);
+ },
+ /**
+ * @param {{num: number, gen: number}} ref The page reference. Must have
+ * the 'num' and 'gen' properties.
+ * @return {Promise} A promise that is resolved with the page index that is
+ * associated with the reference.
+ */
+ getPageIndex: function PDFDocumentProxy_getPageIndex(ref) {
+ return this.transport.getPageIndex(ref);
+ },
+ /**
+ * @return {Promise} A promise that is resolved with a lookup table for
+ * mapping named destinations to reference numbers.
+ *
+ * This can be slow for large documents: use getDestination instead
+ */
+ getDestinations: function PDFDocumentProxy_getDestinations() {
+ return this.transport.getDestinations();
+ },
+ /**
+ * @param {string} id The named destination to get.
+ * @return {Promise} A promise that is resolved with all information
+ * of the given named destination.
+ */
+ getDestination: function PDFDocumentProxy_getDestination(id) {
+ return this.transport.getDestination(id);
+ },
+ /**
+ * @return {Promise} A promise that is resolved with a lookup table for
+ * mapping named attachments to their content.
+ */
+ getAttachments: function PDFDocumentProxy_getAttachments() {
+ return this.transport.getAttachments();
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an array of all the
+ * JavaScript strings in the name tree.
+ */
+ getJavaScript: function PDFDocumentProxy_getJavaScript() {
+ return this.transport.getJavaScript();
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an {Array} that is a
+ * tree outline (if it has one) of the PDF. The tree is in the format of:
+ * [
+ * {
+ * title: string,
+ * bold: boolean,
+ * italic: boolean,
+ * color: rgb array,
+ * dest: dest obj,
+ * items: array of more items like this
+ * },
+ * ...
+ * ].
+ */
+ getOutline: function PDFDocumentProxy_getOutline() {
+ return this.transport.getOutline();
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an {Object} that has
+ * info and metadata properties. Info is an {Object} filled with anything
+ * available in the information dictionary and similarly metadata is a
+ * {Metadata} object with information from the metadata section of the PDF.
+ */
+ getMetadata: function PDFDocumentProxy_getMetadata() {
+ return this.transport.getMetadata();
+ },
+ /**
+ * @return {Promise} A promise that is resolved with a TypedArray that has
+ * the raw data from the PDF.
+ */
+ getData: function PDFDocumentProxy_getData() {
+ return this.transport.getData();
+ },
+ /**
+ * @return {Promise} A promise that is resolved when the document's data
+ * is loaded. It is resolved with an {Object} that contains the length
+ * property that indicates size of the PDF data in bytes.
+ */
+ getDownloadInfo: function PDFDocumentProxy_getDownloadInfo() {
+ return this.transport.downloadInfoCapability.promise;
+ },
+ /**
+ * @return {Promise} A promise this is resolved with current stats about
+ * document structures (see {@link PDFDocumentStats}).
+ */
+ getStats: function PDFDocumentProxy_getStats() {
+ return this.transport.getStats();
+ },
+ /**
+ * Cleans up resources allocated by the document, e.g. created @font-face.
+ */
+ cleanup: function PDFDocumentProxy_cleanup() {
+ this.transport.startCleanup();
+ },
+ /**
+ * Destroys current document instance and terminates worker.
+ */
+ destroy: function PDFDocumentProxy_destroy() {
+ this.transport.destroy();
+ }
+ };
+ return PDFDocumentProxy;
+})();
+
+/**
+ * Page text content.
+ *
+ * @typedef {Object} TextContent
+ * @property {array} items - array of {@link TextItem}
+ * @property {Object} styles - {@link TextStyles} objects, indexed by font
+ * name.
+ */
+
+/**
+ * Page text content part.
+ *
+ * @typedef {Object} TextItem
+ * @property {string} str - text content.
+ * @property {string} dir - text direction: 'ttb', 'ltr' or 'rtl'.
+ * @property {array} transform - transformation matrix.
+ * @property {number} width - width in device space.
+ * @property {number} height - height in device space.
+ * @property {string} fontName - font name used by pdf.js for converted font.
+ */
+
+/**
+ * Text style.
+ *
+ * @typedef {Object} TextStyle
+ * @property {number} ascent - font ascent.
+ * @property {number} descent - font descent.
+ * @property {boolean} vertical - text is in vertical mode.
+ * @property {string} fontFamily - possible font family
+ */
+
+/**
+ * Page render parameters.
+ *
+ * @typedef {Object} RenderParameters
+ * @property {Object} canvasContext - A 2D context of a DOM Canvas object.
+ * @property {PDFJS.PageViewport} viewport - Rendering viewport obtained by
+ * calling of PDFPage.getViewport method.
+ * @property {string} intent - Rendering intent, can be 'display' or 'print'
+ * (default value is 'display').
+ * @property {Object} imageLayer - (optional) An object that has beginLayout,
+ * endLayout and appendImage functions.
+ * @property {function} continueCallback - (deprecated) A function that will be
+ * called each time the rendering is paused. To continue
+ * rendering call the function that is the first argument
+ * to the callback.
+ */
+
+/**
+ * PDF page operator list.
+ *
+ * @typedef {Object} PDFOperatorList
+ * @property {Array} fnArray - Array containing the operator functions.
+ * @property {Array} argsArray - Array containing the arguments of the
+ * functions.
+ */
+
+/**
+ * Proxy to a PDFPage in the worker thread.
+ * @class
+ */
+var PDFPageProxy = (function PDFPageProxyClosure() {
+ function PDFPageProxy(pageIndex, pageInfo, transport) {
+ this.pageIndex = pageIndex;
+ this.pageInfo = pageInfo;
+ this.transport = transport;
+ this.stats = new StatTimer();
+ this.stats.enabled = !!globalScope.PDFJS.enableStats;
+ this.commonObjs = transport.commonObjs;
+ this.objs = new PDFObjects();
+ this.cleanupAfterRender = false;
+ this.pendingDestroy = false;
+ this.intentStates = {};
+ }
+ PDFPageProxy.prototype = /** @lends PDFPageProxy.prototype */ {
+ /**
+ * @return {number} Page number of the page. First page is 1.
+ */
+ get pageNumber() {
+ return this.pageIndex + 1;
+ },
+ /**
+ * @return {number} The number of degrees the page is rotated clockwise.
+ */
+ get rotate() {
+ return this.pageInfo.rotate;
+ },
+ /**
+ * @return {Object} The reference that points to this page. It has 'num' and
+ * 'gen' properties.
+ */
+ get ref() {
+ return this.pageInfo.ref;
+ },
+ /**
+ * @return {Array} An array of the visible portion of the PDF page in the
+ * user space units - [x1, y1, x2, y2].
+ */
+ get view() {
+ return this.pageInfo.view;
+ },
+ /**
+ * @param {number} scale The desired scale of the viewport.
+ * @param {number} rotate Degrees to rotate the viewport. If omitted this
+ * defaults to the page rotation.
+ * @return {PDFJS.PageViewport} Contains 'width' and 'height' properties
+ * along with transforms required for rendering.
+ */
+ getViewport: function PDFPageProxy_getViewport(scale, rotate) {
+ if (arguments.length < 2) {
+ rotate = this.rotate;
+ }
+ return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0);
+ },
+ /**
+ * @return {Promise} A promise that is resolved with an {Array} of the
+ * annotation objects.
+ */
+ getAnnotations: function PDFPageProxy_getAnnotations() {
+ if (this.annotationsPromise) {
+ return this.annotationsPromise;
+ }
+
+ var promise = this.transport.getAnnotations(this.pageIndex);
+ this.annotationsPromise = promise;
+ return promise;
+ },
+ /**
+ * Begins the process of rendering a page to the desired context.
+ * @param {RenderParameters} params Page render parameters.
+ * @return {RenderTask} An object that contains the promise, which
+ * is resolved when the page finishes rendering.
+ */
+ render: function PDFPageProxy_render(params) {
+ var stats = this.stats;
+ stats.time('Overall');
+
+ // If there was a pending destroy cancel it so no cleanup happens during
+ // this call to render.
+ this.pendingDestroy = false;
+
+ var renderingIntent = (params.intent === 'print' ? 'print' : 'display');
+
+ if (!this.intentStates[renderingIntent]) {
+ this.intentStates[renderingIntent] = {};
+ }
+ var intentState = this.intentStates[renderingIntent];
+
+ // If there's no displayReadyCapability yet, then the operatorList
+ // was never requested before. Make the request and create the promise.
+ if (!intentState.displayReadyCapability) {
+ intentState.receivingOperatorList = true;
+ intentState.displayReadyCapability = createPromiseCapability();
+ intentState.operatorList = {
+ fnArray: [],
+ argsArray: [],
+ lastChunk: false
+ };
+
+ this.stats.time('Page Request');
+ this.transport.messageHandler.send('RenderPageRequest', {
+ pageIndex: this.pageNumber - 1,
+ intent: renderingIntent
+ });
+ }
+
+ var internalRenderTask = new InternalRenderTask(complete, params,
+ this.objs,
+ this.commonObjs,
+ intentState.operatorList,
+ this.pageNumber);
+ if (!intentState.renderTasks) {
+ intentState.renderTasks = [];
+ }
+ intentState.renderTasks.push(internalRenderTask);
+ var renderTask = internalRenderTask.task;
+
+ // Obsolete parameter support
+ if (params.continueCallback) {
+ renderTask.onContinue = params.continueCallback;
+ }
+
+ var self = this;
+ intentState.displayReadyCapability.promise.then(
+ function pageDisplayReadyPromise(transparency) {
+ if (self.pendingDestroy) {
+ complete();
+ return;
+ }
+ stats.time('Rendering');
+ internalRenderTask.initalizeGraphics(transparency);
+ internalRenderTask.operatorListChanged();
+ },
+ function pageDisplayReadPromiseError(reason) {
+ complete(reason);
+ }
+ );
+
+ function complete(error) {
+ var i = intentState.renderTasks.indexOf(internalRenderTask);
+ if (i >= 0) {
+ intentState.renderTasks.splice(i, 1);
+ }
+
+ if (self.cleanupAfterRender) {
+ self.pendingDestroy = true;
+ }
+ self._tryDestroy();
+
+ if (error) {
+ internalRenderTask.capability.reject(error);
+ } else {
+ internalRenderTask.capability.resolve();
+ }
+ stats.timeEnd('Rendering');
+ stats.timeEnd('Overall');
+ }
+
+ return renderTask;
+ },
+
+ /**
+ * @return {Promise} A promise resolved with an {@link PDFOperatorList}
+ * object that represents page's operator list.
+ */
+ getOperatorList: function PDFPageProxy_getOperatorList() {
+ function operatorListChanged() {
+ if (intentState.operatorList.lastChunk) {
+ intentState.opListReadCapability.resolve(intentState.operatorList);
+ }
+ }
+
+ var renderingIntent = 'oplist';
+ if (!this.intentStates[renderingIntent]) {
+ this.intentStates[renderingIntent] = {};
+ }
+ var intentState = this.intentStates[renderingIntent];
+
+ if (!intentState.opListReadCapability) {
+ var opListTask = {};
+ opListTask.operatorListChanged = operatorListChanged;
+ intentState.receivingOperatorList = true;
+ intentState.opListReadCapability = createPromiseCapability();
+ intentState.renderTasks = [];
+ intentState.renderTasks.push(opListTask);
+ intentState.operatorList = {
+ fnArray: [],
+ argsArray: [],
+ lastChunk: false
+ };
+
+ this.transport.messageHandler.send('RenderPageRequest', {
+ pageIndex: this.pageIndex,
+ intent: renderingIntent
+ });
+ }
+ return intentState.opListReadCapability.promise;
+ },
+
+ /**
+ * @return {Promise} That is resolved a {@link TextContent}
+ * object that represent the page text content.
+ */
+ getTextContent: function PDFPageProxy_getTextContent() {
+ return this.transport.messageHandler.sendWithPromise('GetTextContent', {
+ pageIndex: this.pageNumber - 1
+ });
+ },
+ /**
+ * Destroys resources allocated by the page.
+ */
+ destroy: function PDFPageProxy_destroy() {
+ this.pendingDestroy = true;
+ this._tryDestroy();
+ },
+ /**
+ * For internal use only. Attempts to clean up if rendering is in a state
+ * where that's possible.
+ * @ignore
+ */
+ _tryDestroy: function PDFPageProxy__destroy() {
+ if (!this.pendingDestroy ||
+ Object.keys(this.intentStates).some(function(intent) {
+ var intentState = this.intentStates[intent];
+ return (intentState.renderTasks.length !== 0 ||
+ intentState.receivingOperatorList);
+ }, this)) {
+ return;
+ }
+
+ Object.keys(this.intentStates).forEach(function(intent) {
+ delete this.intentStates[intent];
+ }, this);
+ this.objs.clear();
+ this.annotationsPromise = null;
+ this.pendingDestroy = false;
+ },
+ /**
+ * For internal use only.
+ * @ignore
+ */
+ _startRenderPage: function PDFPageProxy_startRenderPage(transparency,
+ intent) {
+ var intentState = this.intentStates[intent];
+ // TODO Refactor RenderPageRequest to separate rendering
+ // and operator list logic
+ if (intentState.displayReadyCapability) {
+ intentState.displayReadyCapability.resolve(transparency);
+ }
+ },
+ /**
+ * For internal use only.
+ * @ignore
+ */
+ _renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk,
+ intent) {
+ var intentState = this.intentStates[intent];
+ var i, ii;
+ // Add the new chunk to the current operator list.
+ for (i = 0, ii = operatorListChunk.length; i < ii; i++) {
+ intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
+ intentState.operatorList.argsArray.push(
+ operatorListChunk.argsArray[i]);
+ }
+ intentState.operatorList.lastChunk = operatorListChunk.lastChunk;
+
+ // Notify all the rendering tasks there are more operators to be consumed.
+ for (i = 0; i < intentState.renderTasks.length; i++) {
+ intentState.renderTasks[i].operatorListChanged();
+ }
+
+ if (operatorListChunk.lastChunk) {
+ intentState.receivingOperatorList = false;
+ this._tryDestroy();
+ }
+ }
+ };
+ return PDFPageProxy;
+})();
+
+/**
+ * For internal use only.
+ * @ignore
+ */
+var WorkerTransport = (function WorkerTransportClosure() {
+ function WorkerTransport(workerInitializedCapability, pdfDataRangeTransport) {
+ this.pdfDataRangeTransport = pdfDataRangeTransport;
+ this.workerInitializedCapability = workerInitializedCapability;
+ this.commonObjs = new PDFObjects();
+
+ this.loadingTask = null;
+
+ this.pageCache = [];
+ this.pagePromises = [];
+ this.downloadInfoCapability = createPromiseCapability();
+
+ // If worker support isn't disabled explicit and the browser has worker
+ // support, create a new web worker and test if it/the browser fullfills
+ // all requirements to run parts of pdf.js in a web worker.
+ // Right now, the requirement is, that an Uint8Array is still an Uint8Array
+ // as it arrives on the worker. Chrome added this with version 15.
+ if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
+ var workerSrc = PDFJS.workerSrc;
+ if (!workerSrc) {
+ error('No PDFJS.workerSrc specified');
+ }
+
+ try {
+ // Some versions of FF can't create a worker on localhost, see:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=683280
+ var worker = new Worker(workerSrc);
+ var messageHandler = new MessageHandler('main', worker);
+ this.messageHandler = messageHandler;
+
+ messageHandler.on('test', function transportTest(data) {
+ var supportTypedArray = data && data.supportTypedArray;
+ if (supportTypedArray) {
+ this.worker = worker;
+ if (!data.supportTransfers) {
+ PDFJS.postMessageTransfers = false;
+ }
+ this.setupMessageHandler(messageHandler);
+ workerInitializedCapability.resolve();
+ } else {
+ this.setupFakeWorker();
+ }
+ }.bind(this));
+
+ var testObj = new Uint8Array([PDFJS.postMessageTransfers ? 255 : 0]);
+ // Some versions of Opera throw a DATA_CLONE_ERR on serializing the
+ // typed array. Also, checking if we can use transfers.
+ try {
+ messageHandler.send('test', testObj, [testObj.buffer]);
+ } catch (ex) {
+ info('Cannot use postMessage transfers');
+ testObj[0] = 0;
+ messageHandler.send('test', testObj);
+ }
+ return;
+ } catch (e) {
+ info('The worker has been disabled.');
+ }
+ }
+ // Either workers are disabled, not supported or have thrown an exception.
+ // Thus, we fallback to a faked worker.
+ this.setupFakeWorker();
+ }
+ WorkerTransport.prototype = {
+ destroy: function WorkerTransport_destroy() {
+ this.pageCache = [];
+ this.pagePromises = [];
+ var self = this;
+ this.messageHandler.sendWithPromise('Terminate', null).then(function () {
+ FontLoader.clear();
+ if (self.worker) {
+ self.worker.terminate();
+ }
+ });
+ },
+
+ setupFakeWorker: function WorkerTransport_setupFakeWorker() {
+ globalScope.PDFJS.disableWorker = true;
+
+ if (!PDFJS.fakeWorkerFilesLoadedCapability) {
+ PDFJS.fakeWorkerFilesLoadedCapability = createPromiseCapability();
+ // In the developer build load worker_loader which in turn loads all the
+ // other files and resolves the promise. In production only the
+ // pdf.worker.js file is needed.
+ Util.loadScript(PDFJS.workerSrc, function() {
+ PDFJS.fakeWorkerFilesLoadedCapability.resolve();
+ });
+ }
+ PDFJS.fakeWorkerFilesLoadedCapability.promise.then(function () {
+ warn('Setting up fake worker.');
+ // If we don't use a worker, just post/sendMessage to the main thread.
+ var fakeWorker = {
+ postMessage: function WorkerTransport_postMessage(obj) {
+ fakeWorker.onmessage({data: obj});
+ },
+ terminate: function WorkerTransport_terminate() {}
+ };
+
+ var messageHandler = new MessageHandler('main', fakeWorker);
+ this.setupMessageHandler(messageHandler);
+
+ // If the main thread is our worker, setup the handling for the messages
+ // the main thread sends to it self.
+ PDFJS.WorkerMessageHandler.setup(messageHandler);
+
+ this.workerInitializedCapability.resolve();
+ }.bind(this));
+ },
+
+ setupMessageHandler:
+ function WorkerTransport_setupMessageHandler(messageHandler) {
+ this.messageHandler = messageHandler;
+
+ function updatePassword(password) {
+ messageHandler.send('UpdatePassword', password);
+ }
+
+ var pdfDataRangeTransport = this.pdfDataRangeTransport;
+ if (pdfDataRangeTransport) {
+ pdfDataRangeTransport.addRangeListener(function(begin, chunk) {
+ messageHandler.send('OnDataRange', {
+ begin: begin,
+ chunk: chunk
+ });
+ });
+
+ pdfDataRangeTransport.addProgressListener(function(loaded) {
+ messageHandler.send('OnDataProgress', {
+ loaded: loaded
+ });
+ });
+
+ pdfDataRangeTransport.addProgressiveReadListener(function(chunk) {
+ messageHandler.send('OnDataRange', {
+ chunk: chunk
+ });
+ });
+
+ messageHandler.on('RequestDataRange',
+ function transportDataRange(data) {
+ pdfDataRangeTransport.requestDataRange(data.begin, data.end);
+ }, this);
+ }
+
+ messageHandler.on('GetDoc', function transportDoc(data) {
+ var pdfInfo = data.pdfInfo;
+ this.numPages = data.pdfInfo.numPages;
+ var pdfDocument = new PDFDocumentProxy(pdfInfo, this);
+ this.pdfDocument = pdfDocument;
+ this.loadingTask._capability.resolve(pdfDocument);
+ }, this);
+
+ messageHandler.on('NeedPassword',
+ function transportNeedPassword(exception) {
+ var loadingTask = this.loadingTask;
+ if (loadingTask.onPassword) {
+ return loadingTask.onPassword(updatePassword,
+ PasswordResponses.NEED_PASSWORD);
+ }
+ loadingTask._capability.reject(
+ new PasswordException(exception.message, exception.code));
+ }, this);
+
+ messageHandler.on('IncorrectPassword',
+ function transportIncorrectPassword(exception) {
+ var loadingTask = this.loadingTask;
+ if (loadingTask.onPassword) {
+ return loadingTask.onPassword(updatePassword,
+ PasswordResponses.INCORRECT_PASSWORD);
+ }
+ loadingTask._capability.reject(
+ new PasswordException(exception.message, exception.code));
+ }, this);
+
+ messageHandler.on('InvalidPDF', function transportInvalidPDF(exception) {
+ this.loadingTask._capability.reject(
+ new InvalidPDFException(exception.message));
+ }, this);
+
+ messageHandler.on('MissingPDF', function transportMissingPDF(exception) {
+ this.loadingTask._capability.reject(
+ new MissingPDFException(exception.message));
+ }, this);
+
+ messageHandler.on('UnexpectedResponse',
+ function transportUnexpectedResponse(exception) {
+ this.loadingTask._capability.reject(
+ new UnexpectedResponseException(exception.message, exception.status));
+ }, this);
+
+ messageHandler.on('UnknownError',
+ function transportUnknownError(exception) {
+ this.loadingTask._capability.reject(
+ new UnknownErrorException(exception.message, exception.details));
+ }, this);
+
+ messageHandler.on('DataLoaded', function transportPage(data) {
+ this.downloadInfoCapability.resolve(data);
+ }, this);
+
+ messageHandler.on('PDFManagerReady', function transportPage(data) {
+ if (this.pdfDataRangeTransport) {
+ this.pdfDataRangeTransport.transportReady();
+ }
+ }, this);
+
+ messageHandler.on('StartRenderPage', function transportRender(data) {
+ var page = this.pageCache[data.pageIndex];
+
+ page.stats.timeEnd('Page Request');
+ page._startRenderPage(data.transparency, data.intent);
+ }, this);
+
+ messageHandler.on('RenderPageChunk', function transportRender(data) {
+ var page = this.pageCache[data.pageIndex];
+
+ page._renderPageChunk(data.operatorList, data.intent);
+ }, this);
+
+ messageHandler.on('commonobj', function transportObj(data) {
+ var id = data[0];
+ var type = data[1];
+ if (this.commonObjs.hasData(id)) {
+ return;
+ }
+
+ switch (type) {
+ case 'Font':
+ var exportedData = data[2];
+
+ var font;
+ if ('error' in exportedData) {
+ var error = exportedData.error;
+ warn('Error during font loading: ' + error);
+ this.commonObjs.resolve(id, error);
+ break;
+ } else {
+ font = new FontFaceObject(exportedData);
+ }
+
+ FontLoader.bind(
+ [font],
+ function fontReady(fontObjs) {
+ this.commonObjs.resolve(id, font);
+ }.bind(this)
+ );
+ break;
+ case 'FontPath':
+ this.commonObjs.resolve(id, data[2]);
+ break;
+ default:
+ error('Got unknown common object type ' + type);
+ }
+ }, this);
+
+ messageHandler.on('obj', function transportObj(data) {
+ var id = data[0];
+ var pageIndex = data[1];
+ var type = data[2];
+ var pageProxy = this.pageCache[pageIndex];
+ var imageData;
+ if (pageProxy.objs.hasData(id)) {
+ return;
+ }
+
+ switch (type) {
+ case 'JpegStream':
+ imageData = data[3];
+ loadJpegStream(id, imageData, pageProxy.objs);
+ break;
+ case 'Image':
+ imageData = data[3];
+ pageProxy.objs.resolve(id, imageData);
+
+ // heuristics that will allow not to store large data
+ var MAX_IMAGE_SIZE_TO_STORE = 8000000;
+ if (imageData && 'data' in imageData &&
+ imageData.data.length > MAX_IMAGE_SIZE_TO_STORE) {
+ pageProxy.cleanupAfterRender = true;
+ }
+ break;
+ default:
+ error('Got unknown object type ' + type);
+ }
+ }, this);
+
+ messageHandler.on('DocProgress', function transportDocProgress(data) {
+ var loadingTask = this.loadingTask;
+ if (loadingTask.onProgress) {
+ loadingTask.onProgress({
+ loaded: data.loaded,
+ total: data.total
+ });
+ }
+ }, this);
+
+ messageHandler.on('PageError', function transportError(data) {
+ var page = this.pageCache[data.pageNum - 1];
+ var intentState = page.intentStates[data.intent];
+ if (intentState.displayReadyCapability) {
+ intentState.displayReadyCapability.reject(data.error);
+ } else {
+ error(data.error);
+ }
+ }, this);
+
+ messageHandler.on('JpegDecode', function(data) {
+ var imageUrl = data[0];
+ var components = data[1];
+ if (components !== 3 && components !== 1) {
+ return Promise.reject(
+ new Error('Only 3 components or 1 component can be returned'));
+ }
+
+ return new Promise(function (resolve, reject) {
+ var img = new Image();
+ img.onload = function () {
+ var width = img.width;
+ var height = img.height;
+ var size = width * height;
+ var rgbaLength = size * 4;
+ var buf = new Uint8Array(size * components);
+ var tmpCanvas = createScratchCanvas(width, height);
+ var tmpCtx = tmpCanvas.getContext('2d');
+ tmpCtx.drawImage(img, 0, 0);
+ var data = tmpCtx.getImageData(0, 0, width, height).data;
+ var i, j;
+
+ if (components === 3) {
+ for (i = 0, j = 0; i < rgbaLength; i += 4, j += 3) {
+ buf[j] = data[i];
+ buf[j + 1] = data[i + 1];
+ buf[j + 2] = data[i + 2];
+ }
+ } else if (components === 1) {
+ for (i = 0, j = 0; i < rgbaLength; i += 4, j++) {
+ buf[j] = data[i];
+ }
+ }
+ resolve({ data: buf, width: width, height: height});
+ };
+ img.onerror = function () {
+ reject(new Error('JpegDecode failed to load image'));
+ };
+ img.src = imageUrl;
+ });
+ });
+ },
+
+ fetchDocument: function WorkerTransport_fetchDocument(loadingTask, source) {
+ this.loadingTask = loadingTask;
+
+ source.disableAutoFetch = PDFJS.disableAutoFetch;
+ source.disableStream = PDFJS.disableStream;
+ source.chunkedViewerLoading = !!this.pdfDataRangeTransport;
+ if (this.pdfDataRangeTransport) {
+ source.length = this.pdfDataRangeTransport.length;
+ source.initialData = this.pdfDataRangeTransport.initialData;
+ }
+ this.messageHandler.send('GetDocRequest', {
+ source: source,
+ disableRange: PDFJS.disableRange,
+ maxImageSize: PDFJS.maxImageSize,
+ cMapUrl: PDFJS.cMapUrl,
+ cMapPacked: PDFJS.cMapPacked,
+ disableFontFace: PDFJS.disableFontFace,
+ disableCreateObjectURL: PDFJS.disableCreateObjectURL,
+ verbosity: PDFJS.verbosity
+ });
+ },
+
+ getData: function WorkerTransport_getData() {
+ return this.messageHandler.sendWithPromise('GetData', null);
+ },
+
+ getPage: function WorkerTransport_getPage(pageNumber, capability) {
+ if (pageNumber <= 0 || pageNumber > this.numPages ||
+ (pageNumber|0) !== pageNumber) {
+ return Promise.reject(new Error('Invalid page request'));
+ }
+
+ var pageIndex = pageNumber - 1;
+ if (pageIndex in this.pagePromises) {
+ return this.pagePromises[pageIndex];
+ }
+ var promise = this.messageHandler.sendWithPromise('GetPage', {
+ pageIndex: pageIndex
+ }).then(function (pageInfo) {
+ var page = new PDFPageProxy(pageIndex, pageInfo, this);
+ this.pageCache[pageIndex] = page;
+ return page;
+ }.bind(this));
+ this.pagePromises[pageIndex] = promise;
+ return promise;
+ },
+
+ getPageIndex: function WorkerTransport_getPageIndexByRef(ref) {
+ return this.messageHandler.sendWithPromise('GetPageIndex', { ref: ref });
+ },
+
+ getAnnotations: function WorkerTransport_getAnnotations(pageIndex) {
+ return this.messageHandler.sendWithPromise('GetAnnotations',
+ { pageIndex: pageIndex });
+ },
+
+ getDestinations: function WorkerTransport_getDestinations() {
+ return this.messageHandler.sendWithPromise('GetDestinations', null);
+ },
+
+ getDestination: function WorkerTransport_getDestination(id) {
+ return this.messageHandler.sendWithPromise('GetDestination', { id: id } );
+ },
+
+ getAttachments: function WorkerTransport_getAttachments() {
+ return this.messageHandler.sendWithPromise('GetAttachments', null);
+ },
+
+ getJavaScript: function WorkerTransport_getJavaScript() {
+ return this.messageHandler.sendWithPromise('GetJavaScript', null);
+ },
+
+ getOutline: function WorkerTransport_getOutline() {
+ return this.messageHandler.sendWithPromise('GetOutline', null);
+ },
+
+ getMetadata: function WorkerTransport_getMetadata() {
+ return this.messageHandler.sendWithPromise('GetMetadata', null).
+ then(function transportMetadata(results) {
+ return {
+ info: results[0],
+ metadata: (results[1] ? new PDFJS.Metadata(results[1]) : null)
+ };
+ });
+ },
+
+ getStats: function WorkerTransport_getStats() {
+ return this.messageHandler.sendWithPromise('GetStats', null);
+ },
+
+ startCleanup: function WorkerTransport_startCleanup() {
+ this.messageHandler.sendWithPromise('Cleanup', null).
+ then(function endCleanup() {
+ for (var i = 0, ii = this.pageCache.length; i < ii; i++) {
+ var page = this.pageCache[i];
+ if (page) {
+ page.destroy();
+ }
+ }
+ this.commonObjs.clear();
+ FontLoader.clear();
+ }.bind(this));
+ }
+ };
+ return WorkerTransport;
+
+})();
+
+/**
+ * A PDF document and page is built of many objects. E.g. there are objects
+ * for fonts, images, rendering code and such. These objects might get processed
+ * inside of a worker. The `PDFObjects` implements some basic functions to
+ * manage these objects.
+ * @ignore
+ */
+var PDFObjects = (function PDFObjectsClosure() {
+ function PDFObjects() {
+ this.objs = {};
+ }
+
+ PDFObjects.prototype = {
+ /**
+ * Internal function.
+ * Ensures there is an object defined for `objId`.
+ */
+ ensureObj: function PDFObjects_ensureObj(objId) {
+ if (this.objs[objId]) {
+ return this.objs[objId];
+ }
+
+ var obj = {
+ capability: createPromiseCapability(),
+ data: null,
+ resolved: false
+ };
+ this.objs[objId] = obj;
+
+ return obj;
+ },
+
+ /**
+ * If called *without* callback, this returns the data of `objId` but the
+ * object needs to be resolved. If it isn't, this function throws.
+ *
+ * If called *with* a callback, the callback is called with the data of the
+ * object once the object is resolved. That means, if you call this
+ * function and the object is already resolved, the callback gets called
+ * right away.
+ */
+ get: function PDFObjects_get(objId, callback) {
+ // If there is a callback, then the get can be async and the object is
+ // not required to be resolved right now
+ if (callback) {
+ this.ensureObj(objId).capability.promise.then(callback);
+ return null;
+ }
+
+ // If there isn't a callback, the user expects to get the resolved data
+ // directly.
+ var obj = this.objs[objId];
+
+ // If there isn't an object yet or the object isn't resolved, then the
+ // data isn't ready yet!
+ if (!obj || !obj.resolved) {
+ error('Requesting object that isn\'t resolved yet ' + objId);
+ }
+
+ return obj.data;
+ },
+
+ /**
+ * Resolves the object `objId` with optional `data`.
+ */
+ resolve: function PDFObjects_resolve(objId, data) {
+ var obj = this.ensureObj(objId);
+
+ obj.resolved = true;
+ obj.data = data;
+ obj.capability.resolve(data);
+ },
+
+ isResolved: function PDFObjects_isResolved(objId) {
+ var objs = this.objs;
+
+ if (!objs[objId]) {
+ return false;
+ } else {
+ return objs[objId].resolved;
+ }
+ },
+
+ hasData: function PDFObjects_hasData(objId) {
+ return this.isResolved(objId);
+ },
+
+ /**
+ * Returns the data of `objId` if object exists, null otherwise.
+ */
+ getData: function PDFObjects_getData(objId) {
+ var objs = this.objs;
+ if (!objs[objId] || !objs[objId].resolved) {
+ return null;
+ } else {
+ return objs[objId].data;
+ }
+ },
+
+ clear: function PDFObjects_clear() {
+ this.objs = {};
+ }
+ };
+ return PDFObjects;
+})();
+
+/**
+ * Allows controlling of the rendering tasks.
+ * @class
+ */
+var RenderTask = (function RenderTaskClosure() {
+ function RenderTask(internalRenderTask) {
+ this._internalRenderTask = internalRenderTask;
+
+ /**
+ * Callback for incremental rendering -- a function that will be called
+ * each time the rendering is paused. To continue rendering call the
+ * function that is the first argument to the callback.
+ * @type {function}
+ */
+ this.onContinue = null;
+ }
+
+ RenderTask.prototype = /** @lends RenderTask.prototype */ {
+ /**
+ * Promise for rendering task completion.
+ * @return {Promise}
+ */
+ get promise() {
+ return this._internalRenderTask.capability.promise;
+ },
+
+ /**
+ * Cancels the rendering task. If the task is currently rendering it will
+ * not be cancelled until graphics pauses with a timeout. The promise that
+ * this object extends will resolved when cancelled.
+ */
+ cancel: function RenderTask_cancel() {
+ this._internalRenderTask.cancel();
+ },
+
+ /**
+ * Registers callbacks to indicate the rendering task completion.
+ *
+ * @param {function} onFulfilled The callback for the rendering completion.
+ * @param {function} onRejected The callback for the rendering failure.
+ * @return {Promise} A promise that is resolved after the onFulfilled or
+ * onRejected callback.
+ */
+ then: function RenderTask_then(onFulfilled, onRejected) {
+ return this.promise.then.apply(this.promise, arguments);
+ }
+ };
+
+ return RenderTask;
+})();
+
+/**
+ * For internal use only.
+ * @ignore
+ */
+var InternalRenderTask = (function InternalRenderTaskClosure() {
+
+ function InternalRenderTask(callback, params, objs, commonObjs, operatorList,
+ pageNumber) {
+ this.callback = callback;
+ this.params = params;
+ this.objs = objs;
+ this.commonObjs = commonObjs;
+ this.operatorListIdx = null;
+ this.operatorList = operatorList;
+ this.pageNumber = pageNumber;
+ this.running = false;
+ this.graphicsReadyCallback = null;
+ this.graphicsReady = false;
+ this.cancelled = false;
+ this.capability = createPromiseCapability();
+ this.task = new RenderTask(this);
+ // caching this-bound methods
+ this._continueBound = this._continue.bind(this);
+ this._scheduleNextBound = this._scheduleNext.bind(this);
+ this._nextBound = this._next.bind(this);
+ }
+
+ InternalRenderTask.prototype = {
+
+ initalizeGraphics:
+ function InternalRenderTask_initalizeGraphics(transparency) {
+
+ if (this.cancelled) {
+ return;
+ }
+ if (PDFJS.pdfBug && 'StepperManager' in globalScope &&
+ globalScope.StepperManager.enabled) {
+ this.stepper = globalScope.StepperManager.create(this.pageNumber - 1);
+ this.stepper.init(this.operatorList);
+ this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();
+ }
+
+ var params = this.params;
+ this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs,
+ this.objs, params.imageLayer);
+
+ this.gfx.beginDrawing(params.viewport, transparency);
+ this.operatorListIdx = 0;
+ this.graphicsReady = true;
+ if (this.graphicsReadyCallback) {
+ this.graphicsReadyCallback();
+ }
+ },
+
+ cancel: function InternalRenderTask_cancel() {
+ this.running = false;
+ this.cancelled = true;
+ this.callback('cancelled');
+ },
+
+ operatorListChanged: function InternalRenderTask_operatorListChanged() {
+ if (!this.graphicsReady) {
+ if (!this.graphicsReadyCallback) {
+ this.graphicsReadyCallback = this._continueBound;
+ }
+ return;
+ }
+
+ if (this.stepper) {
+ this.stepper.updateOperatorList(this.operatorList);
+ }
+
+ if (this.running) {
+ return;
+ }
+ this._continue();
+ },
+
+ _continue: function InternalRenderTask__continue() {
+ this.running = true;
+ if (this.cancelled) {
+ return;
+ }
+ if (this.task.onContinue) {
+ this.task.onContinue.call(this.task, this._scheduleNextBound);
+ } else {
+ this._scheduleNext();
+ }
+ },
+
+ _scheduleNext: function InternalRenderTask__scheduleNext() {
+ window.requestAnimationFrame(this._nextBound);
+ },
+
+ _next: function InternalRenderTask__next() {
+ if (this.cancelled) {
+ return;
+ }
+ this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList,
+ this.operatorListIdx,
+ this._continueBound,
+ this.stepper);
+ if (this.operatorListIdx === this.operatorList.argsArray.length) {
+ this.running = false;
+ if (this.operatorList.lastChunk) {
+ this.gfx.endDrawing();
+ this.callback();
+ }
+ }
+ }
+
+ };
+
+ return InternalRenderTask;
+})();
+
+
+var Metadata = PDFJS.Metadata = (function MetadataClosure() {
+ function fixMetadata(meta) {
+ return meta.replace(/>\\376\\377([^<]+)/g, function(all, codes) {
+ var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g,
+ function(code, d1, d2, d3) {
+ return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
+ });
+ var chars = '';
+ for (var i = 0; i < bytes.length; i += 2) {
+ var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
+ chars += code >= 32 && code < 127 && code !== 60 && code !== 62 &&
+ code !== 38 && false ? String.fromCharCode(code) :
+ '' + (0x10000 + code).toString(16).substring(1) + ';';
+ }
+ return '>' + chars;
+ });
+ }
+
+ function Metadata(meta) {
+ if (typeof meta === 'string') {
+ // Ghostscript produces invalid metadata
+ meta = fixMetadata(meta);
+
+ var parser = new DOMParser();
+ meta = parser.parseFromString(meta, 'application/xml');
+ } else if (!(meta instanceof Document)) {
+ error('Metadata: Invalid metadata object');
+ }
+
+ this.metaDocument = meta;
+ this.metadata = {};
+ this.parse();
+ }
+
+ Metadata.prototype = {
+ parse: function Metadata_parse() {
+ var doc = this.metaDocument;
+ var rdf = doc.documentElement;
+
+ if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in
+ rdf = rdf.firstChild;
+ while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
+ rdf = rdf.nextSibling;
+ }
+ }
+
+ var nodeName = (rdf) ? rdf.nodeName.toLowerCase() : null;
+ if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) {
+ return;
+ }
+
+ var children = rdf.childNodes, desc, entry, name, i, ii, length, iLength;
+ for (i = 0, length = children.length; i < length; i++) {
+ desc = children[i];
+ if (desc.nodeName.toLowerCase() !== 'rdf:description') {
+ continue;
+ }
+
+ for (ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) {
+ if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text') {
+ entry = desc.childNodes[ii];
+ name = entry.nodeName.toLowerCase();
+ this.metadata[name] = entry.textContent.trim();
+ }
+ }
+ }
+ },
+
+ get: function Metadata_get(name) {
+ return this.metadata[name] || null;
+ },
+
+ has: function Metadata_has(name) {
+ return typeof this.metadata[name] !== 'undefined';
+ }
+ };
+
+ return Metadata;
+})();
+
+
+//