From 090f2b5b4ec7d47e102cd6afc89de5b98812b30a Mon Sep 17 00:00:00 2001 From: Abdulrahman Date: Sat, 13 Apr 2019 19:43:19 +0300 Subject: [PATCH] move plugins out ... --- .gitignore | 2 + plugins/advanced_extras/admin_adv_extras.html | 97 - plugins/advanced_extras/icon.png | Bin 87256 -> 0 bytes plugins/advanced_extras/index.html | 55 - plugins/advanced_extras/init.php | 246 - plugins/kj_amp_seo/amp.html | 302 - plugins/kj_amp_seo/icon.png | Bin 113511 -> 0 bytes plugins/kj_amp_seo/index.html | 55 - plugins/kj_amp_seo/init.php | 241 - plugins/kj_ban_admin/icon.png | Bin 10174 -> 0 bytes plugins/kj_ban_admin/index.html | 55 - plugins/kj_ban_admin/init.php | 128 - plugins/kj_download_speed_limit/icon.png | Bin 98029 -> 0 bytes plugins/kj_download_speed_limit/index.html | 55 - plugins/kj_download_speed_limit/init.php | 130 - plugins/kj_ftp/admin_kjftp.html | 156 - plugins/kj_ftp/ftp.php | 374 - plugins/kj_ftp/ftpUploader.php | 845 - plugins/kj_ftp/icon.png | Bin 95471 -> 0 bytes plugins/kj_ftp/index.html | 55 - plugins/kj_ftp/init.php | 577 - plugins/kj_ftp/kj_ftp_options.php | 187 - plugins/kj_meta_seo/icon.png | Bin 101666 -> 0 bytes plugins/kj_meta_seo/index.html | 55 - plugins/kj_meta_seo/init.php | 283 - plugins/kj_recaptcha/icon.png | Bin 95248 -> 0 bytes plugins/kj_recaptcha/index.html | 55 - plugins/kj_recaptcha/init.php | 469 - plugins/kj_sitemap_seo/icon.png | Bin 94855 -> 0 bytes plugins/kj_sitemap_seo/index.html | 55 - plugins/kj_sitemap_seo/init.php | 285 - plugins/kj_x_sendfile/icon.png | Bin 10777 -> 0 bytes plugins/kj_x_sendfile/index.html | 63 - plugins/kj_x_sendfile/init.php | 160 - plugins/klj_adfly/icon.png | Bin 104071 -> 0 bytes plugins/klj_adfly/index.html | 55 - plugins/klj_adfly/init.php | 273 - plugins/language_switch/icon.png | Bin 11670 -> 0 bytes plugins/language_switch/index.html | 55 - plugins/language_switch/init.php | 169 - plugins/menu_toggle/admin_menus_toggle.html | 106 - plugins/menu_toggle/icon.png | Bin 87897 -> 0 bytes plugins/menu_toggle/index.html | 55 - plugins/menu_toggle/init.php | 223 - plugins/menu_toggle/menus_toggle.php | 114 - plugins/pdf_viewer/icon.png | Bin 94217 -> 0 bytes plugins/pdf_viewer/index.html | 55 - plugins/pdf_viewer/init.php | 141 - plugins/pdf_viewer/v/compatibility.js | 577 - plugins/pdf_viewer/v/example.local.css | 27 - plugins/pdf_viewer/v/images/kogmbh.png | Bin 2835 -> 0 bytes plugins/pdf_viewer/v/images/nlnet.png | Bin 5400 -> 0 bytes plugins/pdf_viewer/v/images/texture.png | Bin 2459 -> 0 bytes .../v/images/toolbarButton-download.png | Bin 512 -> 0 bytes .../v/images/toolbarButton-fullscreen.png | Bin 491 -> 0 bytes .../v/images/toolbarButton-menuArrows.png | Bin 237 -> 0 bytes .../v/images/toolbarButton-pageDown.png | Bin 353 -> 0 bytes .../v/images/toolbarButton-pageUp.png | Bin 344 -> 0 bytes .../v/images/toolbarButton-presentation.png | Bin 4366 -> 0 bytes .../v/images/toolbarButton-zoomIn.png | Bin 228 -> 0 bytes .../v/images/toolbarButton-zoomOut.png | Bin 143 -> 0 bytes plugins/pdf_viewer/v/index.html | 145 - plugins/pdf_viewer/v/pdf.js | 8052 ---- plugins/pdf_viewer/v/pdf.worker.js | 39353 ---------------- plugins/pdf_viewer/v/pdfjsversion.js | 1 - plugins/pdf_viewer/v/text_layer_builder.js | 419 - plugins/pdf_viewer/v/ui_utils.js | 394 - plugins/pdf_viewer/v/webodf.js | 936 - plugins/rebrandly/icon.png | Bin 102500 -> 0 bytes plugins/rebrandly/index.html | 55 - plugins/rebrandly/init.php | 223 - plugins/traidnt_arbah/icon.png | Bin 119130 -> 0 bytes plugins/traidnt_arbah/index.html | 55 - plugins/traidnt_arbah/init.php | 231 - plugins/video_player/icon.png | Bin 7584 -> 0 bytes plugins/video_player/index.html | 55 - plugins/video_player/init.php | 200 - 77 files changed, 2 insertions(+), 56952 deletions(-) delete mode 100755 plugins/advanced_extras/admin_adv_extras.html delete mode 100644 plugins/advanced_extras/icon.png delete mode 100755 plugins/advanced_extras/index.html delete mode 100644 plugins/advanced_extras/init.php delete mode 100644 plugins/kj_amp_seo/amp.html delete mode 100644 plugins/kj_amp_seo/icon.png delete mode 100755 plugins/kj_amp_seo/index.html delete mode 100644 plugins/kj_amp_seo/init.php delete mode 100644 plugins/kj_ban_admin/icon.png delete mode 100755 plugins/kj_ban_admin/index.html delete mode 100644 plugins/kj_ban_admin/init.php delete mode 100644 plugins/kj_download_speed_limit/icon.png delete mode 100755 plugins/kj_download_speed_limit/index.html delete mode 100644 plugins/kj_download_speed_limit/init.php delete mode 100755 plugins/kj_ftp/admin_kjftp.html delete mode 100644 plugins/kj_ftp/ftp.php delete mode 100644 plugins/kj_ftp/ftpUploader.php delete mode 100644 plugins/kj_ftp/icon.png delete mode 100755 plugins/kj_ftp/index.html delete mode 100644 plugins/kj_ftp/init.php delete mode 100644 plugins/kj_ftp/kj_ftp_options.php delete mode 100644 plugins/kj_meta_seo/icon.png delete mode 100755 plugins/kj_meta_seo/index.html delete mode 100644 plugins/kj_meta_seo/init.php delete mode 100644 plugins/kj_recaptcha/icon.png delete mode 100755 plugins/kj_recaptcha/index.html delete mode 100644 plugins/kj_recaptcha/init.php delete mode 100644 plugins/kj_sitemap_seo/icon.png delete mode 100755 plugins/kj_sitemap_seo/index.html delete mode 100644 plugins/kj_sitemap_seo/init.php delete mode 100644 plugins/kj_x_sendfile/icon.png delete mode 100755 plugins/kj_x_sendfile/index.html delete mode 100644 plugins/kj_x_sendfile/init.php delete mode 100644 plugins/klj_adfly/icon.png delete mode 100755 plugins/klj_adfly/index.html delete mode 100644 plugins/klj_adfly/init.php delete mode 100644 plugins/language_switch/icon.png delete mode 100755 plugins/language_switch/index.html delete mode 100644 plugins/language_switch/init.php delete mode 100644 plugins/menu_toggle/admin_menus_toggle.html delete mode 100644 plugins/menu_toggle/icon.png delete mode 100755 plugins/menu_toggle/index.html delete mode 100644 plugins/menu_toggle/init.php delete mode 100644 plugins/menu_toggle/menus_toggle.php delete mode 100644 plugins/pdf_viewer/icon.png delete mode 100755 plugins/pdf_viewer/index.html delete mode 100644 plugins/pdf_viewer/init.php delete mode 100755 plugins/pdf_viewer/v/compatibility.js delete mode 100755 plugins/pdf_viewer/v/example.local.css delete mode 100755 plugins/pdf_viewer/v/images/kogmbh.png delete mode 100755 plugins/pdf_viewer/v/images/nlnet.png delete mode 100755 plugins/pdf_viewer/v/images/texture.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-download.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-fullscreen.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-menuArrows.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-pageDown.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-pageUp.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-presentation.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-zoomIn.png delete mode 100755 plugins/pdf_viewer/v/images/toolbarButton-zoomOut.png delete mode 100755 plugins/pdf_viewer/v/index.html delete mode 100755 plugins/pdf_viewer/v/pdf.js delete mode 100755 plugins/pdf_viewer/v/pdf.worker.js delete mode 100755 plugins/pdf_viewer/v/pdfjsversion.js delete mode 100755 plugins/pdf_viewer/v/text_layer_builder.js delete mode 100755 plugins/pdf_viewer/v/ui_utils.js delete mode 100755 plugins/pdf_viewer/v/webodf.js delete mode 100644 plugins/rebrandly/icon.png delete mode 100755 plugins/rebrandly/index.html delete mode 100644 plugins/rebrandly/init.php delete mode 100644 plugins/traidnt_arbah/icon.png delete mode 100755 plugins/traidnt_arbah/index.html delete mode 100644 plugins/traidnt_arbah/init.php delete mode 100644 plugins/video_player/icon.png delete mode 100755 plugins/video_player/index.html delete mode 100644 plugins/video_player/init.php diff --git a/.gitignore b/.gitignore index c87d411..cf17d51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ cache/*.php cache/*.log plugins/*.php +plugins/* +!plugins/index.html config.php uploads/* !uploads/index.html diff --git a/plugins/advanced_extras/admin_adv_extras.html b/plugins/advanced_extras/admin_adv_extras.html deleted file mode 100755 index c97ad24..0000000 --- a/plugins/advanced_extras/admin_adv_extras.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - -
- - -
-
- {lang.EX_HEADER_N} -
-
- -
- -
- -
- - -
-
-
- -
-
-
-
-
-
- - - - -
-
- {lang.EX_FOOTER_N} -
-
- -
- -
- -
- - -
-
-
- -
-
-
-
-
-
- - -
- - - -
- - - - - - {H_FORM_KEYS} -
- diff --git a/plugins/advanced_extras/icon.png b/plugins/advanced_extras/icon.png deleted file mode 100644 index aaad91514bb5d9af905d8b7dda4695c74cb46ac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87256 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 t8~Q@w*orz&(LIEPF~8~UuO - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
- - \ No newline at end of file diff --git a/plugins/advanced_extras/init.php b/plugins/advanced_extras/init.php deleted file mode 100644 index df06955..0000000 --- a/plugins/advanced_extras/init.php +++ /dev/null @@ -1,246 +0,0 @@ - array( - 'en' => 'Advanced Extras', - 'ar' => 'هيدر وفوتر إضافي متفدم' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.0', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'An advanced interface for the extra templates feature', - 'ar' => 'واجهة متقدمة لصفحة هيدر وفوتر إضافيين' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['advanced_extras']['first_run']['ar'] = " -شكراً لاستخدامك هذه الإضافة قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -
-
-

لاحظ:

-تجد إعدادات الإضافة في صفحة: هيدر وفوتر إضافي في اللوحة -"; - -$kleeja_plugin['advanced_extras']['first_run']['en'] = " -Thanks for using this plugin, to report bugs contact us: -
-info@kleeja.com -
-
-

Note:

-You can find the settings at: Extra Templates page in the control panel - -"; - - -# Plugin Installation function -$kleeja_plugin['advanced_extras']['install'] = function ($plg_id) -{ - //new language variables - add_olang(array( - 'ADVANCED_EXTRAS_APPEAR_PAGE' => 'عرض في صفحة' - ), - 'ar', - $plg_id); - - add_olang(array( - 'ADVANCED_EXTRAS_APPEAR_PAGE' => 'Appears in page', - ), - 'en', - $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['advanced_extras']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['advanced_extras']['uninstall'] = function ($plg_id) { - //delete language variables - foreach (array('ar', 'en') as $language) { - delete_olang(null, $language, $plg_id); - } - - global $SQL , $dbprefix; - $update_query = array( - 'UPDATE' => "{$dbprefix}stats", - 'SET' => "ex_footer = '' , ex_header = '' " - ); - - $SQL->build($update_query); - - if($SQL->affected()) - { - //delete cache .. - delete_cache('data_extra'); - } -}; - - -# Plugin functions -$kleeja_plugin['advanced_extras']['functions'] = array( - 'end_admin_page' => function($args){ - - if(!empty($args['go_to'])) { - $go_to = $args['go_to']; - - - if ($go_to == 'n_extra') { - global $lang; - - $ex_header = $args['ex_header']; - $ex_footer = $args['ex_footer']; - - $stylee = 'admin_adv_extras'; - $styleePath = dirname(__FILE__); - - //$ex_header, $ex_footer - - $ex_values['header'] = advanced_extras_get_values($ex_header); - $ex_values['footer'] = advanced_extras_get_values($ex_footer); - - foreach (array('header', 'footer') as $k) { - $extra_pages[$k] = array( - array('name' => 'all', 'title' => $lang['ALL'], 'value' => isset($ex_values[$k]['all']) ? $ex_values[$k]['all'] : ''), - array('name' => 'index', 'title' => $lang['INDEX'], 'value' => isset($ex_values[$k]['index']) ? $ex_values[$k]['index'] : ''), - array('name' => 'download', 'title' => $lang['DOWNLOAD'], 'value' => isset($ex_values[$k]['download']) ? $ex_values[$k]['download'] : ''), - array('name' => 'rules', 'title' => $lang['RULES'], 'value' => isset($ex_values[$k]['rules']) ? $ex_values[$k]['rules'] : ''), - array('name' => 'guide', 'title' => $lang['GUIDE'], 'value' => isset($ex_values[$k]['guide']) ? $ex_values[$k]['guide'] : ''), - array('name' => 'stats', 'title' => $lang['STATS'], 'value' => isset($ex_values[$k]['stats']) ? $ex_values[$k]['stats'] : ''), - array('name' => 'reports', 'title' => $lang['REPORT'], 'value' => isset($ex_values[$k]['reports']) ? $ex_values[$k]['reports'] : ''), - array('name' => 'call', 'title' => $lang['CALL'], 'value' => isset($ex_values[$k]['call']) ? $ex_values[$k]['call'] : ''), - array('name' => 'profile', 'title' => $lang['PROFILE'], 'value' => isset($ex_values[$k]['profile']) ? $ex_values[$k]['profile'] : ''), - array('name' => 'fileuser', 'title' => $lang['YOUR_FILEUSER'], 'value' => isset($ex_values[$k]['fileuser']) ? $ex_values[$k]['fileuser'] : ''), - array('name' => 'login', 'title' => $lang['LOGIN'], 'value' => isset($ex_values[$k]['login']) ? $ex_values[$k]['login'] : ''), - array('name' => 'register', 'title' => $lang['REGISTER'], 'value' => isset($ex_values[$k]['register']) ? $ex_values[$k]['register'] : ''), - ); - } - - return compact('stylee', 'styleePath', 'extra_pages'); - } - } - - }, - - 'require_admin_page_begin_n_extra' => function ($args) { - - if(ip('submit')){ - - $_POST['ex_header'] = ''; - $_POST['ex_footer'] = ''; - - if(!empty($_POST['ex_header_x']) && is_array($_POST['ex_header_x'])){ - foreach ($_POST['ex_header_x'] as $key => $value){ - $_POST['ex_header'] .= "\n!!! start advanced_extras ". htmlspecialchars($key) ." !!!\n".$value."\n!!! end advanced_extras ". htmlspecialchars($key) ." !!!\n"; - } - } - - if(!empty($_POST['ex_footer_x']) && is_array($_POST['ex_footer_x'])){ - foreach ($_POST['ex_footer_x'] as $key => $value){ - $_POST['ex_footer'] .= "\n!!! start advanced_extras ". htmlspecialchars($key) ." !!!\n".$value."\n!!! end advanced_extras ". htmlspecialchars($key) ." !!!\n"; - } - } - } - }, - - 'Saaheader_links_func' => function($args){ - - $extras = $args['extras']; - $go_page = g('go', 'str', - defined('IN_DOWNLOAD') ? 'download' : (defined('IN_REAL_INDEX') ? 'index' : '')); - - if(!empty($extras['header'])){ - $ex_extras = advanced_extras_get_values($extras['header']); - - $extras['header'] = $ex_extras['all']; - foreach ($ex_extras as $page=>$value){ - if($page == $go_page){ - $extras['header'] .= (trim($extras['header']) == '' ? '' : '
') . $value; - } - } - } - - return compact('extras'); - }, - - 'Saafooter_func' => function($args){ - - $extras = $args['extras']; - $go_page = g('go', 'str', - defined('IN_DOWNLOAD') ? 'download' : (defined('IN_REAL_INDEX') ? 'index' : '')); - - if(!empty($extras['footer'])){ - $ex_extras = advanced_extras_get_values($extras['footer']); - - $extras['footer'] = $ex_extras['all']; - foreach ($ex_extras as $page=>$value){ - if($page == $go_page){ - $extras['footer'] .= (trim($extras['footer']) == '' ? '' : '
') . $value; - } - } - } - - return compact('extras'); - } -); - - -/** - * special functions - */ - -if (!function_exists('advanced_extras_get_values')) { - function advanced_extras_get_values($content) - { - $re = '/!!! start advanced_extras ([a-zA-Z0-9_]+) !!!\n?(.*?)\n?!!! end advanced_extras \1 !!!/sm'; - - preg_match_all($re, $content, $matches, PREG_SET_ORDER, 0); - - $values = array(); - - if(!empty($matches)) { - foreach ($matches as $match) { - $values[$match[1]] = $match[2]; - } - } - - return $values; - } -} diff --git a/plugins/kj_amp_seo/amp.html b/plugins/kj_amp_seo/amp.html deleted file mode 100644 index 8aa4d05..0000000 --- a/plugins/kj_amp_seo/amp.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - - - - - - - - - - - {title} - - - - - - - - - - - - - - - - - {{title}} - - - - - - - {{title}} - - - - - - - - - - -

{title}

- - -
- - - - - - - - -
- - - - -
- - - - - - -
- - - -
-

{lang.FILENAME}: {name}

-

{lang.FILETYPE}: {type}

-

{lang.FILESIZE}: {size}

-

{lang.FILEDATE}: {time}

-

{lang.FILEUPS}: {uploads}

- -

{lang.USERNAME}: {fusername}

-
-

- {lang.FILEREPORT} -

-
- -
- - - - - - -
- -

- - - - - - {lang.CLICK_DOWN} - - {size} -

- - - - - - - - - - \ No newline at end of file diff --git a/plugins/kj_amp_seo/icon.png b/plugins/kj_amp_seo/icon.png deleted file mode 100644 index fbaf737e7245eb23e9b7edcf45ddca2f799553be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113511 zcmb@sWmH_rMLc|>UH(2` zom6BcVamtJ4*w2NfuFUVU|`U3|G8mdQqzfGVBm|a)U=$n2r#Sr}a{twJfL-j9;vyBLimb?;`lmp0&ikFRt zje|xMjf#p&7-VWLsPakXzvX{NA~crH&OkwSb~iUSHaBiI2ap9jCjbCo=ip-J;$r>F zV0H4acQ$fowRfWZFDL)w=aZR}3CIfQY~^52^^ad8V+R*!5gM9*0{yS+zvpQO{9l3W zo&GzkzxlDd8v)rl**Mt$Paob^xh4IM|9R zS-G3p+Wj-6;%4LjFXg}6|4sT&7J`Z(E3?1l{ilece*^u0u>a&sIoJU~W=>B3@Ol56 z|L@p;@>R^79Bf_waj$M~;B%h`LtH^@fnI* zSEr1k341z$T(hP2*G&K;)&{i52)RjoA`6SF(dvup3U;~}wa2U9TA{%2tuMZj#3P-= zj98sSKXJebZ-gb9~%C9eceiH}6 zxC=qNNnQTgHrG5YQ=d!9VD|j83yV#w+3qUw4OlM`@zPTI)IJIhPbuFw$Gsrq$0w_$ zSuuKQXeY!QSiCJkQNo=dL{p<#jEy?n6af%h^1(c2>njoi{n|^R(}y$*h+{gpxU_B3 z-iViIjrz~e!e;PeYkj@XaRqQFwBOz#wki(+4PSr6H6V? zeYjJz5$z5uSF?vN4QtGDf-C*~b zDAe)$*{ncLOkRe@FM_=U+R^yqFAB@Ou6N7E(HVqKdSh!-_tQT2>2wjUmYlQ|d&4&gwUUt0#E3M?jB(ZZybL-K>DwUYO%JRvTBC?m# z&hVF@_XS>kFAUaUvF=*pPEzrZE?nS<*4ElW;#?IS#n>VikOk{G;mN zo$ed2^=d=+w#)uJ%Kzq7`>Gdn{5XN}IMVS5HDIhYC^&cxFXjuC&uy#o+HOR(>N=cH zpcf`nFxUH4=s5x~o>5lLvyuS#XMM+5PWz*)cK0-Yj>g1=XCBmuwuF#u`OC3kXuHJ5 zM~#Ku=eH$@%s>)z(%J9umkUU_dV*#Sq^4$hO2RT! zk4Uv%Qy&F!Lmv9=Wt-$a=3OMFMSwUn$TcHfR-J==^r%aZ*_hkG;}1Iz92T;{<8N~0 z&)w|LC)aOuJz_CZN4^CCj3pfy#|Al#Z}6bet)Zx{P)mkdB9AFHJ0!XMG_Bdl$<5e@ z#uG^i0cDk{;G7b--_T{AS&6&4 zONd_5cST72MPXB9iYt=gte9y^M|K|^FOoq|ccQo(`SmJH zNr_XK!umJ~@uZ+V6uIX!xN0gyFg2Trl5+Cfr|Z&;5WPQijS4@bZkJcIo!#=j@P6ma z5;Nm$RGfI5lz{r^u~}&o=>ujBGKcmi(mU@~wajTb(@1Y8Hn0KRdMS5uL6MX^n}- z==mwey%O;!Hpevu#xZD*bK4Qf&3XP=Trm{x_+;>`w*E004huSJu=ZCwCBwgsF6-ZQ zqOV*!{Yf7fysJc-)aGa(lXqYIl|>%_J7Dn^$G?__xm(jgtlrVr{j z**1YZ03clJ!byI0)Uw&)C}5tofH|OJ>C_*i0V#^O1Wb-(kjkS(Uk^)`Z?})ei{_Vw z7e(6u!;CF6<{*Z~u^d3VOeYxMjm;(RZsgQXzw*Op} zpfrceDZre<@+asb?2XhwSj6W#Z3pkY*lXV3;ullqy&!Uice#7P5R0*ak!#-$_I>xD z9q2cT9)hvY7xTXRnqse*+faO#4xkY~`6`SINtK| z5g_R{%y8K#wee+F$eXZqFpWwCsci;T9WCq@J&GDZR$J@7U+x4dHW+`Z4x>R+(-W{t=O^8C}-3GpDYk|B4g zj{^J{j?qy-H*W6C-K^A4ZgK@ANPPF^z<5$8Tv_V05$mXU#a%8P6=DhjJp$R?DTFUD zZE$h&p*2$a?G;f_6%&Q7^bTu1BTh$Db7&E3^d(sf$E?rdf$U}y@04Due>%0r>ew~= z^TG9u;`2;a7Wi4WXk@O?)0t;LY=W2){3`bHw=q`Fvi3r^v27mQd`}@8Zx1)mls2|h zULPKMk#3)Fbl(o3hhDzGcf?LPH$_8%DeoXPhF|@x$EZL9DG3DE;?fp+Yq%Wm3wsf6 zpendxbs$={wYZ_hww@0*T%#n5cMk8@fHM6pzrrkTey-@k*!GFw#`6kr9i1VZugizO z94W0Cf8g&kdBz#kkZiFbQ8lUuu+R74K;8FGZ9#C?nCFVSGG5;x1gn*`JtCs5?@8_W z6S37alKm$|!;y^~bJL=GE6=5T&7ha5?uB`!Z-||nTPm+=u54uU(Z^#8VP6R!g!Hf; z*J^*->uoIBL;8M1r;8-a3Ff;rb&~grbhTtpZ`CFf3-RWb^GVH^ioEpo;KUW*{OB!B z9Ylmm|M-E|kL#K`R`Q6&5bF0WRB#v3gWvk`>0xs?#OwIi7U8JN9``%M=&S&H%4bFf znK1G;M_qvig&NaN9h|^veT>2ipeqKG?vE1b1<7Mf#I=_oO6cQu8e7Gs z;uPhEjv{CREtuG_zBb>{_#J0d(UfQJh@W@gc<1qy3(6dI*6LJzY4^5B6@{v2&wEuN zerfbAHoaROdz0+1p3~Jj)BULkcYM5rV}Suf*Akb~7dwxhGi7!!MbqgT@XmA~)amp+ z%IFUY{eebD8NVp73te6F#Le{~m}Djb>%8tO$Muy&^=v=3XVsS6fI}(#MvsyhV5Gg! z3XvfSZ9~BJj?lKo2UwV6gDOkR&88N8{Vo;0Q> zxaobPq5&}7;0NJFhELi7SAs6XE%k*lePl4!#)E|N%ey)G<|%rjDmupMWMa}WjeeKG zLZFDZEQr-H`|D1D_}pG!sF?3Vnr|v2>*U+c0Q+Ui9HHXIgF|vE`(x!ho2<`Z2&J&t z3tN^dz8j+PbI^O}v}@cS!+cCE@<;*_zQ~sx1X)bR170Iui+Bq0hCz({dcNZ9OSF!x zOzMdRO41nofNWv!P};0dlG8!dm$$A8L+zv=?}(E^-~;9T@ZsL&5-Btq+eM!7o=A{rg#;2lA6uS4m82DNjyJyBdXbnK+7ES zMoxjqz7Fq}SM^%^<4e+o*a`p`y&ngbYNOo{fI{xot)kQFV&IvoW5LvDDTt?w8*N~K z`#~m3W_zE7?%TBDDdk8Vc#SZ}8nq6PvZrSxC}b7k*u@0KX=QiTb=6q-14H z4(2}go}RxwMqw*%V>uONOrEG2zEy;suZhdz~*CLacrF6CXxf9FoNa>WZ&2rUMEKEl7z*%CwT9_fg zO4;Tz{(iIaHt;2^tPwyQ06TcpRon&DV$BbV)+ruXn6Wl*Ua?SYS8CJPel!F)UAxFm zPBjSVPwB2Z)!+(vm_1YQ1-;XJ5esDH0hNs^bVPppwl*Xx_A(grcQuc8TtE-eK@212 zN&IHs=5G}*9AYARt>WHmmoJ4AZ^S_txGR2iSBHmhuOSnP9dABsF+YeV=>VDd6vpnH zLvc3>=f+%2jG}bLjYPjcufZhJjUG^rQd8+nb7LUGx3kVO$dV3PCy|lAXlHxB%0x(k zSq%xtMyMykC3#_dsz1jFSRV&uA^btw$zeA^?&}_q!7A#jXBi9vvv*|(+=PGF&rHXv z9a#Ythi1KVOOA(j^L^tWUCEtL*if5&4!tXO_xixIZ)~x{>i`uh+m8HYVi*Ap)h2ky z5f`t~ALf^oWzcvTh@))4!cGq_*JEUB5c*V~c>Hs~e{wU)rMdls*^TgE6_lZ&@O9`4)Upoa@@{u~^+4nc7*Sq~4;>y5G9 ztP38nLEiJXw}Jb&DE9WtsJEP}+$+bMo41RUIfu6nBzZcSE~8vRF0O#Y*>$nGJ)XIE z7Idk2o-QrLQdT|gN>1ld878D*f$?-0v%B+^hzmg@p&)>CeU{8&%w2#K)#pieEJr(= zO@78*qoI&|C$FZCHj(io0N2T%S+T1737O7!-%h$~7H1jp7;p9zGS0wEx4I*{W_{eA zo?NdcA>ikCCt2vqXpt@^oU)G`8f*9gOS}eYdGPu3h8%grQ?%b3>~?+t_?aLWO!bKoMSes7KIBvuRZpq3vE03W!YPe{h{U6)%t6_yLxD# z@HW8`&eto1@^+~Y+@n!LeWxp9&%{4SFlPk8cnEG#tBLS)RJKAtYx7o~NtumwHp;IK zFl{u2LIj?lCdNOhl9@LpLLQ_1 zFG6G7cOC6Ou0Ci~ilF=Wx6zpy#mf|pm( zDq;BswC(Rk)rWjy_r7m1Y-xE0%}_xDHakGOSld;fUMC*)JUtB~0>UY#)m*M#)AwT&LUa zlG)H&&9zi&8Q^eZucCuUPRE;Ef>j-IcZ&9Uj8WqYZSet7Sz2c4U zAKgqz+>>8rt>+@8e3>YXaP}Z$_sI0lrH#%$DhQJD`EZyAm&GuvX`bFLIQsC%UbsL~ zBnzQ?w?u)T^;C6|dMv&I$k<8r;@p23ALFp(!C83KnR$LfexmEkx5LJs_Bhor5H==! zsgCdf4IK`nTDj?K0(@5f9go{}5Kgv0lKZiyesAJI@%w59;<3eoH~0TPYJGF6r#u{8`iFIHM^2 zc5%94_dbMF!pCXnRB$amX0bRTAqoAHEq5%1ot;<{u|P17KGd{QNF5h1j?MOE!tU92*&pjgLVbvM1ux8e9^DUSASz7G#1%+hO>g%j1 z@EV}A*|efG-Vt5=4kKf*l!OW3ZKaWVVHo$~UFd~v+sJ}P$^7SB&Fk_qSW=7ETSR1t zW+52>x$|w$0nsqjaWm{-f7#-I#`C%oZ9`Pl`xRStl5qU((oIanCuXC8OB1weOc5Aw z*L6ZUK(flmO$a$dBFLoM9n(bho_Z694K0i|Y1icQbV#MxPFdU|_$dM)Hu1Y1knQla zJnDHr&~2$QYAJ4xq8(x2ukn?BkV#o;wozRDulwphoyBL&N!t`DX65QZg<1N zny#=fuQ5zzbP?{Wa@i2!m-RCsW8064@u)F{;KaYz;~~l^K1R3^yn0{j_^(4X?;D{n41F z_gdP7=jwB1q(!n>tXavsM%1g`a~i=e?GfM3!`?v*i0|%`{0;26v`_{f+#VL#H(s$g zbw2c4kGDJC5m&7X@IXr-(2d7FgXe8%1h%hT!bShR*yHy>0-)_TKXez=9o!C3mq`z9y&To-RfZ8}jFC9(;T?^C@#6q_GavNwuf$YA1K6!jJrVK$)`!L_1eg6>Hxxp7o%46UF+oz+ zgT@(_wyk(nBsF4r60z-ehf~-G8e$K<(uTbY$Q@WB!+Ngs#{to8pKk!U|S4L0SLTJv|9 zS9m#=H6yI<8LC|CFCJako4UD6*xfZ$&lq=caxu0f6Pqm%wg<2iH2Gh|4eMHx5gLE#=&+Jq?C`vN7VOWFXm$4o{v?(<3;525g8?c z+Ou7fFs3aj#uw$Yg*NlVEf2%3vP{?g^Md40*c)#)dD!rm#=Z2!A(&9rOo*z#&XR3y z%@4Fb6#281ODMoy(j;at&Npt^cnTSmRpQ-YFy4pY;Pz!8$XxCOtvA9_TeSSu71aFr z!D^%g`t{3Go)Swx^JniyeG!+*wl^7Im4MhXF0G+`k^Zh_8Olz<)C|Gex;{67V$-&b zgF*evz`E8|nF(|F%An|zK(AiDZX~ljx3B;!>IcKNOXCmaxQkPq&ni@!KAa6lA4W7p z2YlbJ;C!NHgX7?u_WW4x!ABUDu#Qw4Dqj;Yx7{MD)?*nFr#EH6WY3>``Kt^$bCmw8 z-4EHf$9OYAsvYc)#o@}Cjd6U@WxN%;oqD-Di+srb85=x-WPVUi3vX$>CcWV=U-=Gg zk|y#(oOx*{olOnfhRR6YX?2sZP>;8ySrmeL1P&LfHL^(eC+(0qb3!SU;cysEFuowJ|+O!bOMCzKJezRrtwu zE<0{UJtRTA5X4lOH%Q!QfiQm3ZyV$U~KGuxvCU{(l#P07H`pJ3cZ&j<&-oPpX$^r?{Xv=jIro#!0Tuj zYLiRRkB;pcJLjveF%rVV=+g4FE`r(fE7|w2OO%DB3Zsh->A_A0_)jquSm31`{<}16 zvF{-IA%*JzN}_~7`pdY{C)El9Jd-iFq#pu^#_v=(A4GCcYUsikZQ|KH;&tBLVD|P^ z3@fzMH%-w=NB`t0S0FP`&~wAOBqA-)v49OPB!=Ibw%wvu<8R99llE+e45wW79v$hD z$$MAZCUt)kCKBv%?5cztsvx)zK}7+Pd<8{VdF+SlllIX7UU&Uh1sVlkE`{_Wxv}~| zXzi=UN}@C7gN|!X#g9{n(T#)=!0m}Tof^eWs{ZRWCF{Pg$H58Mat7NuQDwrxh9m4Q zu3U=q(M})}(g~~nZcaz3=}B$m`-?ieFGX8!yE$?`(rvZviGSWhIvVX=5A=+$8Y>pL zlj|h0Tp&^%9y#&t@r?7e3McM;itWUuE{&-j@LwX>yT~B9Vh|3Q0cW~ar;o7LuB*KR z>0;ZMl8QN4?4uss_6Ba`H-XXe*M<06>`uvU-sj8dQn?hss-O3O`mL@Rtz8s@HgJ|~ z*}U8{<_WYAr-hLjIt>}gtW>+}3%-RGzR>?set5ol5d-pz27*}nNSRpsX=FFer(4#) zg^xy8k|A&lrPa<@B#(_nRem}^j+g(*JQbt)fPyVUZ~e@$Z@AF{8*cQg7sC?KRUn8TaSj@%5I+;?NX_ekXbTn#rco=a^Tw*t`EFuNQ=iwO;Ci^Cn$OJ=sJT6u zb2p5?57W4vhND=)!rckmGMrB7wrVlk!Dis;vpkr!BmxqGds(p6bwHIIsjug@0AXKr z&i6I-;w#l0^w-)3Qz{dTp(!ReZOX;~)^A_D3(n4;2|@0j-SdLd9i$|Stj~-#~hQkaL_R_8+Z;>U% zDq}zLu_6Pe7tEXAU#|E=W~dt#`!@l2xSO^f!yq~q7wke{ahQGf{`ZI(syoVyC#_us z4C$h_^~z`h_=;%umC7@Y4zr6WU(Vr5VAZofoqJes5PTCVmm^9;XL>gG{4dVIB^L4V zV9}f)z7v8w=J7*+FSse4QfQ+99f4IJ4YF6KJva&GOKRmaXZvqiskb)1@@U-L{>C-s z2jx~QOxY&SVcNk^_!te^gTGs7NU&>l=Czz8r~&hq(Ta2m)xwP|8EFlCLf6?%A(Z+f+VqWUtKZE_ znSk8f3IM~?{tua_N@qmFYc-^-UA<0kA~QFysznTAWCjGtH5Y%Oh)8285# z0~STBL&`lk=?`6HlgXttlgGWORhvA_7GVUub6pg4Xfb@f1my|+;>2{ZEpz9+!L-2AR!eDoRN2}KoS{8F_5Q9StknnKCho`vL~0F1 ze0`5PKkj*PA(zQ}l^y+wt^AR&+5v>tqGpNWxI@0u<*;(B9zPBJ567hRP8HlvE!ZpM zt9w#CJ2zZ#znkwB{|v1ukU@?u@M>-t`$YPRf5>$ZfYL^pds}kQa1m!tAz~RKcEGjC zy=2$4FlSpQJc;M|q?`*-pP4A_PlUIt>~;cjJF-QggkXm+QY9Vk5ny-2H3NJ61?i8$ zFi`>8_T=1HYt7%FC<(ugqDm4 zFYwL!9j5243Jp%_VCaz=WcE4Q`i!N8^kPRnxN;4biYH9JPzX7d`3?2b>%5p~$L zmAg5a0>gY>O9T>9f<`yY*_xG@%G@9-xBFaI^;Fe1&f3y?1_^nHYV0<{idm-bBcwDo zOrTksmhkpMy^gsyxv}IU45=)i24g*Izh4x6-Ax%ie=!(4=m$$bZD~dsk-dHbXIk!_ zkg;Po4_p3@wc0MVBEMxtv?DLuC46#0Knzq#%z%r=fvL2vMc5AVK3r4#ca_1F9vL-c zKzjY!fBXT9as!{-&ufK&i`{wEf;cz}T^Eo+TH5NNTi6)H^Op7v22nmc!|E%`8!{6NA>MAI`!he*$ejLW?j_6C4S-L7Mz;+ zj(v4hquwm^rf~RCTb)Tj;tyjlRBebv8XH)vgIBFWJY-58p}~!rHeVno#YTU z5uF~U0oqC(mx`VR+HHG4N@jUT;kd-Z%cql4O<<3{!g%=K9u{UlIos$35Ka%Q_DwJ5 zQs4?(@|ozJ6y&%Uy}W-|dz1F0Z~>iEIu-mZQ=1-+y(CK$HZ|_#^}Y8u1Zr83tF#hb0 zW8V}Oi>#-UiV;dP@-_+G2;@wNzgE|Zsd6&}rd{&MdNcw$<^hKC!P!;P{=ouHI^)}3 zWb6cW`z?i}`(b&Ed7yI)f_E&C?w4GM;se!Dt+AWltheBaT}q#T?k znX^S-$G2}=CWJ7Q;b=4BF06X^I7P9hZ~%3Tu#Lj~|0QXf9Lm>eqwI?Jh5rYIj z!=_>f-ZNU^8dduYkxI}dDScL7M52+VEIw^BCg5+ucS!I!6!mW z`j`80p1}Z5wpq8U+oV0%^c;xmUtZu(oM%V3HuM9rrw|!~jGM3Q>yGzB_E~ zJkH-s!2LdyA^<9~FB~>vn8g{G;ij%zGvuWdLw5$#mZkWXMpMG$aKE~r)ej~!$Ess>wGX8h!WX9nAaQ_U#s7w@v~ov7{hauth;vAy-=J zE5lNh2V^Yk5FgaS1tGoM8;MdTs@XZ8Cu5pR^xhQX5tfVnPIc|UDGE*HY+j1!($DpI zMB$&U!_CpU@%&jHue=qmN-^F&H!HAncp_jM+pslYiS68^GnR;8#23IY4k83IH+~p6BJ%=a`#p-5t;aqD8JbzU*dktFw*S_Y-1C1riF2q0ZaQV{lI^57L zD`ENhR`L1T=?FCq?@HvPk?PK=41D2tt$5D}Nh=CUi6=v6@sAdmB-j^)T5kTBgO=It zdywW}7#i4ar$pG1y?%0L?Y`Wz$hN|sC|9IWNF}0LH=@+Uz~a!Tn1fM6{vQyW!Q-oKlLI* zZWwu+y`FxK(>US>AUMaRsanNbW=QX7kok<27%j7hNf2$(_o0qz*g5uU1hMnlilp8M zV-)2Jo*4NOvhbmzNlAJjhDx@!aSe}jUltW@2l5Ku{wnQp;ap@uL##EA2<+3u(1Zeq zn7$*t_OSk<6HIy#kPZ`=0t^}GxNKF2VWC9!IZrf3XE|EWtXQxlNz6%o$u$RYSUNKu z*02J}Y9@*=39y^zbuZbCEL5i{2?lTGrzPB8IXl3-YHY7@v*2n;b%V74dUovd&FRWx zcY`<;zKq>a99TKYfb>q486Bbi@BMK`mHZtLlGH*HOITjT)R?3&Onh>i8m$@4f<A zA{{KxZBeLo9;g!DCS731N^!h?q2qWM`#gxRwOSFfw=-|Sxd(ne%Gm{;6OH zD711rPC$z0C#*O11a0DOn)tKAwGnN$$zW!h?~FI#XG9wfXH7|RpSOJ*^vJx)JPWH) zvo@;wBp6j8OgxZ8eig3qg~2iIU}c2497QowP$HRXfbOK%vU98H&OGsO-fn$xZzi9`OXs)qYJr^y zoz|S-WGaKHAny*3LVYikfKbS8;R1DBx|Jqex@1LmVqilX$#Mg)?^&aWj)mw^PQO=+ z21D7=?(QHD{2f<dWj5XE<%g!uv|u zVR}qI&-D-qHFcuWduZrh&1WHbuhjbb`bf40_WPH=W7PwO4;bC@YAi|TVdsPGxh}`N z)|~S|K3^&N7Shr2TGe`^lB};Z{_cU___922`<6P}zEb-f8mxRL?|6&+Dm$)@a;3@7 z-V|MPJXQxD&>_7N&-@Oq%*8zqu&~dCw_hMTo(R^TMBcxo3++s0si^-J+4zV1T4~j^ zv%ddYlmdgGrjeOzS#aEPwdznT^t&aN_u=Ipt_CTLLaJv9@W9edI6#PNhoD%5pT_Mg zyt=X8(@sAn`JBpp2)rlQ1^*>xeR8 ze8)q>*wZil6pp5D!A`nYN?gA=Jv_a}H;#tsXPK^DtBL2HUweB9|r~>!7`UZIr z@zDuvysneXpL(BCgB}|_oZtu(h;(tob#W8$=N40H<_(q7#yF%cjZ*&#n`2DRRGrO& zy&a~jNU_0FKrs3U*#0|+&8KEsC3s?&2nWEcczw7?g#7nN15}lY_Jo%(SKFFFHx$B- z5}9Y`{CKfabrc+&?5+L{9q#4uP6>3VS#{hT#5MIb}r9!VuS$60TZ;|ro z$nzQRG*N-Z!@(fCYY&rbUn_^#=&PpH6LSWFhbtzs@@4Sa zPNbVI1?;Xe<1Yc4i!2f~huj>WZ)Pa#I<0FE3#D0K!%po5Lj{K?!W@lv~f!0!);&kwRsBnN^iFFr~U=4p+sJ4gJF2j=4*=6lux zP3-N5gs}_*lDS6t?$5mK_1CMa{A)H4Jpw0|-nj(=Ye20VL^FEb2*X$T0i-}t!1b;t zeMZB=Kf4Lieycvoo-#cNc3+NmR{Yfu@-{suxeile-_f_+2fv<9XxOsW)v4P})w0|; zyd4d?x2y5X(9OHmr+azR{F=%t#j!NIZRt&JyPtDLk>T$LTD zYUWhw{E76Obae+GU7QlbjhIZR)+ z;PBy09CyDF!%Q#|$c-~XMs!Qa-ldpj@~{GU+aUE_=Gy6C?l`Z}*j1%-3ur`X7C>6x z7!xpNQe32Q^RZBGgp^23E7}*zFJ=+Yr%4)B1w4tg*)80tjyT_PyojLmeu*sR55-yO zYjyA4iG6P}NPfMt!u+e(v5Hqlh)94*>~ycO(Y!+%RfaQ#0M9DThS&u%7z=WA2dID< zTk059eMwFy0n)lY)MQz80(+w#ICtYSe6edse2MryE1L*70jnDg#G$FU89NeZrq%Lz zIU759j7{;#*Q-$z?P5TQjY^T7BKf_WYuCnM9~|I3bBTdlYnxG+l6mM)Ke@-R3|Msy z;%0ECxPIV|mMM3qaDsdYEn{eL*xN)!7E?o7S>Og7twE&Tkv_ht{uP7-i{8*jkhq?SR!1d^wv^V{~ivFc$U1z6$NE@L7x$e*l}c^muvbt+bEned=9%4 znMGyn@~!Bx%zXPW%nA9V%@{Vqv}rv5^NZtR{tmW;J@ge>*m3IDWZ7G_eSF-3cNCUJ z!N1z3n=8sKiFBcfEycljRf{&!+$06=Yh?XL!Wp9-j;8UVPBda2&RghBq(r&5q{)3p zaA5R&XuHdtL2_r-(O3xPdkg*PsjO_Wm!t46zx8=0E7F|akg5=iGFvP89FK~!MlonY zdT0qw$mh<@RmJN>s;oy#NybIWxOF3^WNI0~1Cz0GJj7`>mfMHMdI+bMEnUK|DlDAB ze2g+T+H63Yx2tfq)~iomP+ej3WAM&<=yNH1;%mVMOIlKV0KF1o-7|D%&k2=dY;QVh ztW;ZSZnJ&Q-K&S@#~QUbsvHQJj9&zt#50iOE+F7C+Vej3%@#}IgeEjn=F=L{*CP+# znLy6^PhPxQCn>ACmhQV+Y((GlA(@S6U({QU(^fD{otI6z^F=qqf z!fcT`$ZlMxVf7VU9n8wQ3=3KtkV`t-U~i0G2XP+N-|+`-+e7qPo6zQT!abyb5TmJSdo)W8v5GXKf=B#;{qtQJQn7=w$#EhK0iffVP zR4{{v60@ke{2t)Fj8aV~eU268v`2@kvDa<1=K8&y!hK-8ijR$h;Mq7e%5a#Gl+2EF znBDb8)HHV=M#}f6<>c; zE6Pp-sC`sjjGSeCh?9kZ(9C1z0bgJ1K}L{sA!!2j7xCKO$Cy*R+7H!3p#clf~y_j8w!xx@h^$G0+3 zfDdV|h9C8S-KnC0dT~`?#;)MVq_BkaYcWsPBV8E~VJfy&5{ z(bBI*TJvI`CNj_qVFJsYF>L#xmrkHwQ|1|=7e#(^NysuZ&&#+2-VaH)>6eh5?S^ge z##XdXrpE=57m5%L9Y^|k@VU7YmM&O+?oCfVUfS?f=A%?uETa*nx#% zdb%;M@umG;yw%A zx6H@W!tmPEgBC3;S$35$My)3$7uP(kFF_S&;D?`@QMCg8HYVjt+Z^m8GtWA>SY;&B z7qdBfC+3o)x?;m!vGIDs(~$g)el%-gzK%#(OSbf85Iv!-Zez7T6HYCu4uGByT~3I7 zYdL`PiXhKezpsqVmEv(Sz@TmAXHBa2y^%L~l$>`4E>vD?H(-cV8JwC!L;?jt(Fw;H^=U9e9q#T%8|3vYmhU1c**y24g zQp?4h>7KKJ8(djC_LABE)es6gvU{esbOFhZIl>E~*fK*DRa=Yhgc_ju=JYE-PYSt))t zhx11}K>DQn8|y=O<1225wH?&{hX%mG8=28GKik+Ni=xJrF2#ru!TTt)g(m|@nA)o} z%)wlBin=2aBCndR?Uk%PU&SJRGDf6w2Ztq`lCbNKQ*N_br8eli4Ebqf?pXB0t^4~- zTfX5bQ*Txl7Czj+t*}Cxh~uG#!_b|KGKnCB>J8Oh6kJoh$+zgN@UCb_9}NS=b4ZL7 zZIK5>CL5a9i^ZtWms_Ig^NPGz{nIO01LDUWX!yAmsNw^((XITt;NHTWuvD;G)^nc8;K2Q@5Yy2R+>#i{bg>Q3yxz%*R&Vc zPO27jEUu~ILUhrPU)J~V(jk##axSA&aI)%PMx-X*hDBz3^CJ3vjp#WXavv7geAnK7 zL$T8Ucptl5L<=eI!k7j>!+p)n<(w8B*=Xw-TE&x{55J(!N|E4}|!rksZKR?U&Z*_>@ zMhx&Lmt@IWg{!MAo3HIo)Nr{T-v=2qUnPE&I4z5P98|iP;Ap_$4)2{d{2w%L?z$vJ2Sh7_xOk# z+A1jP0TBLWAMoKrBSMT8*c6@2hejp=UOBvHkrd~Nh>xtE_a{`W5mA%-#URR>o z#)P{*xUW_r(l}nhOK!Qgw?&``uQW|XxYasFMhG3^T%vVO)t?vZ?}hF7 zaAeLV`)K|NpLnM?alG*awG5}(%de@a>8F8X z_qzpr7tI4&_xB_Qxd7EL%=+S#uYA3geKz4KNx$D5L#9wotg=g+B5p6cYI+7gz&%HP z^x0j6zP1i2bn>V^uYs`5)epA|1RIJifmq%nD&E)A1^#R1vN9uG{%kA}+HsdNM5`iW zhGood1)2FANAQL~*39rIo4cp7F-Qe{rW^kfzEgr<|F~Yi)w3ym>{ADFSW8gI8>qCN ztk3Y$RkjO;zQOGa8}?6Zvi}EaK$X8mj@g3VeBcYcJ#mR+y!t%4;&90PK5b;Dk`w50 zbL$fie$vIR#otpN{xvp#)f*M5DSVp~qsW~nc@y8sM>QaQ`J?39t&g;=;d0JZ+wuT+ zujLg#{o6MA=>C;F?QR0dvHfVih{sK?DL1B&zymy6eH89=?l@{MHDNFWh6W8^52MN~ z^E2dBwea0+-C(qkOJeu0MNXD#)MIyow?XlWjJ_o=**rD-Jo0^Q9t!K~-+qt#EasAF$QH z=~;HX6)75+a&5W-1G#_|! zWh!>X%#R}W-+0mBI}ESlJo2lb4HhHDP(s4Vku!nzG;AK&f%e30EX;Wc)MmMKUitwA z2^2e9%=>q;jJ5Db;*6TnSin8!Ot`Q+!I6&0YU8y7@$y7`x?dDWMATpv$N z;vF0}-BI7|RmD>ZxMGg5m6tvuVPa7*zT#5efQ>0>?*{!i5_Rdn#3=n*9?AuY+);jy~pM+*H1gw^y!Fp)@Bt8IZVf1Pke6bPN#3Jd}I7o0ZdHL97U3 zQQj*O^)x)j`n0nvE#$!?x7fP@?QSqXoR=dF&%D_>K7FduV_Z@>ymN|TxGxLi-kE(u z>5u?Q;Yrf!_Zu$Vz2#@$p=rL1sox+9KK;OinFjUJkEDredHde*Wkiay&9IzC4(~kRSbHmuvEIsRU?bj?0Ft6wOWP z)&au(Hos0%+*rEf-;E9&bEN0xI_;eRD=$oLoN|b56L4(wIcwq)Y1zp`WERuN&X-f= zQzzLwdMk>Nnx}T?8G{HMT!T6NG|i_%zT->VVfpl=SR09;TwGL(b^7U= z6LGkD2Nh?Fdo6S5;=Hnfkqz~Q6TY@R`uZ3l+OrkafvfNM7JSM_9Uu5_;Rodm_2wr$ z{fHwV#txv>6Ns_P)j=0zEi^B4xq1*?PFy*~)ZBj5h7hJ&gD7Ip@ZRD3f8u3xfHe(n*_5#IUbG*4>fel#+ieh+k&}T1-7=zb}gRTj( zZ$`A;?pedr0=e=)C#yc{H$A8xAcFzRmC@Tjnv&W4n1)b2)zYpzE(409a>r73AZgd` zhH=&3EauuaFa4{}m~!XG*=tic9vIoiq1p>HQaLlJ%FiQ4Wh0g`@YNq|^MhZ2H}@&y z&Z6BREh)%I`91oqux`(Tpn*_dP3J^EJMyK5K_K$@9Y{YPeV2=wDc?}M)OVV zwbgH$cSUio9{}4-2)<1P-NxZ4{tm|aVx*iJpO`Gdk^z_F-@JCy1EmEY7leZO8BR8A z4LUnk<10SQ}6Jt5?DkFKH%%VeEd|qAX_fQZNr$cn}Bm6;YCpxyoqiyfgwac*rt97w` z`nV_7>ce>Tn}&`zf3llDuVP>34uFb+c(&v0{E~;8$EcR)ly(v{a<61x()^kYi)0HF zxDL0Fbl5=59bUNIkzf^Jblj9x^<~&E!CP2j7ziK&o?EpA*+f||9$sA38VIZ^r)^+* zRKdi^b!qCubvWI}WfRp;H&AW4E@>{%=>mR8r|&yRe< zAy-}%diZ|IzPQND)wGrs(om@l~xnn+c?v6E_kStO`)DgEl zc}30_BTK*6a&N!w7Kt{)+=jszvSryhu=dHNoQ+QpbG1cJCti*;w1u%HyfKDi5k~gt zkht@SA%jLCbL(mL@xzaFPnP1KW@UumJtddz?8`xX)QV|wmIHFRIbpFfSXB|6A3s!g z1~nAMW$(P}UpWVtazeiqlGyh66a&Eaqs+tvFs@q8;1x`UYffZ)~hlIRPzh^tA!F-(}J_{Wde& zcJH|+l8V_8gRFQeb%t+|sVPzV=ckNDeq)&b6Es@I3*O#(A+G?%7%%6w{3bbaVyOP; zR@j0Vmq~ts4yr!#{mz~rP;Z-Al?Drfvc6eu?ICa6?w82{o*dap0c_YuJQ%Sbs z+EimlaezPHg7S^7OscJ;x)_d;YGCY1)saBsIz#*VRd3gRiCTWx#hs=%2ygly+zZsz zr3PPfyuD$CvH}wJqwihxNV^Beh&eK+=3^Kl$S+A2ZU0=S8Atc% zt#}TW4m=3932(tF0G(OvN8#8v30y5EGltZAt&aB;#xRn8-HZrY$ms`EIK%#xH~vD_^6FnA4(Rg9O%O#U2t2}#;U-B_TIwM(5}-s$mJHW zCiOMISw96;MsVAZXj=H#K&5=^UC>+nwGr*9PiANYtXczI-6Y&t6$OEwbLFvxjb+6A zNs@XS^hVXMCrH3NYe#d7lk1t&n~V4%tM(8+;y6@Be=$iESD{I4=*}zt&rOF`bKrG9 z33u$wp_uB5Baj$zr>TxS&@eZP1MP5`=^U@-P<=dos_)!&C0^kD=5#l$gQ=h7D#!xf z$;`mSRWfG5e~}zV&S$`{}5PxiD^x z$RT>$4`jJxxsyM72vzkNu@3#F-W;FBZGT!dzVh_uh81s4u1`Hm#{yhoP3Yo_2T~Vb z|2|CGvNWkN;hOrAdD)mk)fz-k9h1D8pu_j$^Rm3Fuw>F|{E=YfH(idIpq;qtmLT+{ z&*|lzp@icXsFrAm*Dtl80k<}`fG-!#Tia#=}}#T!q#1>Hs~1z|`Ry#+9pc#V<%omnW{}Yg`Ein4BIY%ruZZf-ZU;lxlt7*KH(^t z;^d@Yep|SU&0H;XbBh7CZ9dG6pShMx#61D)y5u#xQ&)BlVdH6zKD zJKo%|WKfL$IEbSJa&2KCa?BbtKo1v1MMA$j17q6sv=9(I^-=P1usot`UKW9EItNf4 z{eBbr{}3=c_pp?C6FR20ZLY<|NoyqHre&zP@#At3JBobyq2f znQvl^xh2D@YdND``RvlTwWBG9ov=xbiMt#TW`cl5T z*AW~fx7b2GycL&!W37TGAWe_*8LG8FOKxGE1$!4=KnE+{=m)Zzh>@K6f@TQLg~Xd? z@~NLkJbEu7*z`oZQS;N^>z75jLjd3@mEoR_SZ*#J#hq_?(L3<*!M?Ckv_`>Hw>ieI zc(PLrXQ%7dsjNyA`5gDdOWh9h4Q7yHsF&6BiQk&Nv3Q*~8G9VxaiHrQrvpFd@S>e@ zB`58}7sWgwj6=SW3G3W(jE$DZ8)9`!qrU1N9JKd@YZQ#lEKZLbKsRPawF{LK3BQ}U zb#ZUBD!E?5iupD8^6T3h)+u5i(G73}5ApgZ(O^qlat6N*g&q@oOq+a__LGe>fmc^M zjXlCyk{(k=Q2QX=Bx=h@yA*8;C}TOAKo`UcP#dHj!pE^mBI!7C>=sG{!cOR_VBASL zG04l9iK*%aY2iii_ zAts@F+B_O}+_h({BDOg^3O6zpy?H59I-3{{;vqH`6%Z_*l+#PBrMf|2ummOClhMIA zfwYwu2f7E-4M4zUTfTd{T5eL4h}gSW?1x-3^O}E7Z3x7;_(3c<6?ko@!7c3$^Rm24 zL20$+M<4Y!F6Q-Z5_sazL4$hb)+{>%Jg+?^9_kYY+f9}E3sGuZfF?*R_$F-2=)-kst2GHUkQ{5yFtC}P`aaR_Iu&AYg86Pzx_~UdeA0G4 zbqr8}FV7MoS3C+V{^jzHJNa4|W}nM2KmD^Zgdv^UDj;-T z{;{__5#Yg}tjCdj`4NIlI=sj^e&&yZb`K5o%C9OW%lXiuaxeB_Wo5(z9P?K0SPzbt zV=ZiOeCl^<7&*Dot^fVrGAoL6qb2&v3t)VQz`1#7cr^`(_|8u{sVs-H0oSqP)A$y~ zM&@&_)QjtNpAmJfyI;qi7e6LiBw2R#=-S7Sr>50&?Y zy>@PJIw}`j_*&lEnomB+E4+l;XKr%#2}XjwF>h?vo7-74ypVP^b6}JY@#Nf%$s47f zQ!@p!pe%@mUEhuW@wAT5n}7dKd750c(OMMqvl=lUwvl&rOg*(iX|C)i<5Dz{M3U|} zMVx-~s6XuQ{5&26$ffx)|IXL=a5lH6#+7cP$R#J{)A@>n={PYklIP;3iJ`H?>F{&h z85p)0svVtrcYd5--v%z`@_z8Luwa?Cu*7@g_?it1%gwNjCE=_F#e5&aOsWgj+LLl) zCzy#iWABp!+_dXtZ7Fk%yT5l23%y~JEPDR9AWm`;sw+#UZ?d>;g1AYrpR+iLD;zgI z@rR}Viqyw6eK-S71b$nHW4AG5nE^(zO#LQSrcIzEgyXBHKk*cx=*=@7?_^5h*3%m{ zx2P;`@v|u;7rjLBDKy-Q7qxy9nPiwX@r=P%f8<|X+MbO6{!~Xch53hYofet?0*sLMxYSr8$^QW1s2~i!;BN3cyWa{4u10j$-)jN?r6twtF^zRkc_w4&e2i#b- zH~-6HDM3O1y43(Xm~Ktfj5jTdrVD922X@(jiJdnp#ovBMahPs| z5(cp~;&pRwqHJ5^568#aCz40o;k(dmYt!P2Ph~KkC+YD-N8S7RN^4k| z0b%C^wczF~JT0Ov4-DD}9+N*}ms-3bYb>6tt0il(CBVjwRsNnCznfQGhau!1dyiZA zkGHSQL)NGqP6Kp3bo7KZ7WADb#c*n&EPwTpYho_zAA6;vYkr&?CHkBmU5@3QmiSCA}XCffNh=6so>6N~?7Ti&-Oo?Q%@2=7zAtgtn}yI$pRpWai8$L7+=ipaYw zhrM%4iLSstX(9%HxxT+Z-TY|7n0e?))XtHaj?lPvV`k|7%ZlELQ{=tfh3}cVY`^OC z=7!a;6qww+k0x)KA%?Tp`IwV&0%fJ?I zpybUy{f0Joq`r0z zc~wjM%Y)jkJBArq+q&0>Allq^cm`j75Q`gVuBMkKo6DR4`ri>~dU1SZ+rNfEPs|R8 zsf`C@r~Lxd$d{eo+^`JbP*`wAFR0n=m`f)qO?P)hrcquWiM9#7gp@l_AT&^3*nS=n z_1>1axW&0gf2T>?K5<8?sRosfeE}r}o({z2_2P@6d!XyzLs|%%P_0)1>r18>nlS@1 zsRNL41UN@AIVZl2q6E{MFC+9kEaf*p%OeA5EXwI+5V1vAj_6x|+ONK}LS`NX_n_g8VNbLA zVVo~f)V0pG;lUT4{S*m!sQ8j<%d^R7z_fr)?KD! zN5s9&WLP^VNx2tok$E*|{we2VsghHCxp9giSDLGTu5TS*yI~pZ4wJ*dZ2K1$@iJmf zBI5WswJaGcA{vsv(?29fdJL~YoAJlS3hSP5&XbhM*k=`h6H*Dl!{8UBBzlx5IV(!~ zP&NUe&6gb$O1~KBZd{!P&F+z*)t%`~pxGDi82Y}vd37=vP;Q}4h93H7sH;AE`pMyl zxdfKL3#yG<4Z6BxCdCy~yf(dZp-i7>mT>e;O$l7A+RIC1G{Y=MU`6Q6U4JgeJog@x zm~yP0EXG5m@*^fm70rG=oL9Nz51II9T+hx?(HX?6vHP^W;y(PaTh7+klQB8pccbqu zh*(Z?t^&<(tRT{p%k_=!RgWj?y#~ck25i&$+enQ7vVM$Vo{!U)fc8?_omfHFM432t59;||Inj+8Ie*30u@VhE^ui0 zYl56-V36IZMd2%tw>PW@c4BK^)pOJG}VTJ?}J=Dg5?4&qt~Zm$9#F{k26K;=UXp_GmejH z!bQP+si|51%%om7Ps;O)idf!l4YEz%cG%7=3YZ!DbyptH5xRUfx0utvCwcT?x%jkW z2Y^@cr3d8s!>*XdIhTxGds8}FIH}Lrl>y!2vww@l&DEzT zkDD`D8qZ@R6H!juPchy8+b{<9RH9eokUu_=x7lZ5krlFZ)9j(c!4ddJx;{i{{iezf`{ORYTwooX3bkv=%+4Or?By!VbrkQv0)IZP- z*W7D_EE>z(;?Q48fEkx@&_|_tomtXFy-nu}HRYtXiWUMK?%OGGVu{ZUsi_p3=GbAd zh~KN)YYt1vuug6ckIT!43iU^sEbGVGGEVTTt0o&f^zJ;|-RZuyQ;!9@c+r=mpl$MC z_Ldu5v)br+vY)|xX7V+sH#e;AvL^9>&za0f1J3W=Qwqjxbg$ngD7r=Al$cGeZ(`Ru zc#fgsqCrtr1krWll?1i?~5V*5oT!9HPI9~>UtYV;<4cE9ZT7A4SQDauJ)ON@v zciyt*f>K7+@_l5oj1w%%cmeZZ@F)L8PmNj!&=_yc~fE4 zGgO^;^>9J@G}Q)R3~|*STQ?sO@Mj%t4$xs!V@WZDFd!G8Xq*4>^e0zm*hDjKx;^@^ zmoYK#@%jncx!dN0U*`;7t~+xgzvdmVi#M|P18ILECue=*Y= zud(jeQN+k&KGn5nQnx926>BdBX&*ma`&>=+2D03yMN0SCm@yffxPHOX{O89reaJQ* zX(ah#Og9C18>c$+D}cC+op`EgPR$X;TBP-b+2 zf~J!L?2ji`NXQ^$T#l7|bAOZ88d0fT12=#66zsI~(Yf+%MB=G7PTj~?a2fq=L@m*{V z?XOHI%RpReX}@|OO$Ei66!(q%}ADHvFN7T?a zHw@Ca%P?K@q=t5<9_)YJ@#cnw7wk<6tZ`6fAaQYdY>kYpeVuO-R6uUD9xcephzUJ| z7Fn%(qKCWyDy$IF()AuwNe3PK-BE+rMwzJ!js63fJGbd2(Zc6(xax~3VKHw)ZF-0q zS1}z%M*Z5%|B7}o`1>tauEZFeC=L3j6!=z05^WInwUCs+s`9nw>~n51Ar$W$U%1GT z-c4GKEmUQ9vs9WEXCe{YfO2B4Xi9;vHI(snWsKY3Msw_Ri@v$hjA35GvZkdGqy%^X46^gJVOzoGRAm1m}8wVs}a5%rN!e=U19?IJc&}A2#c^ zFLl<|{N_VgH012(?7h_5Nm0N&&j(O>iH9N?M2u;*p-O+Jn=e? zY#Z}1d{?neYfmiY7)L!P}G3Sz{&@SsTnE2Yj~s9P50zFIMBAwm8+XAss&h z^IE6z$Ak#)2r-%ByP5dZadnKPf(k(c`h>YBvyHisjQB*w)ejlL;MVi_;I}DtBU4k| zrPKIIV{+O}zDW9#8`n(MKef%cxpwT#7L{7D&a(6W$KJcfY`dm+UH6(bYu3zkX4+|| zGo8+~(||(R2tapt`l+3yHsD~H$mm9s}2Bo8$08{MtkED17uEYIw{yqzb@oUGBzmZcMu(xXotPXy%DraKN!Oy;kupYmfSvvEEXL*tZQ|@%ZUj z95@1fEY6mXCk)Ew7-JeIAy@zb>-M!+h_!zE%-a?{`?$*J+Sej|<$4I?pjG)^oAKIj z37lc3zB?`@-UrCrT5v7k1kjSrw6tSbhn3E z6x;)w{x>uwfQG3NoRShY4Jd7hB^NQ3(p^9;d&X!3-`5`U>fM8k-sb4xpoS+YHa&JqT#VucLF z-Tt7r+bbf_q$v{1+m=rhk`?>fEhCv^ka)-ll}B(+?joC;aDjNq!>rH=3x33@FEB})KUmouB z(U*lhlL*dAZ71ePQ3>p70#oe^=QSa9s2-|^HlRYAHG4TO|TR)fuq+lzK_ z#j8cOw&9wCZ5(~sq>z1JTnnhTTAeFs9uGvEBp0SUM5jTFoxL{5`2*gPPGl!D2IYZa z`L&p7mv;j|w+n!0mjxFois@7U1KlO;Jha!Xi6SrG)+y{P;))!ML<;fvmm<&Q;Q#gH*d-x{V{?V z?U@r2A&>Nl6M7gaHmBX3i-;ET_0j{+CUdEgIefH7OMj_>lEiB|_FA-UkT3v^dlro| z-p@%&=UJI@*c~4Im}z09Ejo@&C)hf)C`z$n3@ubFVcEv4! zj5r7EOsbt_A~LmfAKN{;U`gL}@x&uuXYA0Z?WgvBaNuxO-HKps8^Nn4 zS^tx>zIHEa67AT{l#0H-uFNe{=d2pICHcNPvd+3c${RLeE%F_mz`0?8(2-);g z70+_=8FJG1K|%GnJifa^vDG@V`s`pcvwd!%Zzhb#o@1D7$mQF`Jw0*JBMD6+V`lX4 zm)f8=eI-swLUCu;B40L*f+F%#!1DDs>aX$8{w@aO7PgA%g+_7&L`l;C$jcOR1>qSxiHxk7ZLExk<7vaLxCb^3)v-clIpIQqs3#6VP+ANs(qrnESJQ|7SN!xQ-^}&K`Pe+|0(TYZI2%-cwC66n?TrZfaj^68?a>8G zDF1eNR{#>#qTxCLEbz2MVqG*LCAmqaq0?Js=h!CFbGPRa>o$@8WYV$%rUBAXwhh{G zQmjxZG<3LY(YFT_b-qB_5dVw2Vsr|d4t!k1;Cug9<8&&WD!UlqlX|wMnn5ZwY_X#6 zOoB}&I-WU0UHkzq5&G?VVkq9l(^P7JO;mpDt*9*pZK16Fd85r#^4E%D&+!rNt9%== zMLkd&>4+CcWv;C+g8~>%ecG^>3OL?=H%W8a*4dc;v9Dcy5u{BF$|d%&d*E!7`W>@S zjLIe3vVmueMOUkGFs80LSF+m#in23z`b9=;?6l%W?uKdWX#=lGD_`XIctY93E8L@P zc~L7zHF)QxikNa^bL``jJ@v%KJ$SoJz)}m7wQof=*Q%eiS&Qo(OyMjQFq8JNj%+Q9c&VVt@3@nISZXlYm&UGG-LIO0q3e;_MuBSZbc43@2k% zQ_0(UXf7gFR&tDu?;CB8E?8PAfZ%uwan&W&*-kDRk{regIx$#m5aQ=yaY2WUp2_3| zeR+YdD|BrV_Dv;o*I`0 zLt||EX3;PdTqbjV7I1^De3G;yl%5T6<|;r`?Yh}*WIJ0^_GBsFD~@Vi&o{bSv?oaY zH^9@Mk;CK2h#M7ThNwN-u;CX#W#ZzZjZPNgipSCIT6i4aqOYLxSFATsaTed7on5J+ z(}`BR&_V=%;JJDFvZK!oKrz?GoD>j6f%)+Yiee``3SBt|ZnPAo(;q4pJ^yg1K`wH% z9))1%f5U(J70?G?Nt*|hJW($m2)cOFx(}4(<<$tlVBRnC5WB99`v)dR2Q@o5FdMX$ zK^wI}?Zh{F@DMgfjJ0}+ZVZyu8L?Fm4S`NbXfFOJ%#Z@(EeYjLS4*k39Oq*rGde_$ zgoDo5Xp3GPE|0V?-X`VdgjJ2P85_+@aJQtCQ_+IudO3P_DDPm{dU)(C->`&SyeSE{0FV596T^1i6obgQDXgvy>TWhz z;nH=lv?eEy@mFGVchoj{Yf*Zz|2BCyVrYzc&-jo8Ckti^18lx-$nvu<*6 zX3@w-6!k$x_e*A5Ts#`n1i7UEM!u6as*A^xUm@!Hq2EZk?;)%LR9bM7BA>El+~|@p zKQ+~$CO9;hJLX>n+iY+|J+QfeTz|VMUK)v`V<%>SNQ&7A(kNc1hT&On5I8J&@lzEB zD{G9+4{gT9gAwqkWlQvVtdRr#Mq#&K^F_%bkIWUxd5h}du-jKbi~+vp&+yc;y^!YL zaP+KsTEMW9-}*BST`lTc^kgtU?2V^m<^tp~8F$Jcd-RN}50T=~psRzJwp{F}s!Na# zXXBA2#Ec`=H`pFsusp+f2Gr6n2aj_XunZ)GC7b%_6>`^$4$8cHZXt2xA>P%RIt2}) zoGm&_Z@E7@;;GN3gW?-R&n#DvvuTj%O)#nysf2H{6K9dCT|U~S$$6>^sme{sf@x7{ zdu&%$Kd3VhN0dhR6d#(!TelX%ZOkn5vR}CVm>uK75g@e;qp*G3MBd6JJd!HuhWzDrt49c`em$(a^4#}&+b z%nWXISt*`DEgTKn3D835m>MOHiXR*xQ(Iu|rK8P~o%|H2)1Gff!W>Zqr}aY##F^5qzSGV{;5d0lCX(uqjkVk5stHF7*TrrqLT8X$w2D<9Q=z3tHjOJkti z$(r#kPB^5K*F(jEsT>4-ZCmCw39ca8OSxYNE`*DuA9-rWkVU=$0nY){u>#~7@fsko z4d@971=Z1YV31=l3utTvH)!C{>sYwEc-mt5dYIUxP6NGgCyC`f*Fm=Ausgl^`LMXw znv|xp-k6JkEM;KX*<&oA6V@vE5kF~yg>ZlNS^KH5(-(CtPKrI#(zYYlN8=MHhEYh$ z7|!S7p$-IySln7LL~#Q8G6wb`BSs|9sYIKvbQvo>M3NTX2v2X8N2MMOhNpz%-EFE! z@<60mW52&xs!S`tXp_0H7DrKLvm~HAISOo9Jm$<(FMbxw-gMb_!~#<8elev^z5se1kh6sQtJ7N4?SD_tlO&4iHCK0BEJs> z2%}I+DV{71;ZjSLjt0a2hMFq?I^bi!+m$Ggq0Pqg)*d9idW=Nv*MR4`(8OxPsi)2r zdCNzf5{0%>fOd__qZ5R>)=#3*T#{)fYRH?k((RKZK*ihH4ix3`Eoo$_V5?YUC(ppr z;!oYK`p&3O24V|a^s5&jDaXrr%?_mr#S(1#orYp6;qMtP3`x>2*HczNV;yoe)f&))x4Bmp95LcCyUS{M0fdmgE9)?Mp`$Ywm(=LA z|Bbds7c9x^c@7&SBgPE4955le^`JSr8pIJlanrcLXpn5y9kFoCj^+pTJ4*wrjDb%+ z4N7dO(5{oo&?dMmzAB1Xo#=RGEX4*+Df>54#f!Si>;+)!405t0S80#GoRM`gysj!c zta>1)E!Ge1y&r7b#82PTfVmJuTUtny8CM} z+X8_tft`u`WEy10mkb39ptbmsvn-s_EAaX>^#WQa5aHcpz-2x#hccp9sQfs=ElZoV?zge z;&eg~z}qig8O#uDscO;cD&knQ?U^_;2Kv@KvfLcDZXVD>!F1U;3(yaR(?>(OB{*Eh zWB83P&5bF2*TsYOjbG2lu-VnB`f5j5gZuz2-@MQW%^hr4AYyQ)-J+7kv%wdSO&sA) zp0p5C4@|T=MWYdAv9f7vMnnPEuNyc3nv;e@c_pwBXt=y5 z#wm5Sx)i;n_q92yU8%7cU4cQUbp0D!)tMyI^Ov{g0vWIr?OLuQCp zeXUu0E#8hDM2xfc?A6yK6;@F2{luY)(=?-)Rri$hSy|LF7S_}p2RHG>9iJ+TE&Yl( z?vfEhR`N0qHpHv;!H+aj>d1j3C7La3XE;5QI2Ii1m^^&G~S~$u_pG)TCsm8^W?Ef8tJ4?dQ3hc6fF5u3j|?{y-ueIe^zQGyAXj z&~ATurYT6tV_%dx>u17uF?wwvN{x!$5WR(av@#% zGN3($ZnwcS-f1JLJ$6@;<&3)i7z26fJFDw%Z8eutn2wY1O&nV6GcJ4JstD)^bOqMc zu$Ik{GnqUwfuTRGsWC$*oCjPn)HF6-DX3EeZN9LXgj_HdS9v;vklnAkC<#9d?qp*Y zDsyer(AgCUZFSiuH;?3M#~=%XeJ*DDzw?}29`JO|SQN(NsX%Fg%2Og|hyGeGys8xu&wG(?NqW80$(mN<-lh9y5}3xLB! z(>aa|Ak)f0Cd zRn>Rfb8=%!!xj_TW$u{jkNDQruZda})Kbp`pltqrrVo_sNnYJcZrZjCmO7pGKm3+~ z+^}sd=rGz;YtyE$#RDY?1%Tj@(XyjbyKTJ9EuXzuZgSD@71;c9q}A{QD9o@Hn`-#v zNp<#`bjZm0T5wu?sB5!@_cZifv-|)Zg<*(K-H;b1<0`oAG{~WRv7ZGKCH-$F=jPqU zLUrY1gOEP70^~GB^o?Z;ml$rzd1yot!Y-IS(g9&&`n?=8IVOYhJaO9odyg0 zrIP-lhweTFovXTMx@JTuC31qoBirK()}bsno!gm`vVrH-%1d?MT9A}yOnM3|1XWY+ z1T9(y$pFzd4B3{7;L$=~&xaNp`Z9ho;YczeXE=L!51u$CoNXn7Ht~LE5Lk$zO)}Jl z#N}0g5U($u^vnOkD#mhA&J7HC7l#hY>mPPpX!KV89>cfa`fQt|4oGL|Nz~BQssoqK ziAi=0vzYu)ckwhnJIm`S?e!gALLk$^M6U~}x^B6ezBvSj6p4i&QC~8eN}q;nK`g9XxUOc*CzlZDBc$!c zA|&kj>gO!vQfSO{O?mb1`YU(EPM?n?OqgV(ge~=DvtLwbRLe7c)&bNOALQh8U4_bF zA~MpOn5AoVj|-Am48=N1;bcD-HNX$=6Vog2$^mVPu97z4k2sq4D~ z5GfaY9M%z&Lu?lzT6oa_{%)bHFGx9U8RZR2jBG%WHu0sf=v1E{1`1RSg{HkF<#nqn zL<{KEo=q(WU9B>M6UreKTd=zY(D;KR

&kldnqmWVS31lOYrA_ESu)Xd|WcXyI7f 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 z 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

--+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 - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
Powered by Kleeja -
- - \ No newline at end of file diff --git a/plugins/kj_amp_seo/init.php b/plugins/kj_amp_seo/init.php deleted file mode 100644 index e35b48a..0000000 --- a/plugins/kj_amp_seo/init.php +++ /dev/null @@ -1,241 +0,0 @@ - array( - 'en' => 'KJ AMP SEO', - 'ar' => 'AMP سيو' - ), - # who wrote this plugin? - 'plugin_developer' => 'kleeja.com', - # this plugin version - 'plugin_version' => '1.1', - # explain what is this plugin, why should i use it? - 'plugin_description' => array( - 'en' => 'Add AMP support to download pages to enhance SEO for Kleeja', - 'ar' => 'دعم الـ AMP لصفحات التحميل لدعم السيو في كليجا' - ), - # min version of kleeja that's required to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # max version of kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_amp_seo']['first_run']['ar'] = " -شكراً لاستخدامك إضافة كليجا هذه، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -"; - -$kleeja_plugin['kj_amp_seo']['first_run']['en'] = " -Thank you for using our plugin, if you encounter any bugs and errors, contact us:
-info@kleeja.com -"; - -# plugin installation function -$kleeja_plugin['kj_amp_seo']['install'] = function ($plg_id) { - //new options - $options = array( - 'kj_amp_seo_enable' => - array( - 'value' => '1', - 'html' => configField('kj_amp_seo_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_amp_seo', - 'order' => '1', - ), - 'kj_amp_seo_share_buttons' => - array( - 'value' => '1', - 'html' => configField('kj_amp_seo_share_buttons', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_amp_seo', - 'order' => '2', - ), - 'kj_amp_seo_top_ad' => - array( - 'value' => '', - 'html' => configField('kj_amp_seo_top_ad'), - 'plg_id' => $plg_id, - 'type' => 'kj_amp_seo', - 'order' => '3', - ), - 'kj_amp_seo_middle_ad' => - array( - 'value' => '', - 'html' => configField('kj_amp_seo_middle_ad'), - 'plg_id' => $plg_id, - 'type' => 'kj_amp_seo', - 'order' => '4', - ), - 'kj_amp_seo_sticky_ad' => - array( - 'value' => '', - 'html' => configField('kj_amp_seo_sticky_ad'), - 'plg_id' => $plg_id, - 'type' => 'kj_amp_seo', - 'order' => '5', - ), - - 'kj_amp_seo_adsense_client' => - array( - 'value' => '', - 'html' => configField('kj_amp_seo_adsense_client'), - 'plg_id' => $plg_id, - 'type' => 'kj_amp_seo', - 'order' => '6', - ), - ); - - add_config_r($options); - - - //new language variables - add_olang(array( - 'CONFIG_KLJ_MENUS_KJ_AMP_SEO' => 'خيارات AMP سيو', - 'KJ_AMP_SEO_ENABLE' => 'تفعيل صفحات AMP المسرعة ', - 'KJ_AMP_SEO_SHARE_BUTTONS' => 'عرض أزرار المشاركة', - 'KJ_AMP_SEO_TOP_AD' => 'كود slot لإعلان AMP أدسنس علوي، دعه فارغ للتعطيل', - 'KJ_AMP_SEO_MIDDLE_AD' => 'كود slot لإعلان AMP أدسنس وسطي، دعه فارغ للتعطيل', - 'KJ_AMP_SEO_STICKY_AD' => 'كود slot لإعلان AMP أدسنس لاصق، دعه فارغ للتعطيل', - 'KJ_AMP_SEO_ADSENSE_CLIENT' => 'كود client العام لحساب ادسنس الخاص بالإعلانات', - ), - 'ar', - $plg_id); - - add_olang(array( - 'CONFIG_KLJ_MENUS_KJ_AMP_SEO' => 'AMP SEO Options', - 'KJ_AMP_SEO_ENABLE' => 'Enable fast AMP pages', - 'KJ_AMP_SEO_SHARE_BUTTONS' => 'Enable social share buttons', - 'KJ_AMP_SEO_TOP_AD' => 'Slot code for Top AdSense AMP ad, keep it empty to disable', - 'KJ_AMP_SEO_MIDDLE_AD' => 'Slot code for Middle AdSense AMP ad, keep it empty to disable', - 'KJ_AMP_SEO_STICKY_AD' => 'Slot code for Sticky AdSense AMP ad, keep it empty to disable', - 'KJ_AMP_SEO_ADSENSE_CLIENT' => 'Client code for AdSense ads', - ), - 'en', - $plg_id); -}; - - -//plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_amp_seo']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# plugin uninstalling, function to be called at uninstalling -$kleeja_plugin['kj_amp_seo']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'kj_amp_seo_enable', - 'kj_amp_seo_share_buttons', - 'kj_amp_seo_top_ad', - 'kj_amp_seo_middle_ad', - 'kj_amp_seo_sticky_ad', - 'kj_amp_seo_adsense_client', - )); - - - //delete language variables - foreach (['ar', 'en'] as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# plugin functions -$kleeja_plugin['kj_amp_seo']['functions'] = array( - 'Saaheader_links_func' => function ($args) { - if(defined('IN_DOWNLOAD') && !ig('amp_page')){ - global $config; - $current_url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; - $current_url .= strpos($current_url, '?') === false ? '?' : '&'; - - $current_url .= 'amp_page=1'; - - $extra = $args['extra'] . ''; - return compact('extra'); - } - }, - - 'b4_showsty_downlaod_id_filename' => function($args){ - - - if(!ig('amp_page')){ - return; - } - - global $tpl, $lang; - - extract($args); - - $dir = $lang['DIR']; - - $side_menu = array( - 1 => array('name' => 'profile', 'title' => $lang['PROFILE'], 'url' => $config['mod_writer'] ? 'profile.html' : 'ucp.php?go=profile', 'show' => $user_is), - 2 => array('name' => 'fileuser', 'title' => $lang['YOUR_FILEUSER'], 'url' => $config['mod_writer'] ? 'fileuser.html' : 'ucp.php?go=fileuser', 'show' => $config['enable_userfile'] && user_can('access_fileuser')), - 3 => $user_is - ? array('name' => 'logout', 'title' => $lang['LOGOUT'], 'url' => $config['mod_writer'] ? 'logout.html' : 'ucp.php?go=logout', 'show' => true) - : array('name' => 'login', 'title' => $lang['LOGIN'], 'url' => $config['mod_writer'] ? 'login.html' : 'ucp.php?go=login', 'show' => true), - 4 => array('name' => 'register', 'title' => $lang['REGISTER'], 'url' => $config['mod_writer'] ? 'register.html' : 'ucp.php?go=register', 'show' => !$user_is && $config['register']), - ); - - $top_menu = array( - 1 => array('name' => 'index', 'title' => $lang['INDEX'], 'url' => $config['siteurl'], 'show' => true), - 2 => array('name' => 'rules', 'title' => $lang['RULES'], 'url' => $config['mod_writer'] ? 'rules.html' : 'go.php?go=rules', 'show' => true), - 3 => array('name' => 'guide', 'title' => $lang['GUIDE'], 'url' => $config['mod_writer'] ? 'guide.html' : 'go.php?go=guide', 'show' => true), - 4 => array('name' => 'stats', 'title' => $lang['STATS'], 'url' => $config['mod_writer'] ? 'stats.html' : 'go.php?go=stats', 'show' => $config['allow_stat_pg'] && user_can('access_stats')), - 5 => array('name' => 'report', 'title' => $lang['REPORT'], 'url' => $config['mod_writer'] ? 'report.html' : 'go.php?go=report', 'show' => user_can('access_report')), - 6 => array('name' => 'call', 'title' => $lang['CALL'], 'url' => $config['mod_writer'] ? 'call.html' : 'go.php?go=call', 'show' => user_can('access_call')), - ); - - $tpl->assign("side_menu", $side_menu); - $tpl->assign("top_menu", $top_menu); - $tpl->assign("dir", $dir); - - - - $current_url = 'http://'.$_SERVER['HTTP_HOST'] - . preg_replace('/[\&|\?|\/]amp_page=\d/', '', $_SERVER['REQUEST_URI']); - - $tpl->assign("amp_canonical", $current_url); - - - //ads - $tpl->assign("top_ad", trim($config['kj_amp_seo_top_ad']) == '' ? false : trim($config['kj_amp_seo_top_ad'])); - $tpl->assign("middle_ad", trim($config['kj_amp_seo_middle_ad']) == '' ? false : trim($config['kj_amp_seo_middle_ad'])); - $tpl->assign("sticky_ad", trim($config['kj_amp_seo_sticky_ad']) == '' ? false : trim($config['kj_amp_seo_sticky_ad'])); - $tpl->assign("adsense_client", trim($config['kj_amp_seo_adsense_client'])); - - header('Content-type: text/html; charset=UTF-8'); - header('Cache-Control: private, no-cache="set-cookie"'); - header('Pragma: no-cache'); - header('x-frame-options: SAMEORIGIN'); - header('x-xss-protection: 1; mode=block'); - - echo $tpl->display('amp', __DIR__); - - return ['show' => false]; - } -); - diff --git a/plugins/kj_ban_admin/icon.png b/plugins/kj_ban_admin/icon.png deleted file mode 100644 index 117f4e31ab23e2c0c939fbdf78ec3f88ae1887fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10174 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 - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
Powered by Kleeja -
- - \ No newline at end of file diff --git a/plugins/kj_ban_admin/init.php b/plugins/kj_ban_admin/init.php deleted file mode 100644 index b2c0a26..0000000 --- a/plugins/kj_ban_admin/init.php +++ /dev/null @@ -1,128 +0,0 @@ - array( - 'en' => 'Kleeja Admin Firewall', - 'ar' => 'جدار أمني للوحة كليجا' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.0', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Ban a user after so many invalid login attempts to Kleeja control panel', - 'ar' => 'حظر أي مستخدم يحاول الدخول للوحة كليجا بعد عدة محاولات خاطئة' - ), - # Min version of Kleeja that's required to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_ban_admin']['first_run']['ar'] = " -شكراً لاستخدامك هذه الإضافة، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -
-
-

لاحظ:

-عند حظر عضويتك قم بإزالة الحظر من phpMyAdmin، من جدول klj_stats -"; -$kleeja_plugin['kj_ban_admin']['first_run']['en'] = " -Thanks for using this plugin, for bugs reports, contact us at:
-info@kleeja.com -
-
-

Note:

-If your user account got banned, remove it using phpMyAdmin, from klj_stats table. -"; - -# Plugin Installation function -$kleeja_plugin['kj_ban_admin']['install'] = function ($plg_id) { - -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_ban_admin']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['kj_ban_admin']['uninstall'] = function ($plg_id) { -}; - - -# Plugin functions -$kleeja_plugin['kj_ban_admin']['functions'] = array( - - 'admin_login_submit_admin_page' => function ($args) { - $ERRORS = $args['ERRORS']; - if(sizeof($ERRORS)){ - $_SESSION['kj_ban_admin_attemps'] = !empty($_SESSION['kj_ban_admin_attemps']) - ? intval($_SESSION['kj_ban_admin_attemps'])+1 - : 1; - } - - if(!empty($_SESSION['kj_ban_admin_attemps']) && $_SESSION['kj_ban_admin_attemps'] > 10) - { - global $SQL, $dbprefix, $config; - - $query = array( - 'SELECT' => 'ban', - 'FROM' => "{$dbprefix}stats" - ); - - $result = $SQL->build($query); - - $current_ban_data = $SQL->fetch_array($result); - $current_ban_data = $current_ban_data['ban']; - - if(trim($current_ban_data) == ''){ - $current_ban_data = get_ip(); - }else{ - $current_ban_data = rtrim($current_ban_data, '|') . '|'. get_ip(); - } - - $update_query = array( - 'UPDATE' => "{$dbprefix}stats", - 'SET' => "ban='" . $SQL->escape($current_ban_data) . "'" - ); - - $SQL->build($update_query); - if($SQL->affected()) - { - delete_cache('data_ban'); - } - - unset($_SESSION['kj_ban_admin_attemps']); - redirect($config['siteurl']); - } - } -); - diff --git a/plugins/kj_download_speed_limit/icon.png b/plugins/kj_download_speed_limit/icon.png deleted file mode 100644 index 6a345a3bd494afbb5018af6b42bd498c38fc894b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98029 zcmZ^~19W6vw=SHHI!?#7jgD>Gwr#uPq+;8)ZQH8YX2+f6_WPZ4?*0DnzqiKNqt<%n z^Q^h%+-p_sy=zv4f}A)!3^oi12nf8SgoqLd$T!-54k*yS$P)n;@!z*^&Pw7!AT=|% zXMa1;4icKqARw?P{~X^yGO{p1K)}i@RWw{QWM#OF?QQ7|P3(E^3<*7KZS0)6Ja~!!#o+qe{s(3tCj1x0#hRB`Lso%M*xt#Mkd>Z=o{^XjhLDhu z$H~NuOG!lRzvX{>yu=nRE)HA_4DRmk^zJ|D?VZdSm^e8(85o%vn3?JRGU%K=?OY5! z=Vrlk&ruY9*{bTum%1k{h{~xk{EdM3@S2F%AHY`2!Ke62&#B|Q`!3Fbtr~Vr0DMNJm3AS zH~jR;5U1i@j+_n+4*Ja`K{a9HXYc1n@7GDKzu(8>D!>27+r^H4@89;tj{n!j-E6J@ z*V}U~t@&4}nV`jLYy88$h)R5{k`{0w0tbVvk z@cW+CI2PPN5g9=}+SNEuh^drQcz=R{_0`&)SUn=9nV!a58WDpM%qEP1@-}k7uVqbZ zD@ShkLo^!~*RMBKaWySl&gxV~r}{VVBc`#=PhyibA%8L!OCn}O>R20e1Sjv4M+Yb| zZo?*`aOgUNoHQkaqdB(bJiebkzQ_vdp zWodm}kFlET|EV(cXSPFsiKQiPZop0x9GXDY+)GXS1fcGgB6REpN0e+CH5GVR%EEfW zMPyBB)CnRBIh)bkQMbD1ff=QRwwTy@AS5@%RFyQ2QWuG?TQr3%|6~NVV>TVal|K|I zeBJZ_FVaZKzoyb1eyJzF+q=blGdbg#aJhxKTKblAkOJ zlPDmZn8H#LPJEM$fGREad~$aWCo(>=9r#V0?azWyLUM-C7KE?7px-6`4d%jF6$w2v z#d<2YPvdoXG(NwIW-G@n0!Mh_Z4NntVZx?@EiRZo)!t&@Q*C;oK8C|$_iB7E&{Bo2Ux`pK-eRQ=*$yq% zGO5=4E{x{yYzzG8bE4a7%iy#BICgE+EHv&D3oYY4g_l_rh?`{34a# z8(8&Zp~M3KDI{%P%r@igDGd+U%G-(VS^g%dz0Z{tQ3Hyu^cTE&M|9r9F7g@+6u01M zCfZ_G9AA~FTfVspM!Ag5w$u6&JiZ%gyOtUS;8_Wy-$}us;X_AuR^^S&u7j=F@0`w~ z6MU>GA`wFArK-e?RetiX3f#VKpX;=2DPg?ZMf0i%^U`fw?Aw}s*9kMRacb>i-5cUr z8c&Q5rT#tBHc$ei9kqFwH=y)D;Qcqo>zZ0aL#!h!ZLG)u6(?=YaqfL? zv_R@vF_XE%o2e$^PsF$rZw7BFmJ`0E?%5xy;|GSZ2G*1kpJ-c<7R6tl+&A)Xza)Nm z#p1Gx&^=J97)WR^JdK_q_`}N1$_p6htHX8XN3Cf`A3&9u2Rdt)fWSJpnr{x;4t}it zB7Sh>SNa$W5WGd!X&99BbX9#rFbF|yo0E0;G~`3K>zvB?6K(9-2!HR^?N-fOYMhB= z7ggU}tr82;a)eBIbZ5H4>dD1JD8TS~znaY&eqFm%OqV=H;nbt?^mBA$Jj!CdR$r3ft)&ChsZG&^A`CGOdeH7J0d_dXa*Y@|M$B4_;fdy0eefCHOe@C3KJ{ zhHe2|2UOc!W&x6)wJ61wX+iI4dtG?)#AjxjT#$alO>3wQ8FHE@$C0mVD*sX9Hl`lb zSm;rBp~&hPwe*WZV5oM-&##R~A71(FIO}C5dHx;u8!P+4kW_and*4yT#XBVxBjOv_ z)FBH7ctBsLY+_T@+?13Q;^+)I6+XlF%%@X7r0ww_5g|ANA3rg+30$y`IAhY z#Er#lwMGD~#`C@_?8eValMB94M%S<72Ld8AgSCpVeNT{j@levur!`CbGuTxFQ3LLp z8vQM0q4nM-NSD&IX*^Dqw+Afua8oQ@$rWJu@QJIQt|M&Fcj6a;D)L!I3j~6`S8uIX zRGWV2*y7~4x{lO!8VOZu%Foz{4Q{!C3FQq@Nr%DB?@b4#pFh+@e186dDh9Tq{pn_J zM6)++sA?xFyi4JzIGQ8p98g%<+D0CdIBQ#N_{b3KmEQ1ZFv$&tHs|smiDewCD9WY= z2zHTnhN_4Biyhl z8g3DM3B)J8`yR&C1xmzsU?k)9LK(g$NaGhk_YcxHBg~tE3^VO*v_XGTN*f56rsMA^ zHLbdC`ou5K_5pgauLVyILX^X%K(^%mrr?k^RUpawZ(m!l0+TLV-ca&Hdca-$lvjm% zy6e3KZQzhC>g@PM17X+*!7{;qkZKoTiM6j%yeV2TsxD)@k&Fa(!gocd%MO|V zD<)B5o)#0118KRH%Z&0+vJl}#DQlE=D(=Vnh z&{hpctu8Uzh})g3)C`e{CDl~=DJQF}*4YOdTW`Y~UNKWZWAYjTVNKz7Zus;FZHjcJ za@O@te6W$PuA%H9CxrbpQ%L}CjTTSJ8OMwz_SZmeWThh_9}y{_fVfD+#X&wEVOkRn z;(DVNCRs75?XbIrg`=Xl35mjD8WVDN*3mOE{78!p%R1SY)25V;4PN~sy%lpZQB%)G zc>#5g?%T+>r>B>N(Y|9$U-ieTS(zPbeQpEZf`$_f^dbtltodxl4LKQ`>~N?v<)X}B zPxsBOUF%V~z3Y-IPSu^b#rbd+9XQu>Iz#8lk3`2h2(09h1=+h{v9Wg#F_~*fj7qOh zX4INFrZkS4-{J*WVdTW-d6msk>=)0jv1~2MV$u>y;)2>c#S^C^1>Zz|-rH--Sxg7YHJ3C(<^3MW$9lDG; zsaBQhEik&_;-e$jN7V_DHl;#Evl6!JaE){m<+VUcn*22HpZGh5uG5vh9X0Y4M4m{G z)#v^#kj9wruEG4;3{fs*wJG>gbSt|L>V-b1O~#hoXQ3ou>DiE22Z1f~@chrdLBbe* z8~D2UXeqM%-3?*=9%L-`+7i1zmiu9sSprLJvJ?&P$Ajw=s|PIhzqyHu_7JS-eCM_l z7e?^f8)i6+d1|VKfttb1<%3w z5~K{@CRjUzMOD+gnO30lHAD5TN&j3U#44UrWHmM#4mLdaQo8=5h|}}y%voqp{f^p~ ztX}s6fc|prn`LLV#0-q}80CfJ1p*IhG%7qy*aC6P083UGzJ6fqpz_I6ddfQ=oM(NV zWvJ^5OR%$}(Ea@tL8pHKwvrZ`Ts8|IU@kHU}YgF|elxD;% z1!Tm4CH=l;l-!C)fPHop@0FzWZ zgn)0Fprh!qY>aVtt5tI(P~)y zK|rnWg!bL}T(R|;l`ql4??64pN?{S!S~{d=k3`Cdd$m6eH$T-r!)STFj&)Z|9ux#4 z6B}7R%tZA~m(r~7vnZtW)nd!HAv+*RR6%_qBv|{by{?7E?nuwNH}uLIOt)DE2(L9F zi^jVZ6Pwm?jL%Tn*O=3~28GrT-(eK-#U1^0g9}j+w?*xaXB%7scg(|VPbZ<5M$wle z(p;jadBSB3GTsBx;I?O-ex&EJ+f(*> zMnb>A6A;~EPFoB|A$&5iGL^N=&cwpPx9IaH{d}Go^7i}8GY-lch|`02Fpt{MPH)y+ zz-j7L4iyIl+0u&S&lI2bQu04+ffkx_Sn1RET{vhDYbz=O>kXIqTPnXs4YbW8UJE?b zA0jh-_p&4B>OBLG)D@?)Q;b_ejTbMysV`?=tnG!|;1$+I>uwvBtPV((lc!Dcu1xt5qdWY5OWtT~ z`YknyH#v6~IaC0P3K$-RM{ky@a8OI_hIyTNXSUWs=+li!0JYWnz7zi$)Tg?>iWbV3 z`oY@snQzC@xdDXkR;gxn%Zm^0qg=xAFHY7@_k(<>mKjtcG(_i{W7zH<+SnqdCo3t? zsxors;_v*i&UVQlMLDm*|y z*gsP5Pjekn{>b=#Kb#*$zWr5;Z(|G0sf#$2^jIdK0T`zob@>+f=%2#JVu+ zN!Q90hkeOgE^~NcS?u`cBYwT13_qfS%BRX@%-(z0mzVYDv7WSP+^pBe!p>^ns=lqG zkoNOpw<$uFH){9gGwemO2J4T++WbtOcCQ_ta_N(7WED>$eJ5$)#K;X4jh~_R?ZVCHLg9mKjJgBh7I=dIn%3Ta7ycj4m z!>ePax`)-^-F69MWk%49?6M;AEylhpc+IVfI>ts_6Q%x{rz5<)n&jyuS=cgUfI%1K z-G~(oV!l{Zd!=Eh?Ay9kp;t(7cvAAyeph7)dhRCzlEKU+=7sOVBdaJx)n}G!TVZcD z2CjtGYz^-4VL`W(XqqwCycoFbRJKiQ&uHK+mSiA7a!HDAGczn)y7~wyd5cb5IDpy5 zrYLiBvqadTE!3li#DB55mm%@EvrNa5%QNk`71fxdm6%kU_Tgcpnd>9G=j_&|q2!(| z2&jl@h1xFc)_bn7rdTNQP*wsHP}vMK_`>wf^j-?1*e%SLFEuuxw?EQsZS#C~@50l9 zCp7P}*-jfKYCO}8$c!bc%4jPMS``vk_+;fzIVRoVzs&?WA-YP%9j0x>A|}1*ib7en3@Z<6 zv1eh9n^do%_*1imx(bf5byh}1;8P4G+Is|C8^YDwb|rbXN6cwuT%`PwSC+wSn;l_* zU%8tPBXOCeCjot|4PQ(xcyhy*;?2v2wfMu2v=T;Rztg9gHPNSnFX9JlR$ZfgE~b|v zMjxoQ7AIFsv-B_JYq`1bTMWb0ormbqFrD(@N#EC-f+Qb*H``;l4T^l$BJd9uu9NNV z)-fmDj5BL*Tbd|@7Lp@a&_#qByt^x;MzS57Ju2wk<{_L3Jo%FZJa8k_O33*^44>mY}D~RBP#UN|{p`|PHyV7`+7aCQDZKes@ zm6>-}@np#`GK20~<_4RZ;If{s?w|cj*l#Q?&3GdJJ7nvZp5W$PT|{tJ)Y#ZQDxDqI~f3hO!a75Djh6zcy7S0W0hEf zVLCA|6!`mk2n%d6C6pP^UTGwmJ1gKciEC&ca7MbrGN`Lqz4z@hu1XubyHn9F!6nx) z>e!1mg!ZGa)hTtG)2TwI&V}xFsxVsUY&K<;W^jz&>V6Gl^DKt7cNnc#4827&`Ycd; z?qI`I3e*(}=|V#ad&iNVT;ka;7({#rG|Ez9Cl{o}SKfrCK~%FgJkROPJ)gObFQ!O? z#AY#QVv2@rO0TxW^6I2LsFjIeu~_qE8sc#W;f5SQ7?zSmP?I1 zHL4zx-#W=tAblmG(IniTpe|%eIxK+GjrsLPajiO%+fTzZ zd?)<~>G0~~u!>ZYh}01$FMZ9dz;4Chj|90Q)aSP+ABz@5eO>i=7qPu9GSzC9v~TW# z$k7E)SLL2Fz@(gZcOB`0BJ5G2nf4Dqqiki&i{#DI4EkaS7fPk=YNnPE(5GudSF6C= z8?dUk8lfS~?Jh?*_{rY72fwWrb)ccTi|brhQkM%gf8dJa z&qEgblhss~7-%nuy}HHL!3Tij;G1X0--Lvt!``bPZP!1D;iKG&vk(-o^FV|Z5eIJl ze1r059`xi-J4D$qxskT0Sm$=pd8S8hs@1rLT-)vtp$LmSd{0gdRyJ5|SDx3kgYz4+ zcbk?mstp&QZLpXz1H8MvKvW*xXwdmej2qu1UMl6eLTDfYx<_zzjc>m4M>wFFQ;#sC z(dsPB^jM!e%HCNp@6Nn8nQ?`u8qmNBP|KfM7CDF)n7!iN^^o>R{E27pl;Ih+fx)wu zk*9L%LdN&=PDxf<%FPrOFkG^Ixs+!5?_e5&%HvL4IJU_Nc}z|$kWQ`{|m{0~Q6R}D2tC8Oin zgxns;7+n=liq4C~%tVJHxic5fanqM1e7|`IC(dj;wj6qqdauE^ z^;-k6X=F8*&R5(YV^@uGZJTX)EhaCY<)shwOdT6&)U9)_A_LN%gB@YtTno-_r7y1Q zEPqB!kqdqQfeOr9Yzeg7iRuK|?$MrL3>U=6$4K3{rxC`S>#w>`gPEY3-!AW1OUWDn zjug1`HpZ~b@(j>+)7v*cTVWe?^rz0`DIP27)+pivWS9L5g^SukV){wXX}wQzwGXYC zTaX|FUiV7`FF^aCcux~GRnSnNSuhvD65E1@e?!UE(7r!g-}{cj>nDJoD>>p(Dq>DB zYO3MG*Ti&nZ$L|JBl-;p%qC)8$2^N#Y_I7IBPFi$x)6G*A^ zd+SB%g|T?hwJ0#aq~QcA?Btth{^8qk6sKnp)s4_e3q1RlDriM4y zccwJ8%z!VrHhSb@!aO?0+PMlNv_J-Ug zubSQqj$YFGy*Csvn$7pJ;9jAuy|z5fk$l}pyEsL-Y84CbMJ-=R?3SfcI!|)u-Odyt}v6RmUa+a^e0W zFgD0#yjWz3bFh@koh`p<-oFY6+x*DhdS^tiPMT8&{ECt5>|nophQSBhO>kP>JXdTJ zZj|Q8enzclHYbAE?*V7a2<1e-K=J^;$k3{Ht%B$*X%ce{(DQpcShxtdMD<|JD51&f z_$WwyXl@{f(j%?gk)jW_sm4l0_U`5QD6-ltf|w8BXEm^*PM%z1FmjU6YCyJ~EaBWB zi?6OC){dlup(>M{%3j`b%hD1u5l4Vwq1g$YHV}T1X+l%a_Gr;DVK0U#Iy%!c zhk>*|@iXawUhVRwl?>dVct=~A@G7X$z+!-mW{R7yPPOGCDXDL+|8sOwXVkvf1q#V< zt6|d?lc0nsIjXoYTBbelVXNAOZmKxLyNJ@c74k~qpj6EVgS|mt+C@#Kcrglm=e zHuIKmf+~Wbt$5&_49dvCY`4c=Du$iqK&ah1QgqffxK~d*@5OF+Vyfe%NN|a+w-;wN zxETyfdUP?4v%Da2Em)BqPWKvbD9pe`R8gr*dJS%ltN-{T$+!_@&(v(0aaJeAIyp?> z>O$>Fi#HZ-MI*A(r5IcI@W(hZL_~Xvo)(JN zocX=?60Ww^FFm!Bw34K(Ux|#aYU_H!jqVT*X`5Ti2UKQgQomCWpZR82g50c?A#5D1 z#EEKFm!ptrM5j`esp~aG-M4_7BR;Af8K-v2)eZ#W7|yUiR+znvb;((s>>^-L6!OvBZWxRyjuLw(T%Ukm zv}lr@mRUOt{W#VW3Rj(WL}CPc=A)OKR#Gv!4kiV~gR{n%Qe1oK&;Vjn@iIq060w;h zMq2c4H5Z;SiB5wVp?fKjaefP0w|8{5TJ8&%;4{W`(h^pE7%08@dz&j|66usCv8&kC z*vp@oY0WQLTw-@=VQKZKGim*8-s6?bLnJl!k&Xg#nb_5wy}%~m(Rvna_NUN*|BU{il-pwaD$E` z9J+@>+_U3AdV?|Btzz`9V-Ffi{(2hOF|SXF-s zgX8sgz@FlSq=bIal?HuF?M;CcoSFBe{D!s9v)dYL-dlRIC z;zpn1^7;l4s1_CJ(|OFUJ)@pME^t0g3{sMd0~#!!^Jd(?MpSWp9P( z+~kz-6*FXPh4-Fm8=V!WnH1xPok%6&R>$oavPt&T3f`s9x!vjaeuR1THBZwxpHWfa zYO4L?c6_^%)YFox3u%U-96X)L9&`Ork?Q9HsazDnch~CTQ)83f;M^SbxT@jm;J$ks z{5IWXzB`wlz{l>o`BGyNdJ7-f>*h|IvPGxC(Sv#9vLVn6 z7?e^w2Ywj;u4b{Dzy7494%x>PiMw#maTrk+&mLQxYtE~C?+qT@wS?cbuXNA$rBRcF zyaStm^Ai7#B3c?+Tf81ap7hok3sxkp2u;YE=^b9Ns}dp9aC95a^>pM(0bEuv7J6&n zwIfA0Bf4`*dt&c)ZFj8Y?QXb#)*X(&Vu^|eJ!{ueN>!Y|Eo(*YyECnB<5R4?S-lJB z|Loe?mO_m_nOqyog$Ii+xc!?@Hh+r<&?l`Q(Gk4O@mg^M}=Wzvw-+&befjK)O>bH9gXeve-wU^|I-2ReE-` z2F!0%2F~Hl9l?d%i&cE;<*dGhmph=@xT zde>ifrGWGC8{>PaQUN$4F!tT{uhJN}(~ET|eesSS%7>m5c0ev$?!L*5#KX=Vl3dzh zieT-N!Q_98q-!-?MCkR;=7peBZN*92OW*qUGqfZqWY!S`{asZk?91VG?eC3IBg-S%rjsb1MksD}qHAEC zeE)~4il?Hb8E4B%Yh~$rtm^eFg)4gzsQt4Dy~ETn;&UCZ-WD5vTX#!uUkeJ9hW1-2 z-mrQ0jH~2za^iff=);C845NGZLS~h9Ydvj3Hgo}w^>?Ni!uAe1l5D~9h(LE0NW$zE zf0-M9#v?ASa;#>IvTt|ry-^pMX=56-kdt~HR172fW(g{SiQpSa_`$lP^zwt2G6`my zH-SUEPs)kQeYNgzUOQf){j-?;N@IC&5h(-M82fO-$7ljp=-4?ZrxHCu*Pnf)&ffLa z{x~ldYKx)mt&XKAemL%DO<=aKDb|0V*3Iz>cTnqDO05DeM=yDRa%ATQjdKUA)ipEQ zP4-Buflw=8<8Rsu{#($-wsv?Os8TI*zj=*T=_0E4wNs=&z*%b1ZM7LB(*K;r7vM@S z?Wzgom>T4MWncSq3JS0rmrV-nZGE;PtqNc_*z+!TQh<7HsaX#pGt`=g_%%9Q+r;Ig z-=qfU?qmA6eS_ajr@1QZx{CK>_xVO+x;BE%H494>LU!AxNgX>tO#4U3>zK6Aa8mV| z%QW}TC6;Zn3SOCG+!3bPfQA8TfzX_~v6TAXORD~-;%DYzIka!iqE0VeO8M0nnoR8e z7P%A{VD44ZlDTuFTeo7{{B}8bjhUWxAwJR_!2RKEupd?O zu>;ElT0RL+APe}9fJ)OA#fh%(0ixR6lbAD{6@Tz(tQ0d7j5$ZY)|~1F5Z2Tve}>La zSc5-d;+)P+_oQrV4cz&thFKav@lVwsGbhG?9J@%kYeIs&a#%4@a$Bo=jZnF`8$VFJWnS>x zHv%IxOxM|K+1lkLL<|Xi;_Scic@=Py}z;_Ao<{CRxKwQMjHb$wUWnXAP>9hE&z*2b31Avm%u4re_mM z8f|&>FWV8orQaC!w8@4T+?2UZuj7_5ue@XVGJc=n_7-g;DqGl-&+#~5&C7)0U5vc) zYJFZrvU<0mK?7RpC2YkF{93c0)IuL-IeQq-D6`7bBP5c}aj8ANc?q3A0HZ3vF)ld4 z+k>VXBR?fm)Hey4np-38D1_-nx1D^^`JEtV2a@cHK0`Kn&u*N6O@59u%HgP_9YK~Q zRyYj-(rJ)6G-CaOwZ&l$4l+oL&jjJdfizR zrTa&=D!8h$OYGs`3TEeZ8~aqFN=OR^pxbG}_v&5#K{D)!UTBzu@O( zZprm_`eg4Y$gsHgtWO%UskgvJOiRkfF81d{r44^`@D#b0Dhx_rrXGX2;4F{mWHXAH zNE&4;UfvZgJ}Iz%Jb~B70}@)Pm0J)C_-(QiISW)K)S7@OZ%B_IMGZISL!tlYFiVLa z-H)c?nUP3A0>lQ=JnUvVrBVw%&ngTdmWr(mPV?Go-@Kr-MJ>17XuK5WT(i<2rO(AD zkPG_!jGESs*R4GwY**6gKzd16VZ}O97C3ebB-{q3f%Ki2^dvf)O2++FkNkj(n9nY6eG0qgA|~au+#&>ubxQ{BXlxvEMfs( zHjX!3w6_v$A>gI;fy-Lk+|4?~m1P`OKJ1G0U76i$+=Y`?3ij*}orz_MMX{`yJD9vcARU?!8kI1gt-(7K*?G+Q)B3UM*rmPxzTR7>ssYQCqjZv>Td~v>d{Z80# z!sj-L<|@DNYr78rbmTtE>~Nv$zh$rye-WDqBaZwS=uY9^yqc#K|BmLTI_>__UrW(q z8$s79-B_ZFopo|QQSd|D5|LtOd5&`Qecaw^&Xcy7@r3UYa{iu5tY%gmr_8nqVz1k& zh-Zzt)Aq?|3t-J|yT$#=IEB>fvR~Jm%q_;J=5_{tds*c8&FnyM&J#;O{x!ouUz{|; zX@$mhhO<+x=b-Eb#K*lT@B6T9rx=-07R5gE5V}Ilg5mDjT2S`B`eo$cuCaO2^!IITjfb3}37w$%Jm3|}g@o)o z{A!#uI#|Ryj_Y>9E@MjN31Xkd>fBOQP zD^}A3h@1f8HyO&PEs%YWsmO4K3sf?GKFt_(<`Wu`3?v24pI`5NoI;m3XAJ-$AhBF3 z1W0@hcla#4kw>FB=SGaKI>07B|eia#gSos`rXy21$3hrezAX4>%b4^A-)+8yP) zT}k!9{WltsAe_H;>=9~0s$XC+-k?S zk=_?E%y!=zJs(XaC-+g)#pI*FGWGX*3XedRBdcI22{Z$|k5+jcJ=uE5ay;j8$GjOb z6f9W5!-9ng+@xT7j?QbC3y~1?8{FL$`*C|DJ;QeuCf5OpCtf@Xj-2Ont=z$+>ck5d zTaBCrG$RNPDjJs0_0?V?%~h{hbGSnWk(}M_K$!`kkq0t8Xl=`i%Xljm7t=obVHLDYK4?R9zKjCUO0WVNgqE@3}=lfdx;eEA=Ii~|M)RqcmZ(} zle%Mbn}Tg=bVA1)!O}g#1de!E%s{I-qfK7FCZc8GwRjpW z|3xK8c7#|H>o(u-FHxe)DkU-SpJup@jtF$iOx^-{fG413H{{y4@c< zG>-ag`WyDAXd z+qAzPH|@lJg!pB3(3lQ2R{8s-5mi2@FM&e)ia#Jg7|Jxcz#8cXc|wlkqpS%+hxhKH z3*{xmhs(11?2rna%d9<;Nf&+~nG&HMxBK$E2~!Gk>8SvELin~#eLiWx$XT9$vnc8v zQWYAz-$-^m%}?osZax#Xp^f(yf}ldv=PKQtoS02AsMNCu{uaH#V>^>g2@fxJ5`hKK`F5ZA_IfhVJj&iGbJF4*^Pd|w@*2Qo)#xew91*YEl%UXV<6PLBv`BB4cQIoYHb zpk^iAoLqdMA1qT4m-AKCPAREm%AU<$A4ulRSb{}rWG_Fj?&Q!(yKBOPUf8zP>ed;y ze{OHDnLq)3TdnF&IiT_c(I|GWV80z`^&KKG*@}`?^)+jY0Tu%A5*>uupnV$0TnJnZ zq!)&xlodba@aFl34*@Nm@DDIh0Esu=WH;kzb{IaMrwOa=ha6ixKHn$uo1hfR3h=pk zP=>gh`}N6gv#|Jm{O^X#BENGqyKCEvpdJqXJ{FgAx4WO4U@e;HT?tEKZ!U{yPj01cmqSt^?-c;qQH^8a zP2n=#fEU8&&k|{)rq)83X`g_qNJCwT2(kBbYvp`oG5q;rnh##g^zY9+0(e|}h5#Qz zUm|=%num&eeA6?pbp+5{>OsXZ=&IuxRaeFps;=iRpHyZJZZuyT>Eu|L5o%JW>kW5P zlJyBiRxwZPtx)VNM(vR=S%@b*jPs&SsVOL?CZB6>EEN2RAA3*~6OzeVpDbcHjX!?dZ< zk7GZ7FT})K=UHMN8O6I^)?Aqo+?e&WQc^M4Ay=5atIka_ghV$_X<~F`B3(B%X&XGf zpEJ9wGL}rdlkZfj0l()aL<{0lHo6`A`*kywOowbUil ziA}uGcLFLrquij4Er0L)I6Yq|JhKt7m$A&XKVS^9j4yCvsB=Pb1P+}Wy_C{@gC_W{ zm&x9RS>VG8pl5V`q%d<*o2e}5A`R9)Zb^VCxw1G_Wd63g9q<-A5%n8$V!o|6EZ=#p z4{+tPlr-_H8C>rvX9f*<-|v%xP+6%tMu~?HEmmI*IeoUSI+_U=V`H#Ph~`j=8n=a$(HoI-Rn;xrg46~C$2gF$mV zuW9V%q87xlzPb9?TKGq5u!2p7tLmb#VW+brK2l$$@7k=<?i4u1gj`|bF&3prjY5XI@f0e{>I zMEkjQrS+y%tT2@4cx+TyPI9Xnd15|W;TCpwgYbwoN=5!uE&ybWyWkgQ4eNFxFL4j<)RBrmkSCIzJtG?1x1wMj;3 zRJW*uZ?`quWX?7sfw)hrhuRe~`x8})CUgrC6m6%KtPNbAf4+_Q>M$!wp=1yi^J*Bt ziUEPatUG#})gq#Egat;o6VRsDzQP;O&CbX$v>06Z!~I60rZReRxcw5_Vy7BKv()8d zn-|3=-oRTHJnM>th)kMP?Z`WTQ7T3KO>!*Z6|3RweFh**sye%EGA~gh%wa+Qi-c7A zAq4#59E%lx!9kO6wgTbBhQVUXkW*$g3vZK^kFF&Edzb~YJ+fV=J&mI_N&!i_?GsgIGId7Qb|b4J9^E zJ08C7>`NUtH7pSA>|yXw^^Y`6iZ5|gIy1(Go$f3-9?}|pGut|bu9K`HSkR>X>%-|rwP{@Dtd?O<3aiMzEQIR_XXn`S;*sO?NS^o%m$8jPpXUnjQG8(YA@=4e z`1OhFy6fnJO6o~wPP+m^x)A&HZxzB9S04V^_aBzwqo(ijc*I;$H=P%sB21axto>2b zNjYV!8M*JcIR5KmF^AGgmhv_>gIz5tIy7{@3f#H`O)C7O>cx&mu6v-e2j9~BllJHdpXdKohI@-wAJ=Q~C42W|e15KI1>;m>k z%qBT*eUzK$CQ<4v+zo%p;=5x=?|vBlmdG%?=5#m_OLiXnlRsG15!x5U)RoIE-B5FX z?cGiL>8B^eg(uX z+-O{d7qQWjeTMtK3EJQ6+Wi}dS!!eTK}_Rb#+RDF7OxKcw5UPc61o8sE7zwnt@3@3 zjuiOSxVay!Wo>Djj#irW4q=7GWrEz|Z46$T9PY!0J0>Z9)9uz+U+mDKiCQ4B6U#E? z=Vq>Nn{H;wXB}Dn1LVx#IKtp5-&ih%J?ly@Y+~d|2WyQ-o zx86^#@MpTB$tPJbtan`$->w>Uufko^JDU)~GU| zTEH_($Z=fnau$?-&egsGq#Br^yyq76 zR9AzJDT0&#EFBnE1`jK#^6*4)(Om)%BZUhxKhvub$HcYA29h&n{1TiJkQ=n~#fR-* zsA00SrnMhA?BUOg_qmL&|D;U=d_5{0>Mdd^Iwkxq0o>y20o|?zkJ5c>uq?Hc@L|2T zSYAl#lx)DXw(s4TEABAnmMFHVzXCsUJH6yr5~G(X$mo$;kP7fVm_H0 z&*`Ip#sd<7Zhsh!U;=_M=9!F&`k@wcMbdBhxi2U#C&xgha1y-x0(U=mWupFi_pjBT zoG3oCpvfD>ttsETeZa#Py8VtkVsoO~mMVBV+?6OR15x2o3O9~~u=#a}b@QOg$C0+e z3hIo0)^ax3Ja6?nwI~Ifjc=87&EIXnipE;7FT9bI9xeZJ%) zc*p+zbJVQdYXK~MJ^|Xuy>luG$EQNZ0-F&QP(*sphWr&^N3yOTHp%;~)vRTnY&+B{ zB{8MBWIKEza)8j=!Uj}P#LfG{b#FQLhV*d9V4h;D%WrGTs>W)aQ7D_41@Y7)Qc z{aOvWQ>P$!X-OW#*nYYhFb;?pGgyg>>b=O+JkSwLx{fw$zA0&=8~en+F5+q4OWCFi z_QT3WQs>pxN4odRP40joL3Nh5L*#%O^*5bpQ>*%fnpA_EdUOw#seO zzpeH%FGwpIn~<H zqgrTh_U+NE@sKqpH)2Xpc~@mJ$_FWd7$r7(MRd1i;Te#)V^PWKX^0v$>A6j$l3(s7 zeE6zZk2U>FB0Vgs2Xfi&uhQBhQ9}o9&tlOCfWU;)qmClx%Q|Gq!O|^~#X+Hil_z*QPn+c43`5ZV~F0fjfsyLyH&#Dd9bosQJ^TlJ{=Q!pMn zzZ&XWh_a2&(?u+4Sk&qt@w`i8BaP^RJI@n2O+M?thwL(a;gLz4&@lI_<$M&qP1sh8 zd#bD&X$vktFHxgg_@bfFxZyDag>9*OZh;G_Hg;n!AMgC?!#0*ft`^UCuAzT~tz1)S z+^{geL62W{%GiNC66iSiSC)1uUFG5{xAESt-Gk_kTv?a9fK9Th2cz6#fNSvmbc6`IWg zAMNTPTp?KGEc)*2Ss|0>X%<5-tlnLR(7gMq>%b3+bDqY-s`TW~u615{*cg)5?3CjQ z3gQZ@eS|cdwOsbCr~m^^Q>|j-Y-F7ro@_Ft`ieNfswz zN+J(+51MZ`W*DolG#GM(rj7bm(e~Cec6;`^GRVnF_gh51<=?siP^S{9QZk1HbBY0rz8(X@?$(w$q127_xUgLCnpg**0$VM zbIUhUBKN-}pnyRcPUlQ7Tva#sX-A5vE<|2A+8{~H>!1z~(cstfMdZ~*3$ee5;_3VT znf;|Mph|@8dQ-!Lg8w^yl_y7?o=r)8%&xSR#u!?Fpd zC^5+PG;UD6o>D2_dPg&qbgOvYsBb1pN}mAr2JB2mrBMgle*F+~cR~(wEQ!HGZc;Kd zFG_rp^}-rG&V6_ew~a&pC|tJmH5Qh_$O}ugh|Rimh}X zxph8I0WYd)2{XWC{8}+%I`a9gWmi9-m^s0XLsLLA?Iz*wkZF=enQe87+bF|YZx;IbmNQlbzDhI;T*xpiYx_-MdY@>e>2W`|URY;--RI~aN(6=$k-1;cE*ShKbW{bBB-jhob#cDCgsUUdAOv*`zO6HcS3~jA zcj9WYmo{m2-Rve=s`6X4LqvLCsI^^g84NmHLt5)-i@M+3+_XZj4;ZTppzOt~Z^Zs< zjZvU}uMED(>W*krBjaG~#}~2y>@?fo2MYF#3loJVfBjNmz;6%TJnlTo*p67Q zjV$VuXNu^>e-fnkIR%iytr;1opixMhZ&FU6PabQ;K0~@6E=r{bE9Vk8Wy|_@Z4l}^ zB;ZhcY*I*aDxAHrb^Z0*|IsR(3J^XyhiO)~8z1_Ig`RwgP_@{l(nEAd{Qz%v+HPA5 zvTq6ZtcD!Fm^DAIsP-n1@St;amfq>k{a&Lv&vRZ$kV_Y`DY z!mW*>a_)$I;OV6`q@S7KPm7%99qbe}yg%?XNTaH89ud76N3k{K>T3!VRb?w~e-3zE zzExkMLLZ#5biNiZ16lVyJ`r_x*`(cPM#{4n3>w~9E3jpjnC$FsWnwRd-LoYS5umUb zr)pWgJz1pRqf)iIey}APc+td@cxv&;X+G1B`k!0-6i@pj4k=@St0S^3PJ*w(CMk0Y z8S1HLDbhX&xDY$D+>ZW@m5W7~9NKbu0NHKfbDeS~B(|opBItRX1(~|DJKoQS0cF*` z%qfB&A=KwOEiuo%PvX-TU#7{C*fOb06$JOXfDL6;*z_MfJ5uz0ANxv>x&yx})%A7I z>+<~R^cWt_rNagcD@*3GFE*BQFU+tkXK8OZ=%i*3gyu&x_$djGOC

n>T=R{oKPa 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 z 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 - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
Powered by Kleeja -
- - \ No newline at end of file diff --git a/plugins/kj_download_speed_limit/init.php b/plugins/kj_download_speed_limit/init.php deleted file mode 100644 index 3b76f4b..0000000 --- a/plugins/kj_download_speed_limit/init.php +++ /dev/null @@ -1,130 +0,0 @@ - array( - 'en' => 'KJ Download Speed Limit', - 'ar' => 'تحديد سرعة التحميل' - ), - # who wrote this plugin? - 'plugin_developer' => 'kleeja.com', - # this plugin version - 'plugin_version' => '1.1', - # explain what is this plugin, why should i use it? - 'plugin_description' => array( - 'en' => 'Limit files download speed for each group', - 'ar' => 'تحديد سرعة تحميل الملفات لكل مجموعة' - ), - - # min version of kleeja that's required to run this plugin - 'plugin_kleeja_version_min' => '2.3', - # max version of kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_download_speed_limit']['first_run']['ar'] = " -تجد خيار تحديد سرعة التحميل في إعدادات كل مجموعة

-شكراً لاستخدامك الإضافة، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -"; - -$kleeja_plugin['kj_download_speed_limit']['first_run']['en'] = " -You will find the ability to change speed limit in each group settings.

-Thank you for using our plugin, if you encounter any bugs and errors, contact us:
-info@kleeja.com -"; - -# plugin installation function -$kleeja_plugin['kj_download_speed_limit']['install'] = function ($plg_id) { - //new options - $options = array( - 'kj_download_speed_limit_number' => - array( - 'value' => '30', - 'html' => configField('kj_download_speed_limit_number'), - 'plg_id' => $plg_id, - 'type' => 'groups', - 'order' => '1', - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'KJ_DOWNLOAD_SPEED_LIMIT_NUMBER' => 'سرعة التحميل (كيلوبايت/ثانية)' - ), - 'ar', - $plg_id); - - add_olang(array( - 'KJ_DOWNLOAD_SPEED_LIMIT_NUMBER' => 'Download Speed (KB/Second)', - ), - 'en', - $plg_id); -}; - - -//plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_download_speed_limit']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# plugin uninstalling, function to be called at uninstalling -$kleeja_plugin['kj_download_speed_limit']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'kj_download_speed_limit_number', - )); - - - //delete language variables - foreach (['ar', 'en'] as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# plugin functions -$kleeja_plugin['kj_download_speed_limit']['functions'] = array( - 'down_go_page' => function ($args) { - global $config; - - $givenSize = floatval(trim($config['kj_download_speed_limit_number'])); - - if($givenSize === 0){ - return; - } - - define('TrottleLimit', true); - - $chunksize = round($givenSize * 1024); - - return compact('chunksize'); - } -); - diff --git a/plugins/kj_ftp/admin_kjftp.html b/plugins/kj_ftp/admin_kjftp.html deleted file mode 100755 index 685a6b0..0000000 --- a/plugins/kj_ftp/admin_kjftp.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - {olang.KJ_FTP_ADD_NEW_ACCOUNT} - -
- - -
- - - -
- - -
-
- - -
- - - -
- - - {olang.KJ_FTP_OPT_NAME_HELP} -
- -
- - - {olang.KJ_FTP_OPT_HOST_HELP} -
- -
- - -
- -
- - -
- -
- - -
- -
- - - {olang.KJ_FTP_OPT_ROOT_HELP} - -
- - -
- - - {olang.KJ_FTP_OPT_LINK_HELP} -
- -
- - - {olang.KJ_FTP_OPT_PASSIVE_HELP} - -
- -
- - - {olang.KJ_FTP_OPT_ACTIVE_HELP} - -
- - -
- -
- - - - - {H_FORM_KEYS} - -
- - -
-
-
- -
-
- - - - - - \ No newline at end of file diff --git a/plugins/kj_ftp/ftp.php b/plugins/kj_ftp/ftp.php deleted file mode 100644 index 1c2f5a7..0000000 --- a/plugins/kj_ftp/ftp.php +++ /dev/null @@ -1,374 +0,0 @@ -timeout = $timeout; - - $this->debug = defined('DEV_STAGE'); - - - #connect to the server - if($ssl) - { - $this->handler = @ftp_ssl_connect($host, $port, $this->timeout); - } - else - { - $this->handler = @ftp_connect($host, $port, $this->timeout); - } - - - if (!$this->handler) - { -// if($this->debug) -// { -// echo 'can not connect
'; -// var_dump($this->handler); -// -// } - return false; - } - - #pasv mode - @ftp_pasv($this->handler, $passive); - - - #login to the server - if (!ftp_login($this->handler, $user, $password)) - { -// if($this->debug) -// { -// echo 'can not login
'; -// var_dump($this->handler); -// } - return false; - } - - #move to the path - - - $rootPath = trim($rootPath); - - if($rootPath == '/') - { - $rootPath = ''; - } - - - if ($rootPath != '') - { - if (substr($rootPath, -1, 1) == '/') - { - $rootPath = substr($rootPath, 0, -1); - } - } - - $this->root = $rootPath; - - if($this->root != '') - { - $this->link = 'http://' . $host . '/' . ltrim($rootPath, '/'); - - if (!$this->file_exists($this->root)) - { - $this->create_folder(''); - } - } - - return $this; - } - - - - /** - * Go to the given folder - * @param string $dir - * @return bool - */ - public function go_to($dir = '') - { - if ($dir && $dir !== '/') - { - if (substr($dir, -1, 1) == '/') - { - $dir = substr($dir, 0, -1); - } - } - - return @ftp_chdir($this->handler, $dir); - } - - /** - * Close current FTP connection - */ - public function close() - { - if (!$this->handler) - { - return; - } - - ftp_quit($this->handler); - } - - /** - * Get the current folder that we are in now - * @return string - */ - public function current_folder() - { - return ftp_pwd($this->handler); - } - - /** - * Change the file or folder permission - * @param string $file - * @param int $perm - * @return bool - */ - public function chmod($file, $perm = 0644) - { - if (function_exists('ftp_chmod')) - { - $action = @ftp_chmod($this->handler, $perm, $this->_fixpath($file)); - } - else - { - $chmod_cmd = 'CHMOD ' . base_convert($perm, 10, 8) . ' ' . $this->_fixpath($file); - $action = ftp_site($this->handler, $chmod_cmd); - } - return $action; - } - - - /** - * is file exists - * @return bool - */ - public function file_exists($file) - { - return ftp_size($this->handler, $this->_fixpath($file)) > -1; - } - - /** - * fix the given path to be compatible with the FTP - * @param string $path - * @return string - */ - private function _fixpath($path) - { - return ($this->root != '' ? $this->root . '/' : '') . $path; - } - - /** - * Delete given file - * @param string $file - * @return bool - */ - public function delete($file) - { - return @ftp_delete($this->handler, $this->_fixpath($file)); - } - - /** - * Create a file and write the given content to it - * @param string $filePath - * @param $content - * @return bool - */ - public function write($filePath, $content) - { - $cached_file = PATH . 'cache/cached_ftp_' . uniqid(time()); - - #make it as a cached file - $h = @fopen($cached_file, 'wb'); - fwrite($h, $content); - @fclose($h); - - - $r = @ftp_put($this->handler, $this->_fixpath($filePath), $cached_file, FTP_BINARY); - - - kleeja_unlink($cached_file, true); - - return $r; - } - - /** - * Upload a local file to the FTP server - * @param string $local_file - * @param string $server_file - * @return bool - */ - public function upload($local_file, $server_file, $deleteLocal = true) - { - #Initate the upload - #TODO if slow, use ftp_put - $ret = ftp_nb_put($this->handler, $this->_fixpath($server_file), $local_file, FTP_BINARY); - while ($ret == FTP_MOREDATA) - { - #still uploading - if($this->debug) - { - print ftell($this->handler)."\n"; - } - - $ret = ftp_nb_continue($this->handler); - } - - if($deleteLocal) - { - kleeja_unlink($local_file); - } - - #bad uploading - if ($ret != FTP_FINISHED) - { - return false; - } - - return true; - } - - /** - * Rename a file - * @param string $old_file - * @param string $new_file - * @return bool - */ - public function rename($old_file, $new_file) - { - return @ftp_rename($this->handler, $this->_fixpath($old_file), $this->_fixpath($new_file)); - } - - /** - * Create a folder - * @param string $dir - * @param int $perm - * @return bool - */ - public function create_folder($dir, $perm = 0755) - { -// if($this->debug) -// { -// var_dump($this->_fixpath($dir)); -// } - - if(ftp_mkdir($this->handler, $this->_fixpath($dir)) === false) - { - return false; - } - - $this->chmod($this->_fixpath($dir), $perm); - return true; - } - - /** - * Delete the given folder - * @param string $dir - * @return bool - */ - public function delete_folder($dir) - { - return @ftp_rmdir($this->handler, $this->_fixpath($dir)); - } - - /** - * @param string $unique_name - */ - public function setUniqueName($unique_name) - { - $this->unique_name = $unique_name; - } - - /** - * @return string - */ - public function getUniqueName() - { - return $this->unique_name; - } - - /** - * @param string $link - */ - public function setLink($link) - { - if(trim($link) == '') - { - return; - } - - if (substr($link, -1, 1) == '/') - { - $link = substr($link, 0, -1); - } - - $this->link = $link; - } - - /** - * @return string - */ - public function getLink($path) - { - return $this->link . '/' . $path; - } -} - diff --git a/plugins/kj_ftp/ftpUploader.php b/plugins/kj_ftp/ftpUploader.php deleted file mode 100644 index cf5b090..0000000 --- a/plugins/kj_ftp/ftpUploader.php +++ /dev/null @@ -1,845 +0,0 @@ -122, 'png'=>2421 ..] - * @return void - */ - function setAllowedFileExtensions($allowed_file_extensions) - { - $this->allowed_file_extensions = $allowed_file_extensions; - } - - /** - * get the allowed extensions of uploaded files - * @return array - */ - function getAllowedFileExtensions() - { - return $this->allowed_file_extensions; - } - - /** - * set the allowed limit of the uploaded files - * @param int $limit - * @return void - */ - function setUploadFieldsLimit($limit) - { - $this->upload_fields_limit = $limit; - } - - /** - * get the allowed limit of the uploaded files - * @return int - */ - function getUploadFieldsLimit() - { - return $this->upload_fields_limit; - } - - /** - * add an information message to output it to the user - * @param string $message - * @return void - */ - function addInfoMessage($message) - { - array_push($this->messages, array($message, 'info')); - } - - /** - * add an error message to output it to the user - * @param string $message - * @return void - */ - function addErrorMessage($message) - { - array_push($this->messages, array($message, 'error')); - } - - /** - * get all the messages - * @return array - */ - function getMessages() - { - return $this->messages; - } - - - /** - * save the file information to the database - * @param array $fileInfo - * @return void - */ - function saveToDatabase($fileInfo) - { - global $SQL, $dbprefix, $config; - -// $fileInfo = -// [ -// 'saveToFolder' -// 'originalFileName' -// 'generatedFileName' -// 'fileSize' -// 'currentUserId' -// 'fileExtension -// 'ftpName' -// ]; -// + to be added in this method and goes to generateOutputBox -// [ -// 'DeleteCode' -// 'insertId' -// [ - - - #sometime cant see file after uploading.. but .. - getKleejaFtpInstance()->chmod($fileInfo['saveToFolder'] . '/' . $fileInfo['generatedFileName'], 0644); - - - $fileInfo['DeleteCode'] = sha1($fileInfo['generatedFileName'] . uniqid()); - - $queryValues = array - ( - 'name' => $fileInfo['generatedFileName'], - 'real_filename' => $fileInfo['originalFileName'], - 'size' => intval($fileInfo['fileSize']), - 'time' => time(), - 'folder'=> 'ftp://' . $fileInfo['ftpName'] . ':' .$fileInfo['saveToFolder'], - 'type' => $fileInfo['fileExtension'], - 'user' => $fileInfo['currentUserId'], - 'code_del' => $fileInfo['DeleteCode'], - 'user_ip' => get_ip(), - 'id_form' => $config['id_form'], - ); - - $is_img = in_array($fileInfo['fileExtension'], array('png','gif','jpg','jpeg', 'bmp')) ? true : false; - - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_saveToDatabase_qr', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - # insertion query - $insert_query = array( - 'INSERT' => '`' . implode('` , `' , array_keys($queryValues)) . '`', - 'INTO' => "{$dbprefix}files", - 'VALUES' => "'" . implode("', '", array_map(array($SQL, 'escape'), array_values($queryValues))) . "'" - ); - - - # do the query - $SQL->build($insert_query); - - - # inset id so it can be used in url like in do.php?id={id_for_url} - $fileInfo['insertId'] = $SQL->insert_id(); - - - - # update Kleeja stats - $update_query = array( - 'UPDATE' => "{$dbprefix}stats", - 'SET' => ($is_img ? "imgs=imgs+1" : "files=files+1") . ",sizes=sizes+" . intval($fileInfo['fileSize']) . "" - ); - - $SQL->build($update_query); - - - $this->generateOutputBox($fileInfo); - } - - - /** - * generate a box of the result and add it to addInfoMessage - * @param array $fileInfo - * @return void - */ - function generateOutputBox($fileInfo) - { - global $config, $lang; - -// $fileInfo = -// [ -// 'saveToFolder' -// 'originalFileName' -// 'generatedFileName' -// 'fileSize' -// 'currentUserId' -// 'fileExtension -// 'DeleteCode' -// 'insertId' -// [ - - - $is_img = in_array($fileInfo['fileExtension'], array('png','gif','jpg','jpeg', 'bmp')) ? true : false; - - - # information of file, used for generating a url boxes - $file_info = array( - '::ID::' => $fileInfo['insertId'], - '::NAME::' => $fileInfo['generatedFileName'], - '::DIR::' => $fileInfo['saveToFolder'], - '::FNAME::' => $fileInfo['originalFileName'], - ); - - # show del code link box - $extra_del = ''; - if ($config['del_url_file']) - { - $extra_del = get_up_tpl_box('del_file_code', - array( - 'b_title' => $lang['URL_F_DEL'], - 'b_code_link' => kleeja_get_link('del', array('::CODE::'=>$fileInfo['DeleteCode'])) - ) - ); - } - - //show imgs - if($is_img) - { - $img_html_result = ''; - - - $img_html_result .= get_up_tpl_box('image_thumb', - array( - 'b_title' => $lang['URL_F_THMB'], - 'b_url_link'=> kleeja_get_link('image', $file_info), - 'b_img_link'=> kleeja_get_link('thumb', $file_info) - ) - ); - - - - #then show, image box - $img_html_result .= get_up_tpl_box('image', - array( - 'b_title' => $lang['URL_F_IMG'], - 'b_bbc_title'=> $lang['URL_F_BBC'], - 'b_url_link'=> kleeja_get_link('image', $file_info), - ) - ); - - #add del link box to the result if there is any - $img_html_result .= $extra_del; - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_generateOutputBox_image_result', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - #show success message - $this->addInfoMessage( - '
'. $lang['IMG_DOWNLAODED'] . ': ' . - htmlspecialchars($fileInfo['originalFileName']) . '
' . "\n" . - $img_html_result - ); - } - else - { - #then show other files - $else_html_result = get_up_tpl_box('file', - array( - 'b_title' => $lang['URL_F_FILE'], - 'b_bbc_title'=> $lang['URL_F_BBC'], - 'b_url_link'=> kleeja_get_link('file', $file_info), - ) - ); - #add del link box to the result if there is any - $else_html_result .= $extra_del; - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_generateOutputBox_file_result', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - #show success message - $this->addInfoMessage( - '
'. $lang['FILE_DOWNLAODED']. ': ' - . htmlspecialchars($fileInfo['originalFileName']) . '
' . "\n" . - $else_html_result - ); - } - - $this->total_uploaded_files++; - } - - - /** - * here happens the magic, call this on upload submit - * @param int $uploadType upload from files input or links - * @todo watermark - * @return void - */ - function upload($uploadType) - { - global $usrcp, $config, $lang; - - # when $uploadType = 1, then we upload from _file input - # if $uploadType = 2, then we uploading from url which is disabled by default and is buggy - - - #upload to this folder - $current_uploading_folder = $config['foldername']; - - #current user id - $current_user_id = $usrcp->name() ? $usrcp->id() : '-1'; - - - #is captcha is on? - $captcha_enabled = intval($config['safe_code']); - - $return_now = false; - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_upload_1st', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - # check folder our real folder - if(!getKleejaFtpInstance()->file_exists($current_uploading_folder)) - { - if(!$this->make_folder($current_uploading_folder)) - { - $this->addErrorMessage($lang['CANT_DIR_CRT']); - } - } - - - if($return_now) - { - return; - } - - #no uploading yet, or just go to index.php, so we have make a new session - if(!$uploadType) - { - unset($_SESSION['FIILES_NOT_DUPLI'], $_SESSION['FIILES_NOT_DUPLI_LINKS']); - } - - - # is captcha on, and there is uploading going on - if($captcha_enabled && $uploadType) - { - #captcha is wrong - if(!kleeja_check_captcha()) - { - $this->addErrorMessage($lang['WRONG_VERTY_CODE']); - return; - } - } - - # to prevent flooding, user must wait, waiting-time is grapped from Kleeja settings, admin is exceptional - if(! user_can('enter_acp') && user_is_flooding($current_user_id)) - { - $this->addErrorMessage(sprintf($lang['YOU_HAVE_TO_WAIT'], - $current_user_id == '-1' ? $config['guestsectoupload'] : $config['usersectoupload'])); - return; - } - - - #detect flooding - if ($uploadType == 1 && isset($_SESSION['FIILES_NOT_DUPLI'])) - { - if(!empty($_SESSION['FIILES_NOT_DUPLI']) && $_SESSION['FIILES_NOT_DUPLI'] == sha1(serialize(array_column($_FILES, 'name')))) - { - unset($_SESSION['FIILES_NOT_DUPLI']); - redirect('./'); - return; - } - } - - if ($uploadType == 2 && isset($_SESSION['FIILES_NOT_DUPLI_LINKS'])) - { - if($_SESSION['FIILES_NOT_DUPLI_LINKS'] == sha1(serialize($_POST))) - { - unset($_SESSION['FIILES_NOT_DUPLI_LINKS']); - redirect('./'); - return; - } - } - - # flooding code, making sure every ok session is cleared - if ($uploadType == 1 && sizeof($_FILES) > 0) - { - $_SESSION['FIILES_NOT_DUPLI'] = sha1(serialize(array_column($_FILES, 'name'))); - } - elseif($uploadType == 2) - { - $_SESSION['FIILES_NOT_DUPLI_LINKS'] = sha1(serialize($_POST)); - } - - - #now close session to let user open any other page in Kleeja - session_write_close(); - - - # do upload - switch($uploadType) - { - #uploading from a _files input - default: - case 1: - - if(!empty($_FILES['file']['tmp_name'])) - { - $_FILES['file'][0] = $_FILES['file']; - } - - - - # loop the uploaded files - for($i=0; $i<=$this->getUploadFieldsLimit(); $i++) - { - //no file! - if(empty($_FILES['file_' . $i . '_']['tmp_name']) && empty($_FILES['file'][$i]['tmp_name'])) - { - continue; - } - - $this->uploadTypeFile($i, $current_uploading_folder, $current_user_id); - } - - break; - - - #uploading from a url text-input - case 2: - - #if not enabled, quit it - if($config['www_url'] != 1) - { - break; - } - - #loop text inputs - for($i=0; $i<=$this->getUploadFieldsLimit(); $i++) - { - $this->uploadTypeUrl($i, $current_uploading_folder, $current_user_id); - } - - break; - } - - - - # well, no file uploaded, ask user to choose a file before submit - if($this->total_uploaded_files == 0 && sizeof($this->messages) == 0) - { - $this->addErrorMessage($lang['CHOSE_F']); - } - } - - - /** - * upload a file from $_FILES - * @param integer $fieldNumber as in file[i] - * @param $current_uploading_folder - * @param $current_user_id - */ - function uploadTypeFile($fieldNumber, $current_uploading_folder, $current_user_id) - { - global $config, $lang; - - $fileInfo = array( - 'saveToFolder', - 'originalFileName', - 'generatedFileName', - 'fileSize', - 'currentUserId', - 'fileExtension' - ); - - - $fileInfo['saveToFolder'] = $current_uploading_folder; - $fileInfo['currentUserId'] = $current_user_id; - - if(!isset($_FILES['file_' . $fieldNumber . '_']) && isset($_FILES['file'][$fieldNumber])) - { - $_FILES['file_' . $fieldNumber . '_'] = $_FILES['file'][$fieldNumber]; - } - - # file name - $fileInfo['originalFileName'] = isset($_FILES['file_' . $fieldNumber . '_']['name']) - ? htmlspecialchars(str_replace(array(';',','), '', $_FILES['file_' . $fieldNumber . '_']['name'])) - : ''; - - if(empty($fileInfo['originalFileName'])) - { - return; - } - - # get the extension of file - $fileInfo['fileExtension'] = strtolower(array_pop(explode('.', $fileInfo['originalFileName']))); - - - # them the size - $fileInfo['fileSize'] = !empty($_FILES['file_' . $fieldNumber . '_']['size']) - ? intval($_FILES['file_' . $fieldNumber . '_']['size']) - : 0; - - - # get the other filename, changed depend on kleeja settings - $fileInfo['generatedFileName'] = change_filename_decoding($fileInfo['originalFileName'], $fieldNumber, $fileInfo['fileExtension']); - - - # filename templates {rand:..}, {date:..} - $fileInfo['generatedFileName'] = change_filename_templates(trim($config['prefixname']) . $fileInfo['generatedFileName']); - - - # file exists before? change it a little - if(getKleejaFtpInstance()->file_exists($current_uploading_folder . '/' . $fileInfo['generatedFileName'])) - { - $fileInfo['generatedFileName'] = change_filename_decoding( - $fileInfo['generatedFileName'], - $fieldNumber, $fileInfo['fileExtension'], - 'exists' - ); - } - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_uploadTypeFile_1st', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - # now, let process it - if(!in_array(strtolower($fileInfo['fileExtension']), array_keys($this->getAllowedFileExtensions()))) - { - # guest - if($current_user_id == '-1') - { - $this->addErrorMessage( - sprintf($lang['FORBID_EXT'], $fileInfo['fileExtension']) - . '
' . $lang['REGISTER'] . '' - ); - } - # a member - else - { - $this->addErrorMessage(sprintf($lang['FORBID_EXT'], $fileInfo['fileExtension'])); - } - } - # bad chars in the filename - elseif(preg_match ("#[\\\/\:\*\?\<\>\|\"]#", $fileInfo['generatedFileName'])) - { - $this->addErrorMessage(sprintf($lang['WRONG_F_NAME'], htmlspecialchars($_FILES['file_' . $fieldNumber . '_']['name']))); - } - # check file extension for bad stuff - elseif(ext_check_safe($_FILES['file_' . $fieldNumber . '_']['name']) == false) - { - $this->addErrorMessage(sprintf($lang['WRONG_F_NAME'], htmlspecialchars($_FILES['file_' . $fieldNumber . '_']['name']))); - } - # check the mime-type for the file - elseif(check_mime_type($_FILES['file_' . $fieldNumber . '_']['type'], $fileInfo['fileExtension'], $_FILES['file_' . $fieldNumber . '_']['tmp_name']) == false) - { - $this->addErrorMessage(sprintf($lang['NOT_SAFE_FILE'], htmlspecialchars($_FILES['file_' . $fieldNumber . '_']['name']))); - } - # check file size - elseif($this->getAllowedFileExtensions()[$fileInfo['fileExtension']] > 0 - && $fileInfo['fileSize'] >= $this->getAllowedFileExtensions()[$fileInfo['fileExtension']]) - { - $this->addErrorMessage(sprintf( - $lang['SIZE_F_BIG'], - htmlspecialchars($_FILES['file_' . $fieldNumber . '_']['name']), - readable_size($this->getAllowedFileExtensions()[$fileInfo['fileExtension']])) - ); - } - # no errors, so upload it - else - { - - $is_img = in_array($fileInfo['fileExtension'], array('png','gif','jpg','jpeg', 'bmp')) ? true : false; - - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_uploadTypeFile_2nd', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - #cache it locally for now - $localFile = PATH . 'cache/' . uniqid(time()) . '.' . $fileInfo['fileExtension']; - - - # now, upload the file - $file = move_uploaded_file($_FILES['file_' . $fieldNumber . '_']['tmp_name'], $localFile); - - if ($file) - { - //watermark + thumbnail - if($is_img) - { - $this->generateThumbnail( - $localFile, - $fileInfo['fileExtension'], - $current_uploading_folder . '/thumbs/' . $fileInfo['generatedFileName'] - ); - } - - if($config['write_imgs'] != 0) - { - $this->generateWatermark($localFile, $fileInfo['fileExtension']); - } - - - getKleejaFtpInstance()->upload($localFile, $current_uploading_folder . "/" . $fileInfo['generatedFileName']); - - - $fileInfo['ftpName'] = getKleejaFtpInstance()->getUniqueName(); - - $this->saveToDatabase($fileInfo); - } - else - { - $this->addErrorMessage(sprintf($lang['CANT_UPLAOD'], $fileInfo['originalFileName'])); - } - } - } - - - /** - * upload a file from a URL - * @param $fieldNumber - * @param $current_uploading_folder - * @param $current_user_id - */ - function uploadTypeUrl($fieldNumber, $current_uploading_folder, $current_user_id) - { - global $config, $lang; - - $fileInfo = array( - 'saveToFolder', - 'originalFileName', - 'generatedFileName', - 'fileSize', - 'currentUserId', - 'fileExtension' - ); - - - $fileInfo['saveToFolder'] = $current_uploading_folder; - $fileInfo['currentUserId'] = $current_user_id; - - - if(p('file_' . $fieldNumber . '_') == '' || p('file_' . $fieldNumber . '_') == $lang['PAST_URL_HERE']) - { - return; - } - - - # get file name - $fileInfo['originalFileName'] = basename(p('file_' . $fieldNumber . '_')); - - - # file extension, type - $fileExtensions = array_map('strtolower', explode(".", $fileInfo['originalFileName'])); - - - if(sizeof($fileExtensions) > 1 && in_array($fileExtensions[sizeof($fileExtensions)-1], array('html', 'php', 'html'))) - { - $fileInfo['fileExtension'] = strtolower($fileExtensions[sizeof($fileExtensions)-2]); - } - else if(sizeof($fileExtensions) > 0) - { - $fileInfo['fileExtension'] = strtolower($fileExtensions[sizeof($fileExtensions)-1]); - } - else - { - $fileInfo['fileExtension'] = ''; //what to do? - } - - - # change to another filename depend on kleeja settings - $fileInfo['generatedFileName'] = change_filename_decoding($fileInfo['originalFileName'], $fieldNumber, $fileInfo['fileExtension']); - $fileInfo['generatedFileName'] = change_filename_templates(trim($config['prefixname']) . $fileInfo['generatedFileName']); - - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_uploadTypeUrl_1st', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - #forbbiden type ? quit it - if(!in_array(strtolower($fileInfo['fileExtension']), array_keys($this->getAllowedFileExtensions()))) - { - if($current_user_id == '-1') - { - $this->addErrorMessage( - sprintf($lang['FORBID_EXT'], $fileInfo['fileExtension']) . - '
' . - $lang['REGISTER'] . '' - ); - } - # a member - else - { - $this->addErrorMessage(sprintf($lang['FORBID_EXT'], $fileInfo['fileExtension'])); - } - } - # file exists before ? quit it - elseif(getKleejaFtpInstance()->file_exists($current_uploading_folder . '/' . $fileInfo['generatedFileName'])) - { - $fileInfo['generatedFileName'] = change_filename_decoding( - $fileInfo['generatedFileName'], - $fieldNumber, $fileInfo['fileExtension'], - 'exists' - ); - } - # no errors, ok, lets upload now - else - { - - $is_img = in_array($fileInfo['fileExtension'], array('png','gif','jpg','jpeg', 'bmp')) ? true : false; - - - is_array($plugin_run_result = Plugins::getInstance()->run('ftpUploader_uploadTypeUrl_2nd', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - - #no prefix ? http or even ftp, then add one - if(!in_array(strtolower(substr(p('file_' . $fieldNumber . '_'), 0, 4)), array('http', 'ftp:'))) - { - $_POST['file_' . $fieldNumber . '_'] = 'http://' . p('file_' . $fieldNumber . '_'); - } - - #get size, if big quit it - $fileInfo['fileSize'] = get_remote_file_size(p('file_' . $fieldNumber . '_')); - - if($this->getAllowedFileExtensions()[$fileInfo['fileExtension']] > 0 && $fileInfo['fileSize'] >= $this->getAllowedFileExtensions()[$fileInfo['fileExtension']]) - { - $this->addErrorMessage(sprintf( - $lang['SIZE_F_BIG'], - p('file_' . $fieldNumber . '_'), - readable_size($this->getAllowedFileExtensions()[$fileInfo['fileExtension']]) - )); - } - else - { - - #cache it locally for now - $localFile = PATH . 'cache/' . uniqid(time()) . '.' . $fileInfo['fileExtension']; - - #get remote data, if no data quit it - $data = fetch_remote_file( - p('file_' . $fieldNumber . '_'), - $localFile, - 15, - false, - 2, - true - ); - - if($data === false) - { - $this->addErrorMessage($lang['URL_CANT_GET']); - } - else - { - - //watermark + thumbnail - if($is_img) - { - $this->generateThumbnail( - $localFile, - $fileInfo['fileExtension'], - $current_uploading_folder . '/thumbs/' . $fileInfo['generatedFileName'] - ); - - if($config['write_imgs'] != 0) - { - $this->generateWatermark($localFile, $fileInfo['fileExtension']); - } - - } - - - getKleejaFtpInstance()->upload($localFile, $current_uploading_folder . "/" . $fileInfo['generatedFileName']); - - - $fileInfo['ftpName'] = getKleejaFtpInstance()->getUniqueName(); - - $this->saveToDatabase($fileInfo); - } - } - } - } - - - function generateThumbnail($source_path, $ext, $saveToThisFtpPath) - { - global $config; - -// var_dump($source_path); - - # get default thumb dimensions - $thmb_dim_w = $thmb_dim_h = 150; - if(strpos($config['thmb_dims'], '*') !== false) - { - list($thmb_dim_w, $thmb_dim_h) = array_map('trim', explode('*', $config['thmb_dims'])); - } - - - $localThumbFile = $source_path.'.thumb.'.$ext; - - # generate a thumbnail - helper_thumb($source_path, $ext, $localThumbFile, $thmb_dim_w, $thmb_dim_h); - - - if(file_exists($localThumbFile)) - { - getKleejaFtpInstance()->upload($localThumbFile, $saveToThisFtpPath); - } - } - - function generateWatermark($localFile, $ext) - { - helper_watermark( - $localFile, - $ext - ); - } - - - function make_folder($folder) - { - #try to make a new upload folder - - $folders = explode('/', $folder); - - $path = ''; - foreach ($folders as $sub_folder) - { - getKleejaFtpInstance()->create_folder($path . $sub_folder); - getKleejaFtpInstance()->create_folder($path . $sub_folder . '/thumbs'); - - - $this->generate_htaccess($path . $sub_folder); - - $indexHtml = '

KLEEJA ..

'; - - getKleejaFtpInstance()->write($path . $sub_folder . "/index.html", $indexHtml); - getKleejaFtpInstance()->write($path . $sub_folder . "/thumbs/index.html", $indexHtml); - - $path .= $sub_folder . '/'; - } - - return true; - } - - - function generate_htaccess($folder) - { - #data for the htaccess - $htaccess_data = "\nOrder allow,deny\nDeny from all\n\n\nphp_flag engine off\n\n\nphp_flag engine off\n\nRemoveType .php .php* .phtml .pl .cgi .asp .aspx .sql"; - - getKleejaFtpInstance()->write($folder . "/.htaccess", $htaccess_data); - getKleejaFtpInstance()->write($folder . "/thumbs/.htaccess", $htaccess_data); - } -} \ No newline at end of file diff --git a/plugins/kj_ftp/icon.png b/plugins/kj_ftp/icon.png deleted file mode 100644 index 677dbcd79d9e636b1124db50d3039472fb45a49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95471 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 diff --git a/plugins/kj_ftp/index.html b/plugins/kj_ftp/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/kj_ftp/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
- - \ No newline at end of file diff --git a/plugins/kj_ftp/init.php b/plugins/kj_ftp/init.php deleted file mode 100644 index cffdd47..0000000 --- a/plugins/kj_ftp/init.php +++ /dev/null @@ -1,577 +0,0 @@ - array( - 'en' => 'Kleeja Multi-FTP Uploading', - 'ar' => 'تحميل FTP متعدد' - ), - # who is developing this plugin? - 'plugin_developer' => 'kleeja.com', - # this plugin version - 'plugin_version' => '1.1', - # explain what is this plugin, why should i use it? - 'plugin_description' => array( - 'en' => 'Add Multi-FTP support to Kleeja', - 'ar' => 'إضافة دعم التحميل لعدة FTP في كليجا' - ), - # min version of kleeja that's required to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # max version of kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not required -$kleeja_plugin['kj_ftp']['first_run']['ar'] = " -شكراً لاستخدامك إضافة الـFTP المتعدد لكليجا، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -"; - -$kleeja_plugin['kj_ftp']['first_run']['en'] = " -Thank you for using our plugin, if you encounter any bugs and errors, contact us:
-info@kleeja.com -"; - -# plugin installation function -$kleeja_plugin['kj_ftp']['install'] = function ($plg_id) { - global $dbprefix, $SQL; - - //create table - $sql = "CREATE TABLE IF NOT EXISTS `{$dbprefix}kj_ftp_info` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(20) COLLATE utf8_bin DEFAULT NULL, - `host` varchar(199) COLLATE utf8_bin DEFAULT NULL, - `username` varchar(199) COLLATE utf8_bin DEFAULT NULL, - `password` varchar(199) COLLATE utf8_bin DEFAULT NULL, - `port` int(4) DEFAULT '21', - `root` varchar(199) COLLATE utf8_bin DEFAULT '', - `passive` tinyint(1) DEFAULT '1', - `ssl` tinyint(1) DEFAULT '1', - `timeout` int(4) DEFAULT '60', - `link` varchar(199) COLLATE utf8_bin DEFAULT NULL, - `active` tinyint(1) NOT NULL DEFAULT '0', - `group` int(4) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;"; - - $SQL->query($sql); - - - //new language variables - add_olang(array( - 'R_KJ_FTP_OPTIONS' => 'تحميل الـFTP المتعدد', - - # - 'KJ_FTP_OPT_NAME' => 'الإسم الثابت', - 'KJ_FTP_OPT_NAME_HELP' => 'كليجا تستخدم الإسم الثابت لحفظ وجلب الملفات، عند تغيير الإسم الثابت لن نستطيع جلب الملفات! عدل الإسم في حالة واحدة فقط، وهي لربط ملفات سابقة بحساب قديم تم حذفه.', - 'KJ_FTP_OPT_HOST' => 'الخادم', - 'KJ_FTP_OPT_HOST_HELP' => ' مثل: kleeja.com أو سب دومين sub.kleeja.com أو آي بي 188.54.12.11', - 'KJ_FTP_OPT_USERNAME' => 'اسم المستخدم', - 'KJ_FTP_OPT_PASSWORD' => 'كلمة المرور (مخفية، أكتب جديدة فقط لو أردت التغيير)', - 'KJ_FTP_OPT_PORT' => 'منفذ', - 'KJ_FTP_OPT_ROOT' => 'المسار الجذر', - 'KJ_FTP_OPT_ROOT_HELP' => 'المسار الذي ستقوم كليجا بإنشاء مجلد uploads داخله، غالباً دعه فارغ', - 'KJ_FTP_OPT_PASSIVE_HELP' => 'وضع FTP الآمن, قد يكون أبطئ', - 'KJ_FTP_OPT_ACTIVE' => 'مُفعل', - 'KJ_FTP_OPT_ACTIVE_HELP' => 'الحساب غير المفعل لن يستلم تحميلات جديدة ولكن سيتم جلب الملفات التي تم تحميلها مسبقاً منه.', - - 'KJ_FTP_OPT_LINK' => 'الرابط الفعلي', - 'KJ_FTP_OPT_LINK_HELP' => 'مثل: http://kleeja.com أو https://www.example.com/ftp1، لو ترك فارغاً سيتم إستخدام إنتاج رابط من الخادم ومجلد الروت.', - - 'KJ_FTP_ADD_NEW_ACCOUNT' => 'أضف حساب FTP جديد', - 'KJ_FTP_ADD_NEW_ACCOUNT_EXP' => ' هل أنت متأكد من إضافة حساب FTP جديد؟
يمكنك إضافة بيانات الحساب بعد الإضافة وتعديل الحساب.', - - 'KJ_FTP_ACCOUNT_ADDED' => 'تم إضافة الحساب بنجاح', - 'KJ_FTP_ACCOUNT_UPDATED' => 'تم تحديث الحساب بنجاح', - - 'KJ_FTP_ACCOUNT_NAME_CONFLICT' => 'الأسم الثابت موجود في حساب آخر! لايمكنك إستخدام اسم ثابت واحد في حسابين', - # - - 'KJ_FTP_NO_ACTIVE_ACCOUNTS_NOTE' => 'لآنه لايوجد أي حساب FTP تم تفعيله للتحميل، فإن كليجا ستستخدم نظام التحميل الإفتراضي المحلي. لجعل كليجا تقوم بالتحميل بإستخدام الإضافة، قم بتفعيل حساب FTP للتحميل الآن!', - - ), - 'ar', - $plg_id); - - add_olang(array( - 'R_KJ_FTP_OPTIONS' => 'KJ - Multi-FTP Uploading', - - # - 'KJ_FTP_OPT_NAME' => 'Unique Name', - 'KJ_FTP_OPT_NAME_HELP' => 'Kleeja uses this name to identify that a file is related to this FTP account. Changing it will ruin the old files connection. Only edit this if you want to recover a connection of an old FTP account that has been deleted.', - 'KJ_FTP_OPT_HOST' => 'Host', - 'KJ_FTP_OPT_HOST_HELP' => ' Like: kleeja.com or a subdomain: sub.kleeja.com or an IP: 188.54.12.11', - 'KJ_FTP_OPT_USERNAME' => 'Username', - 'KJ_FTP_OPT_PASSWORD' => 'Password (hidden, type a new password only you want to change it)', - 'KJ_FTP_OPT_PORT' => 'Port', - 'KJ_FTP_OPT_ROOT' => 'Root Path', - 'KJ_FTP_OPT_ROOT_HELP' => 'The path where Kleeja will create "uploads" folder in. Usually keeping it empty is fine.', - 'KJ_FTP_OPT_PASSIVE_HELP' => 'Secure Passive FTP mode, slower.', - - 'KJ_FTP_OPT_ACTIVE' => 'Active', - 'KJ_FTP_OPT_ACTIVE_HELP' => 'Inactive account will not receive new uploads to it, but will continue serving previous upload from it.', - - 'KJ_FTP_OPT_LINK' => 'Direct Link', - 'KJ_FTP_OPT_LINK_HELP' => 'Link: http://kleeja.com or https://www.example.com/ftp1; If left empty, we will try to generate a link from the ftp host and given root folder.', - - 'KJ_FTP_ADD_NEW_ACCOUNT' => 'Add New FTP Account', - 'KJ_FTP_ADD_NEW_ACCOUNT_EXP' => 'Are you sure of adding a new FTP account?
You can edit the account information after adding it.', - - 'KJ_FTP_ACCOUNT_ADDED' => 'The FTP account has been added successfully!', - 'KJ_FTP_ACCOUNT_UPDATED' => 'The FTP account has been updated successfully!', - 'KJ_FTP_ACCOUNT_NAME_CONFLICT' => 'The unique name is existed before, you can not have two accounts with same unique name!', - - # - 'KJ_FTP_NO_ACTIVE_ACCOUNTS_NOTE' => 'Because you did not activate any FTP account, Kleeja will fallback to the default local uploading method. To make Kleeja Use FTP uploading method, activate an FTP account now!', - - ), - 'en', - $plg_id); -}; - - -//plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_ftp']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# plugin uninstalling, function to be called at uninstalling -$kleeja_plugin['kj_ftp']['uninstall'] = function ($plg_id) { - //delete options -// delete_config(array( -// 'kj_ftp_home_meta_description', -// 'kj_ftp_home_meta_keywords' -// )); - - //delete language variables - foreach (['ar', 'en'] as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# plugin functions -$kleeja_plugin['kj_ftp']['functions'] = array( - - //add to admin menu - 'begin_admin_page' => function ($args) - { - $adm_extensions = $args['adm_extensions']; - $ext_icons = $args['ext_icons']; - $adm_extensions[] = 'kj_ftp_options'; - $ext_icons['kj_ftp_options'] = 'cloud-upload'; - return compact('adm_extensions', 'ext_icons'); - }, - - 'not_exists_kj_ftp_options' => function() - { - $include_alternative = dirname(__FILE__) . '/kj_ftp_options.php'; - - return compact('include_alternative'); - }, - - - 'begin_index_page' => function() - { - if(defined('DISABLE_KLJ_FTP')){ - return; - } - - $uploadingMethodClass = dirname(__FILE__) . '/ftpUploader.php'; - - return compact('uploadingMethodClass'); - }, - - 'kleeja_get_link_func2' => function($args) - { - if(defined('DISABLE_KLJ_FTP')){ - return; - } - - global $config; - if(($args['pid'] == 'image' || $args['pid'] == 'thumb') && $config['id_form_img'] == 'direct'){ - - $realFolder = str_replace(array_keys($args['extra']), array_values($args['extra']), $args['links'][$args['pid']]); - - $uniqueName = ''; - - if(strpos($realFolder, 'ftp://') !== false) - { - $afterFTP = explode('ftp://', $realFolder, 2); - - - $folder = explode(':', $afterFTP[1], 2); - $uniqueName = $folder[0]; - $realFolder = $folder[1]; - - - if(empty($uniqueName)){ - $return_link = getKleejaFtpInstance()->getLink('') . $realFolder; - }else { - $return_link = getKleejaFtpLink($uniqueName, $realFolder); - } - - return compact('return_link'); - - } - - - } - }, - - - 'down_go_page' => function($args) - { - if(defined('DISABLE_KLJ_FTP')){ - return; - } - - if(strpos($args['f'], 'ftp://') !== false) - { - define('MAKE_DOPHP_301_HEADER', true); - - $afterFTP = explode('ftp://', $args['f'], 2); - - $filename = $args['n']; - $folder = explode(':', $afterFTP[1], 2); - $uniqueName = $folder[0]; - $realFolder = ig('thmb') || ig('thmbf') ? $folder[1] . '/thumbs' : $folder[1]; - - $path_file = getKleejaFtpLink($uniqueName, $realFolder, $filename); - - return compact('path_file'); - } - }, - - 'kleeja_unlink_func' => function($args) - { - if(defined('DISABLE_KLJ_FTP')){ - return; - } - - if(strpos($args['filePath'], 'ftp://') !== false) - { - $afterFTP = explode('ftp://', $args['filePath'], 2); - - $path = explode(':', $afterFTP[1], 2); - $uniqueName = $path[0]; - $filePath = $path[1]; - - - $ftpAccount = getKleejaFtpAccount($uniqueName); - - getKleejaFtpAccountInstance($ftpAccount)->delete($filePath); -// getKleejaFtpAccountInstance($ftpAccount)->close(); - $return = true; - return compact('return'); - } - }, - - 'end_common' => function() - { - global $dbprefix, $SQL; - if(! - $SQL->num_rows( - $SQL->query("SELECT active FROM {$dbprefix}kj_ftp_info WHERE active=1") - ) - ){ - define('DISABLE_KLJ_FTP', true); - } - }, - - - 'stats_start_admin' => function($args) - { - $ADM_NOTIFICATIONS = $args['ADM_NOTIFICATIONS']; - - if(defined('DISABLE_KLJ_FTP')) { - global $lang, $olang; - - $ADM_NOTIFICATIONS['kljFtpNoActive'] = array( - 'id' => 'kljFtpNoActive', - 'msg_type'=> 'info', - 'title'=> $lang['NOTE'] . ' (' . $olang['R_KJ_FTP_OPTIONS'] . ')', - 'msg'=> $olang['KJ_FTP_NO_ACTIVE_ACCOUNTS_NOTE'] - ); - - }else{ - unset($ADM_NOTIFICATIONS['htaccess_u'], $ADM_NOTIFICATIONS['htaccess_t'], $ADM_NOTIFICATIONS['no_thumbs']); - } - - return compact('ADM_NOTIFICATIONS'); - }, - - - //support video plugin - 'plugin:video_player:do_display' => function($args){ - - $folder = $args['file_info']['folder']; - $filename = $args['file_info']['name']; - - if(strpos($folder, 'ftp://') !== false) - { - $afterFTP = explode('ftp://', $folder, 2); - - $path = explode(':', $afterFTP[1], 2); - $uniqueName = $path[0]; - $realFolder = $path[1]; - - - $video_path = getKleejaFtpLink($uniqueName, $realFolder, $filename); - - return compact('video_path'); - } - }, - - //support pdf plugin - 'plugin:pdf_viewer:do_display' => function($args){ - - $folder = $args['file_info']['folder']; - $filename = $args['file_info']['name']; - - if(strpos($folder, 'ftp://') !== false) - { - $afterFTP = explode('ftp://', $folder, 2); - - $path = explode(':', $afterFTP[1], 2); - $uniqueName = $path[0]; - $realFolder = $path[1]; - - - $pdf_path = getKleejaFtpLink($uniqueName, $realFolder, $filename); - - return compact('pdf_path'); - } - } - -); - - - - -if(!function_exists('getKleejaFtpInstance')) -{ - /** - * @return kleeja_ftp|null - */ - function getKleejaFtpInstance() - { - if (!class_exists('kleeja_ftp')) - { - require_once dirname(__FILE__) . '/ftp.php'; - } - - /** @var kleeja_ftp $kljFtp */ - static $kljFtp = null; - - if (is_null($kljFtp)) - { - global $dbprefix, $SQL, $cache; - - - ##### ------ > cached random, solve inadequate mySQL RAND. - if (!($ftp_accounts = $cache->get('klj_ftp::ftp_names'))) - { - $query = array( - 'SELECT' => 'k.name', - 'FROM' => "`{$dbprefix}kj_ftp_info` k", - 'WHERE' => 'k.active = 1' - ); - - $result = $SQL->build($query); - - $ftp_accounts = array(); - - while($row=$SQL->fetch_array($result)) - { - array_push($ftp_accounts, $row['name']); - } - - $SQL->freeresult($result); - - $cache->save('klj_ftp::ftp_names', $ftp_accounts); - } - - - if (sizeof($ftp_accounts) == 0) { - kleeja_show_error(102, 'NO FTP ACCOUNT FOUND!', __FILE__, __LINE__); - return null; - } - - #### - - - //random - shuffle($ftp_accounts); - shuffle($ftp_accounts); - shuffle($ftp_accounts); - - $ftp_account = getKleejaFtpAccount($ftp_accounts[0]); - - $kljFtp = new kleeja_ftp(); - - $connect = $kljFtp->open( - $ftp_account['host'], - $ftp_account['username'], - $ftp_account['password'], - $ftp_account['port'], - $ftp_account['root'], - $ftp_account['passive'] == 1, - $ftp_account['ssl'] == 1, - $ftp_account['timeout'] - ); - - if(!$connect){ - kleeja_show_error(102, 'FTP ACCOUNT CAN NOT CONNECT (' . $ftp_account['name'] . ')!', __FILE__, __LINE__); - } - - - $kljFtp->setUniqueName($ftp_account['name']); - $kljFtp->setLink($ftp_account['link']); - - register_shutdown_function(function() { getKleejaFtpInstance()->close(); } ); - } - - - - return $kljFtp; - } -} - - -if(!function_exists('getKleejaFtpAccountInstance')) -{ - /** - * @return kleeja_ftp|null - */ - function getKleejaFtpAccountInstance($ftp_account) - { - if (!class_exists('kleeja_ftp')) - { - require_once dirname(__FILE__) . '/ftp.php'; - } - - - /** @var kleeja_ftp $kljFtp */ - static $kljFtp = null; -// - if ($kljFtp === null || $kljFtp->getUniqueName() !== $ftp_account['name']) - { - - $kljFtp = new kleeja_ftp(); - - $connect = $kljFtp->open( - $ftp_account['host'], - $ftp_account['username'], - $ftp_account['password'], - $ftp_account['port'], - $ftp_account['root'], - $ftp_account['passive'] == 1, - $ftp_account['ssl'] == 1, - $ftp_account['timeout'] - ); - - if(!$connect){ - kleeja_show_error(102, 'FTP ACCOUNT CAN NOT CONNECT (' . $ftp_account['name'] . ')!', __FILE__, __LINE__); - } - - - $kljFtp->setUniqueName($ftp_account['name']); - $kljFtp->setLink($ftp_account['link']); - - - register_shutdown_function(function() use($kljFtp) { $kljFtp->close(); } ); - } - - - return $kljFtp; - } -} - - -if(!function_exists('getKleejaFtpAccount')) -{ - function getKleejaFtpAccount($uniqueName) - { - global $dbprefix, $SQL; - - $query = array( - 'SELECT' => 'k.*', - 'FROM' => "`{$dbprefix}kj_ftp_info` k", - 'WHERE' => "k.name = '" . $SQL->escape($uniqueName) . "'", - 'LIMIT' => '1' - ); - - $result = $SQL->build($query); - - if($SQL->num_rows($result)) - { - return $SQL->fetch_array($result); - } - - return false; - } -} - -if(!function_exists('getKleejaFtpLink')) -{ - function getKleejaFtpLink($uniqueName, $folder, $filename = '') - { - $ftp_account = getKleejaFtpAccount($uniqueName); - if($ftp_account == false) - { - return '...' . $uniqueName . '...'; - } - - - $link = !empty($ftp_account['link']) ? trim($ftp_account['link']) : ''; - $host = trim($ftp_account['host']); - $rootPath = trim($ftp_account['root']); - - if($link != '') - { - return ltrim($link, '/') . '/' . $folder . ($filename !== '' ? '/' . $filename : ''); - } - - - if ($rootPath != '') - { - if (substr($rootPath, -1, 1) == '/') - { - $rootPath = substr($rootPath, 0, -1); - } - } - - return $host . '/' . $rootPath . '/' . $folder . ($filename !== '' ? '/' . $filename : ''); - } -} - diff --git a/plugins/kj_ftp/kj_ftp_options.php b/plugins/kj_ftp/kj_ftp_options.php deleted file mode 100644 index eedb96f..0000000 --- a/plugins/kj_ftp/kj_ftp_options.php +++ /dev/null @@ -1,187 +0,0 @@ - 'k.*', - 'FROM' => "`{$dbprefix}kj_ftp_info` k", - 'ORDER BY' => 'k.id ASC' - ); - - - $result = $SQL->build($query); - - $result_number = $SQL->num_rows($result); - - $ftp_accounts = array(); - - if($result_number > 0) - { - while($row=$SQL->fetch_array($result)) - { - unset($row['password']); - - $ftp_accounts[] = $row; - } - } - - $SQL->free(); - - - break; - - - /** - * no need! - */ - case 'delete': - break; - - - /** - * add new ftp account - */ - case 'new': - - - //is this enough ? - $unique_name = uniqid(); - - - $insert_query = array( - 'INSERT' => 'name, host', - 'INTO' => "{$dbprefix}kj_ftp_info", - 'VALUES' => "'$unique_name', 'example.com'" - ); - - if ($SQL->build($insert_query)) { - $last_user_id = $SQL->insert_id(); - - kleeja_admin_info($olang['KJ_FTP_ACCOUNT_ADDED'], true, '', true, $action, 3); - } - - break; - - - - case 'edit': - - #save, show info - $data = array( - 'name' => p('name'), - 'host' => p('host'), - 'username' => p('username'), - 'password' => p('password'), - 'link' => p('link'), - 'port' => p('port', 'int'), - 'root' => p('root'), - 'passive' => ip('passive') ? 1 : 0, - 'active' => ip('active') ? 1 : 0, - 'ssl' => ip('ssl') ? 1 : 0, - ); - - - if($data['port'] == 0){ - $data['port'] = 21; - } - - if(strpos($data['host'], 'ftp://') !== false){ - $data['host'] = str_replace('ftp://', '', $data['host']); - } - - if(strpos($data['host'], 'http://') !== false){ - $data['host'] = str_replace('http://', '', $data['host']); - } - - if(strpos($data['host'], 'https://') !== false){ - $data['host'] = str_replace('https://', '', $data['host']); - } - - if ($data['password'] === '') { - unset($data['password']); - } - - - if( - $SQL->num_rows( - $SQL->query("SELECT * FROM {$dbprefix}kj_ftp_info WHERE id<>" . p('id') . " AND name='" . $SQL->escape($data['name']) . "'") - ) - ) - { - kleeja_admin_err($olang['KJ_FTP_ACCOUNT_NAME_CONFLICT'], true, '', true, $action); - } - - - $updateSet = ''; - foreach ($data as $n=>$v){ - $updateSet .= ($updateSet == '' ? '' : ', '). "`$n`='" . $SQL->escape($v) . "'"; - } - - $update_query = array( - 'UPDATE' => "{$dbprefix}kj_ftp_info", - 'SET' => $updateSet, - 'WHERE' => "id=". p('id') - ); - - $SQL->build($update_query); - - - $cache->clean('klj_ftp::ftp_names'); - - kleeja_admin_info($olang['KJ_FTP_ACCOUNT_UPDATED'], true, '', true, $action, 2); - - - break; - -} - - - diff --git a/plugins/kj_meta_seo/icon.png b/plugins/kj_meta_seo/icon.png deleted file mode 100644 index 16dc81393b95cf0d7c259fb22c7b259968ba3e11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101666 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 - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
Powered by Kleeja -
- - \ No newline at end of file diff --git a/plugins/kj_meta_seo/init.php b/plugins/kj_meta_seo/init.php deleted file mode 100644 index 4b9a32e..0000000 --- a/plugins/kj_meta_seo/init.php +++ /dev/null @@ -1,283 +0,0 @@ - array( - 'en' => 'KJ Meta SEO', - 'ar' => 'ميتا سيو' - ), - # who wrote this plugin? - 'plugin_developer' => 'kleeja.com', - # this plugin version - 'plugin_version' => '1.0', - # explain what is this plugin, why should i use it? - 'plugin_description' => array( - 'en' => 'Meta fields plugin to enhance SEO for Kleeja', - 'ar' => 'إضافة الميتا الدسكربشن و الكييورزد لكليجا' - ), - # min version of kleeja that's required to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # max version of kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_meta_seo']['first_run']['ar'] = " -شكراً لاستخدامك إضافة الميتا لكليجا، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -"; - -$kleeja_plugin['kj_meta_seo']['first_run']['en'] = " -Thank you for using our plugin, if you encounter any bugs and errors, contact us:
-info@kleeja.com -"; - -# plugin installation function -$kleeja_plugin['kj_meta_seo']['install'] = function ($plg_id) { - //new options - $options = array( - 'kj_meta_seo_home_meta_description' => - array( - 'value' => '', - 'html' => configField('kj_meta_seo_home_meta_description'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '1', - ), - 'kj_meta_seo_home_meta_keywords' => - array( - 'value' => '', - 'html' => configField('kj_meta_seo_home_meta_keywords'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '2', - ), - 'kj_meta_seo_enable_auto_meta' => - array( - 'value' => '1', - 'html' => configField('kj_meta_seo_enable_auto_meta', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '3', - ), - 'kj_meta_seo_enable_download_auto_meta' => - array( - 'value' => '1', - 'html' => configField('kj_meta_seo_enable_download_auto_meta', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '4', - ), - 'kj_meta_seo_enable_facebook_meta_tags' => - array( - 'value' => '1', - 'html' => configField('kj_meta_seo_enable_facebook_meta_tags', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '5', - ), - 'kj_meta_seo_enable_twitter_meta_tags' => - array( - 'value' => '1', - 'html' => configField('kj_meta_seo_enable_twitter_meta_tags', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '6', - ), - 'kj_meta_seo_image_path' => - array( - 'value' => 'iPhone.png', - 'html' => configField('kj_meta_seo_image_path'), - 'plg_id' => $plg_id, - 'type' => 'kj_meta_seo', - 'order' => '7', - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'CONFIG_KLJ_MENUS_KJ_META_SEO' => 'خيارات ميتا سيو', - 'KJ_META_SEO_HOME_META_DESCRIPTION' => 'الميتا دسكربشن/الوصف للبداية', - 'KJ_META_SEO_HOME_META_KEYWORDS' => 'الميتا كيووردز/الكلمات للبداية', - 'KJ_META_SEO_ENABLE_AUTO_META' => 'إنشاء الميتا بشكل تلقائي لباقي الصفحات', - 'KJ_META_SEO_ENABLE_DOWNLOAD_AUTO_META' => 'إنشاء الميتا بشكل تلقائي لصفحة التحميل', - 'KJ_META_SEO_ENABLE_FACEBOOK_META_TAGS' => 'تضمين الميتا أوبن قراف الخاصة بفيس بوك', - 'KJ_META_SEO_ENABLE_TWITTER_META_TAGS' => 'تضمين الميتا كاردز الخاصة بتويتر', - 'KJ_META_SEO_IMAGE_PATH' => 'الصورة المضمنة في الميتا (توضع في مجلد images)', - - - ), - 'ar', - $plg_id); - - add_olang(array( - 'CONFIG_KLJ_MENUS_KJ_META_SEO' => 'Meta SEO Settings', - 'KJ_META_SEO_HOME_META_DESCRIPTION' => 'Meta description', - 'KJ_META_SEO_HOME_META_KEYWORDS' => 'Meta keywords', - 'KJ_META_SEO_ENABLE_AUTO_META' => 'Auto generate meta codes for all pages', - 'KJ_META_SEO_ENABLE_DOWNLOAD_AUTO_META' => 'Auto generate meta codes for download page', - 'KJ_META_SEO_ENABLE_FACEBOOK_META_TAGS' => 'Includes Facebook OpenGraph meta tags', - 'KJ_META_SEO_ENABLE_TWITTER_META_TAGS' => 'Includes Twitter Cards meta tags', - 'KJ_META_SEO_IMAGE_PATH' => 'Included image in meta (from folder: images)', - - ), - 'en', - $plg_id); -}; - - -//plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_meta_seo']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# plugin uninstalling, function to be called at uninstalling -$kleeja_plugin['kj_meta_seo']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'kj_meta_seo_home_meta_description', - 'kj_meta_seo_home_meta_keywords', - 'kj_meta_seo_enable_auto_meta', - 'kj_meta_seo_enable_download_auto_meta', - 'kj_meta_seo_enable_facebook_meta_tags', - 'kj_meta_seo_enable_twitter_meta_tags', - 'kj_meta_seo_image_path', - )); - - - //delete language variables - foreach (['ar', 'en'] as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# plugin functions -$kleeja_plugin['kj_meta_seo']['functions'] = array( - 'Saaheader_links_func' => function ($args) { - $extra = $args['extra'] . kj_meta_seo_out( - defined('IN_DOWNLOAD') ? 'download' : (defined('IN_REAL_INDEX') ? 'home' : 'any') - ); - return compact('extra'); - } -); - - -/** - * special functions - */ -if (!function_exists('kj_meta_seo_out')) { - function kj_meta_seo_out($in = '') - { - global $config, $title; - - - if($in == 'download' && $config['kj_meta_seo_enable_download_auto_meta'] == 0){ - return null; - } - - if($in == 'any' && $config['kj_meta_seo_enable_auto_meta'] == 0){ - return null; - } - - - $metas = []; - - $desc = ''; - $keywords = ''; - - $included_image = rtrim($config['siteurl'], '/') . '/images/' . $config['kj_meta_seo_image_path']; - - switch ($in){ - case 'home': - - $desc = $config['kj_meta_seo_home_meta_description']; - $keywords = str_replace("،", ",", $config['kj_meta_seo_home_meta_keywords']); - - break; - - - default: - - $desc = $title; - $keywords = implode(', ', kj_meta_seo_keywords_extract($title)); - - break; - - } - - $metas = array_merge($metas, array( - '', - '' - )); - - - - $actual_link = htmlspecialchars('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); - - - if($config['kj_meta_seo_enable_facebook_meta_tags'] == 1) { - $facebook_meta = array( - '', - '', - '', - '', - '', - '' - ); - - $metas = array_merge($metas, $facebook_meta); - } - - if($config['kj_meta_seo_enable_twitter_meta_tags'] == 1) { - $twitter_meta = array( - '', - '', - '', - '', - ); - - $metas = array_merge($metas, $twitter_meta); - } - - return ' - - ' . implode("\n ", $metas) . ' - - '; - - } -} - -if (!function_exists('kj_meta_seo_keywords_extract')) { - function kj_meta_seo_keywords_extract($string = '') - { - return array_filter(preg_split("!\W!", $string)); - } -} \ No newline at end of file diff --git a/plugins/kj_recaptcha/icon.png b/plugins/kj_recaptcha/icon.png deleted file mode 100644 index b6de2ae5068b9497e03745e833f9682dc20e6c20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95248 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

Xjd|VABKbfWY1a5J3 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 ROsW6?002ovPDHLkV1n^bw%Gsx diff --git a/plugins/kj_recaptcha/index.html b/plugins/kj_recaptcha/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/kj_recaptcha/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
Powered by Kleeja -
- - \ No newline at end of file diff --git a/plugins/kj_recaptcha/init.php b/plugins/kj_recaptcha/init.php deleted file mode 100644 index 7453a51..0000000 --- a/plugins/kj_recaptcha/init.php +++ /dev/null @@ -1,469 +0,0 @@ - array( - 'en' => 'KJ reCaptcha', - 'ar' => 'كليجا ريكابتشا' - ), - # who wrote this plugin? - 'plugin_developer' => 'kleeja.com', - # this plugin version - 'plugin_version' => '1.3', - # explain what is this plugin, why should i use it? - 'plugin_description' => array( - 'en' => 'Add reCaptcha to Kleeja', - 'ar' => 'إضافة ريكابتشا لكليجا' - ), - # min version of kleeja that's required to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # max version of kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_recaptcha']['first_run']['ar'] = " -شكراً لاستخدامك إضافة الريكابتشا لكليجا، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -
-للحصول على مفتاح وكود ريكابتشا السري سجل في موقعهم: -google.com/reCaptcha. -
-ثم أضفها في إعدادات -> خيارات الريكابتشا -"; - -$kleeja_plugin['kj_recaptcha']['first_run']['en'] = " -Thank you for using our plugin, if you encounter any bugs and errors, contact us:
-info@kleeja.com -
-to get the reCaptcha sitekey and secret code, visit: -google.com/reCaptcha. -
-then configure this plugin from: settings -> reCaptcha settings -"; - -# plugin installation function -$kleeja_plugin['kj_recaptcha']['install'] = function ($plg_id) { - //new options - $options = array( - 'kj_recaptcha_sitekey' => - array( - 'value' => '', - 'html' => configField('kj_recaptcha_sitekey'), - 'plg_id' => $plg_id, - 'type' => 'kj_recaptcha' - ), - 'kj_recaptcha_secret' => - array( - 'value' => '', - 'html' => configField('kj_recaptcha_secret'), - 'plg_id' => $plg_id, - 'type' => 'kj_recaptcha' - ), - 'kj_recaptcha_invisible' => - array( - 'value' => '0', - 'html' => configField('kj_recaptcha_invisible', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_recaptcha' - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'KJ_RECAPTCHA_SITEKEY' => 'مفتاح الرياكبتشا | sitekey', - 'KJ_RECAPTCHA_SECRET' => 'الكود السري للريكابتشا | secret', - 'KJ_RECAPTCHA_INVISIBLE' => 'نوع الريكابتشا: مخفية invisible', - 'CONFIG_KLJ_MENUS_KJ_RECAPTCHA' => 'خيارات ريكابتشا', - ), - 'ar', - $plg_id); - - add_olang(array( - 'KJ_RECAPTCHA_SITEKEY' => 'reCaptcha sitekey', - 'KJ_RECAPTCHA_SECRET' => 'reCaptcha secret', - 'KJ_RECAPTCHA_INVISIBLE' => 'reCaptcha Type: Invisible', - 'CONFIG_KLJ_MENUS_KJ_RECAPTCHA' => 'reCaptcha Settings', - ), - 'en', - $plg_id); -}; - - -//plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_recaptcha']['update'] = function ($old_version, $new_version) { - - $plg_id = Plugins::getInstance()->installed_plugin_info('kj_recaptcha'); - - if(version_compare($old_version, '1.3', '<')){ - $options = array( - 'kj_recaptcha_invisible' => - array( - 'value' => '0', - 'html' => configField('kj_recaptcha_invisible', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_recaptcha' - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'KJ_RECAPTCHA_INVISIBLE' => 'نوع الريكابتشا: مخفية invisible', - ), - 'ar', - $plg_id); - - add_olang(array( - 'KJ_RECAPTCHA_INVISIBLE' => 'reCaptcha Type: Invisible', - ), - 'en', - $plg_id); - } - - - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# plugin uninstalling, function to be called at uninstalling -$kleeja_plugin['kj_recaptcha']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'kj_recaptcha_sitekey', - 'kj_recaptcha_secret', - 'kj_recaptcha_invisible' - )); - - - foreach (array('ar', 'en') as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# plugin functions -$kleeja_plugin['kj_recaptcha']['functions'] = array( - 'Saaheader_links_func' => function ($args) { - global $config; - $extra = $args['extra'] . "\n" . getReCaptchaInputHeadHtml(); - return compact('extra'); - }, - - 'before_display_template_admin_page' => function ($args) { - global $config; - $extra_header_admin_login = $args['extra_header_admin_login'] . "\n" . getReCaptchaInputHeadHtml(); - $show_captcha = false; - return compact('extra_header_admin_login', 'show_captcha'); - }, - - 'style_parse_func' => function($args) { - global $config; - - - if(in_array($args['template_name'], array('call', 'report', 'register', 'login')) && defined('reCaptcha_all')){ - $html = preg_replace( - '/()/', - getReCaptchaInputHtml().'$1', - $args['html']); - - return compact('html'); - }else if($args['template_name'] == 'index_body' && defined('reCaptcha_index')){ - $html = preg_replace( - '/()/', - getReCaptchaInputHtml().'$1', - $args['html']); - return compact('html'); - }else if($args['template_name'] == 'admin_login'){ - - $html = preg_replace( - '/()/', - getReCaptchaInputHtml().'$1', - $args['html']); - - unset($_SESSION['SHOW_CAPTCHA']); - return compact('html'); - } - }, - - 'admin_login_submit' => function($args){ - global $lang; - - if(!isReCaptchaValid()) { - $ERRORS = $args['ERRORS']; - $ERRORS['recaptcha'] = $lang['WRONG_VERTY_CODE']; - return compact('ERRORS'); - } - }, - - 'end_common' => function($args){ - global $config; - if($config['safe_code'] == 1){ - define('reCaptcha_index', true); - } - - if($config['enable_captcha'] == 1){ - define('reCaptcha_all', true); - } - - $config['enable_captcha'] = 0; - $config['safe_code'] = 0; - }, - - 'submit_report_go_page' => function ($args){ - global $lang; - - if(!isReCaptchaValid()) { - $ERRORS = $args['ERRORS']; - $ERRORS['recaptcha'] = $lang['WRONG_VERTY_CODE']; - return compact('ERRORS'); - } - }, - - 'register_submit' => function ($args){ - global $lang; - - if(!isReCaptchaValid()) { - $ERRORS = $args['ERRORS']; - $ERRORS['recaptcha'] = $lang['WRONG_VERTY_CODE']; - return compact('ERRORS'); - } - }, - - - 'login_after_submit' => function ($args){ - global $lang; - - if(!isReCaptchaValid()) { - $ERRORS = $args['ERRORS']; - $ERRORS['recaptcha'] = $lang['WRONG_VERTY_CODE']; - return compact('ERRORS'); - } - }, - - 'submit_call_go_page' => function($args){ - global $lang; - - if(!isReCaptchaValid()) { - $ERRORS = $args['ERRORS']; - $ERRORS['recaptcha'] = $lang['WRONG_VERTY_CODE']; - return compact('ERRORS'); - } - }, - - 'defaultUploader_upload_1st' => function($args){ - global $lang; - - if(!defined('reCaptcha_index')){ - return null; - } - - $captcha_enabled = true; - - return compact('captcha_enabled'); - - }, - - - 'kleeja_check_captcha_func' => function($args){ - - if(defined('IN_REAL_INDEX')){ - $return = isReCaptchaValid(); - return compact('return'); - } - - // if(defined('IN_ADMIN')) { - $return = true; - return compact('return'); - // } - }, - - 'ftpUploader_upload_1st' => function($args){ - global $lang; - - if(!defined('reCaptcha_index')){ - return null; - } - - $captcha_enabled = true; - - return compact('captcha_enabled'); - }, - -); - -// - - -/** - * special functions - */ - -if(! function_exists('getReCaptchaInputHtml')) -{ - function getReCaptchaInputHtml() - { - global $config; - - if($config['kj_recaptcha_invisible'] == 1) - { - return '
'; - } - else - { - return '
'; - } - - } -} - -if(! function_exists('getReCaptchaInputHeadHtml')) -{ - function getReCaptchaInputHeadHtml() - { - global $config; - - if($config['kj_recaptcha_invisible'] == 1) - { - return ''. - ''; - } - else - { - return ''; - } - - } -} - -if (!function_exists('isReCaptchaValid')) { - function isReCaptchaValid() - { - global $config; - - if(empty($config['kj_recaptcha_sitekey']) || empty($config['kj_recaptcha_secret'])){ - return true; - } - - if (!ip('g-recaptcha-response') || empty(p('g-recaptcha-response'))) { - return false; - } - - try { - $data = array( - 'secret' => $config['kj_recaptcha_secret'], - 'response' => p('g-recaptcha-response'), - 'remoteip' => $_SERVER['REMOTE_ADDR'] - ); - - - $url = 'https://www.google.com/recaptcha/api/siteverify?' . http_build_query($data); - - $result = fetch_remote_file($url); -// -// if (function_exists('curl_version')) { -// $curl = curl_init($url . "?" . http_build_query($data)); -// curl_setopt($curl, CURLOPT_HEADER, false); -// curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); -// curl_setopt($curl, CURLOPT_TIMEOUT, 1); -// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); -// $result = curl_exec($curl); -// -// } else { -//// $options = array( -//// 'http' => array( -//// 'header' => "Content-type: application/x-www-form-urlencoded\r\n", -//// 'method' => 'POST', -//// 'content' => http_build_query($data) -//// ) -//// ); -//// -//// $context = stream_context_create($options); -//// -//// //TODO use our function for fallback -// $result = file_get_contents($url, false, $context); -// } - - - if (empty($result) || is_null($result)) { - return false; - } - - return (bool) json_decode($result)->success; - } - catch (Exception $e) { - return null; - } - } -} diff --git a/plugins/kj_sitemap_seo/icon.png b/plugins/kj_sitemap_seo/icon.png deleted file mode 100644 index 5c0d0ad23536cd378c84b5edbd91b5a11eda4ba6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94855 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 diff --git a/plugins/kj_sitemap_seo/index.html b/plugins/kj_sitemap_seo/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/kj_sitemap_seo/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
- - \ No newline at end of file diff --git a/plugins/kj_sitemap_seo/init.php b/plugins/kj_sitemap_seo/init.php deleted file mode 100644 index ad62d00..0000000 --- a/plugins/kj_sitemap_seo/init.php +++ /dev/null @@ -1,285 +0,0 @@ - array('en' => 'KJ SiteMap SEO', 'ar' => 'كليجا سايت ماب سيو'), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.0', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Generate a sitemap and promote your content by notifying (ping) the search engine once at every new content addition to Kleeja', - 'ar' => 'إنشاء سايت ماب لكليجا وإمكانية بينق محركات البحث بعد كل إضافة محتوى جديد' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '4.0', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_sitemap_seo']['first_run']['ar'] = " -شكراً لاستخدامك إضافة السايت ماب لكليجا، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -
-
-

لاحظ:

-لأداء أفضل للسايت ماب، قم بإضافة السطر التالي لملف : robots.txt
-هذا الملف يكون في مجلد كليجا الأساسي وإن لم يكن موجود فقم بإضافته ثم إضافة السطر التالي له: -
-
-Sitemap: " . (!empty($config['siteurl']) ? $config['siteurl'] : 'http://example.com/') . "go.php?go=sitemap -
أو: -
- " . (!empty($config['siteurl']) ? $config['siteurl'] : 'http://example.com/') . "sitemap.xml - -
-
-تجد إعدادات الإضافة في : إعدادات المركز->خيارات سايب ماب سيو -"; - -$kleeja_plugin['kj_sitemap_seo']['first_run']['en'] = " -Thank you for using our plugin, if you encounter any bugs and errors, contact us:
-info@kleeja.com -
-
-

Note:

-For better results, a file named 'robots.txt' should be existed at Kleeja root folder (same folder as config.php file), and has this line:
- Sitemap:
" . (!empty($config['siteurl']) ? $config['siteurl'] : 'http://example.com/') . "go.php?go=sitemap -
or: -
- " . (!empty($config['siteurl']) ? $config['siteurl'] : 'http://example.com/') . "sitemap.xml -
-
-For Plugin's settings: General Settings->SiteMap SEO Settings -"; - -# Plugin Installation function -$kleeja_plugin['kj_sitemap_seo']['install'] = function ($plg_id) { - //new options - $options = array( - 'kj_sitemap_seo_sitemap_ping_enable' => - array( - 'value' => '0', - 'html' => configField('kj_sitemap_seo_sitemap_ping_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_sitemap_seo' - ), - 'kj_sitemap_seo_sitemap_ping_time' => - array( - 'value' => '0', - 'plg_id' => $plg_id, - 'type' => 'kj_sitemap_seo' - ), - ); - - //TODO add an option to let the use decide the interval between pings - - add_config_r($options); - - - //new language variables - add_olang(array( - 'KJ_SITEMAP_SEO_SITEMAP_PING_ENABLE' => 'تفعيل إعلام محركات البحث عن المحتوى الجديد', - 'CONFIG_KLJ_MENUS_KJ_SITEMAP_SEO' => 'خيارات سايب ماب سيو', - ), - 'ar', - $plg_id); - - add_olang(array( - 'KJ_SITEMAP_SEO_SITEMAP_PING_ENABLE' => 'Notify (ping) search engine about new content', - 'CONFIG_KLJ_MENUS_KJ_SITEMAP_SEO' => 'SiteMap SEO Settings', - ), - 'en', - $plg_id); - - - - if(function_exists('add_to_serve_rules')){ - add_to_serve_rules("'^sitemap\.xml$' => ['file' => 'go.php', 'args' => 'go=sitemap'],", 'kj_sitemap_seo'); - } - -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_sitemap_seo']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstall, function to be called at uninstalling -$kleeja_plugin['kj_sitemap_seo']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'kj_sitemap_seo_sitemap_ping_enable', - 'kj_sitemap_seo_sitemap_ping_time' - )); - - - //delete language variables - delete_olang(null, null, $plg_id); - - - //remove rules - if(function_exists('remove_from_serve_rules')) { - remove_from_serve_rules('kj_sitemap_seo'); - } -}; - - -# Plugin functions -$kleeja_plugin['kj_sitemap_seo']['functions'] = array( - - - //new page - 'default_go_page' => function () { - global $SQL, $dbprefix, $config; - - if (g('go') == 'sitemap') { - header('Content-Type: application/xml; charset=utf-8'); - echo '' . "\n"; - echo '' . "\n"; - - $query = array( - 'SELECT' => 'f.id, f.name, f.real_filename, f.folder, f.type, f.time', - 'FROM' => "{$dbprefix}files f", - 'ORDER BY' => 'f.id DESC', - 'LIMIT' => '100' - ); - - $result = $SQL->build($query); - - - while ($file = $SQL->fetch($result)) { - $file_info = array('::ID::' => $file['id'], '::NAME::' => $file['name'], '::DIR::' => $file['folder'], '::FNAME::' => $file['real_filename']); - - echo '' . "\n"; - echo " " . '' . kleeja_get_link(is_image($file['type']) ? 'image' : 'file', $file_info) . '' . "\n"; - if (is_image($file['type'])) { - - echo " " . '' . kleeja_get_link('thumb', $file_info) . '' . (trim($file['real_filename']) !== '' ? xml_entities(htmlspecialchars($file['real_filename'])) : xml_entities(htmlspecialchars($file['name']))) . '' . "\n"; - } - echo " " . '' . date('c', $file['time']) . '' . "\n"; - echo '' . "\n"; - } - echo ''; - - $SQL->free($result); - - #at end, close sql connections & etc - $SQL->close(); - - // #tell kleeja that we have a request from go=sitemap - // $no_request = false; - exit; - } - }, - - //output in header - 'Saaheader_links_func' => function ($args) { - global $config; - $extra = $args['extra'] . "\n" . - ''; - return compact('extra'); - }, - - //ping after uploading files? - 'kljuploader_process_after_loop' => function ($args) { - if (isset($args['check'])) { - send_a_ping(); - } - } -); - - -/** - * special functions - */ - -if (!function_exists('xml_entities')) { - function xml_entities($string) - { - return strtr( - $string, - array( - "<" => "<", - ">" => ">", - '"' => """, - "'" => "'", - "&" => "&", - ) - ); - } -} - -if (!function_exists('is_image')) { - function is_image($pre_ext) - { - return in_array(strtolower(trim($pre_ext)), array('gif', 'jpg', 'jpeg', 'bmp', 'png')) ? true : false; - } -} - -if (!function_exists('send_a_ping')) { - function send_a_ping() - { - global $config; - - //dev ? - // if(defined('DEV_STAGE')){ - // // return; - // } - - if (!$config['kj_sitemap_seo_sitemap_ping_enable']) { - return; - } - - //last time? 3 hours in between - if ((int)$config['kj_sitemap_seo_sitemap_ping_time'] > 0 && (int)time() - $config['kj_sitemap_seo_sitemap_ping_time'] < 3600 * 3) { - return; - } - - $services = array( - "http://www.bing.com/webmaster/ping.aspx?siteMap=", - "http://www.bing.com/ping?sitemap=", - "http://submissions.ask.com/ping?sitemap=", - "http://www.google.com/webmasters/sitemaps/ping?sitemap=", - "http://api.moreover.com/ping?sitemap=", - ); - - foreach ($services as $sv) { - $curl_handle = curl_init(); - curl_setopt($curl_handle, CURLOPT_URL, $sv . rtrim($config['siteurl'], '/') . '/go.php?go=sitemap'); - curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); - curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); - $buffer = curl_exec($curl_handle); - curl_close($curl_handle); - } - - update_config('kj_sitemap_seo_sitemap_ping_time', time()); - - //TODO add last time of ping to admin start page - } -} diff --git a/plugins/kj_x_sendfile/icon.png b/plugins/kj_x_sendfile/icon.png deleted file mode 100644 index 98fdedd7e9e1aa3c80190caf55a5aa8435e965db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10777 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 - - - - - Powered by Kleeja - - - -
-
-

403 - Access forbidden!

-
-
-
Powered by Kleeja -
- - - \ No newline at end of file diff --git a/plugins/kj_x_sendfile/init.php b/plugins/kj_x_sendfile/init.php deleted file mode 100644 index 3231418..0000000 --- a/plugins/kj_x_sendfile/init.php +++ /dev/null @@ -1,160 +0,0 @@ - array( - 'en' => 'Kleeja X SendFile', - 'ar' => 'كليجا إكس سيند فايل' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.0', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Enable x-sendfile or X-Accel-Redirect for both Apache or Nginx for better performance.', - 'ar' => 'كليجا إكس سيند فايل' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '3.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['kj_x_sendfile']['first_run']['en'] = " -Thanks for using our klj_x_sendfile plugin. -\n To report bugs reach us on: \nhttps://github.com/awssat/kleeja/issues -\n\n -You can find configurations on settings->kleeja x sendfile. - -\n\n -This plugin require that xsendfile is enabled on either Apache or Nginx:\n -- Apache: https://tn123.org/mod_xsendfile/ \n -- Nginx: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/ - -\n\n -Do NOT use this plugin if you are not certain of your server configuration. -"; -$kleeja_plugin['kj_x_sendfile']['first_run']['ar'] = " -شكراً لإستخدام إضافة كليجا إكس سيند فايل. للإبلاغ عن الأخطاء : \n -https://github.com/awssat/kleeja/issues -\n\n -You can find configurations on settings->kleeja x sendfile. - -\n\n -لاحظ أن هذه الإضافة تتطلب وجود sendfile مفعل على إما خادم انجين اكس او اباتشي:\n -- Apache: https://tn123.org/mod_xsendfile/ \n -- Nginx: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/ - -\n\n -لا تستخدم هذه الإضافة إذا كنت غير متأكد من إعدادات خادمك وتوفر المتطلبات. -"; - -# Plugin Installation function -$kleeja_plugin['kj_x_sendfile']['install'] = function($plg_id) -{ - //new options - $options = array( - 'kj_x_sendfile_enable' => - array( - 'value'=> '0', - 'html' => configField('kj_x_sendfile_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'kj_x_sendfile', - ), - 'kj_x_sendfile_type' => - array( - 'value'=> 'apache', - 'html' => configField('kj_x_sendfile_type', 'select', ['Apache' => 'apache', 'Nginx' => 'nginx']), - 'plg_id' => $plg_id, - 'type' => 'kj_x_sendfile', - ), - ); - - add_config_r($options); - - //new language variables - add_olang(array( - 'KJ_X_SENDFILE_ENABLE' => 'تفعيل هيدر x-Sendfile/X-Accel-Redirect', - 'KJ_X_SENDFILE_TYPE' => 'نوع الخادم', - 'CONFIG_KLJ_MENUS_KJ_X_SENDFILE' => 'كليجا إكس سيند فايل', - ), - 'ar', - $plg_id); - - add_olang(array( - 'KJ_X_SENDFILE_ENABLE' => 'Enable x-Sendfile/X-Accel-Redirect', - 'KJ_X_SENDFILE_TYPE' => 'Current Server for your hosting', - 'CONFIG_KLJ_MENUS_KJ_X_SENDFILE' => 'Kleeja X Sendfile', - ), - 'en', - $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['kj_x_sendfile']['update'] = function($old_version, $new_version) -{ - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['kj_x_sendfile']['uninstall'] = function($plg_id) -{ - //delete options - delete_config(array( - 'kj_x_sendfile_enable', - 'kj_x_sendfile_type' - )); - - //delete language variables - foreach (['ar', 'en'] as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - - -# Plugin functions -$kleeja_plugin['kj_x_sendfile']['functions'] = array( - - 'do_page_before_headers_set' => function($args){ - global $config; - - if($config['kj_x_sendfile_enable'] == 0) - return; - - if($config['kj_x_sendfile_type'] == 'apache') - header('X-Sendfile: ' . $args['path_file']); - else - header('X-Accel-Redirect: ' . ltrim($args['path_file'], '.')); - } -); diff --git a/plugins/klj_adfly/icon.png b/plugins/klj_adfly/icon.png deleted file mode 100644 index a2cb87d088a2307f42d22902d4149a88eb116c62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104071 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�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 - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
- - \ No newline at end of file diff --git a/plugins/klj_adfly/init.php b/plugins/klj_adfly/init.php deleted file mode 100644 index e78cea1..0000000 --- a/plugins/klj_adfly/init.php +++ /dev/null @@ -1,273 +0,0 @@ - array( - 'en' => 'adf.ly for Kleeja', - 'ar' => 'روابط adf.ly لكليجا' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.1', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Generate a links using adf.ly service', - 'ar' => 'دعم Adf.ly في كليجا وإنشاء روابط ربحية تلقائياً' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['klj_adfly']['first_run']['ar'] = " -شكراً لاستخدامك إضافة adf.ly ، قم بإعلامنا بالأخطاء عند ظهورها على:
-https://github.com/awssat/kleeja/issues -
-
-

لاحظ:

-تجد إعدادات الإضافة في : إعدادات المركز->خيارات adf.ly -
-
-------- -

معلومات قد تفيدك:

-- إضغط هنا للتسجيل في adf.ly
-"; - -$kleeja_plugin['klj_adfly']['first_run']['en'] = " -Thanks for using adf.ly plugin, to report bugs: -
-https://github.com/awssat/kleeja/issues -
-
-

Note:

-You can find the settings at: Settings -> adf.ly Settings -
-
-------- -

Extra Info:

-- Create your adf.ly now!
-"; - - -# Plugin Installation function -$kleeja_plugin['klj_adfly']['install'] = function ($plg_id) { - //new options - $options = array( - 'klj_adfly_enable' => - array( - 'value' => '0', - 'html' => configField('klj_adfly_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'klj_adfly' - ), - 'klj_adfly_images_enable' => - array( - 'value' => '0', - 'html' => configField('klj_adfly_images_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'klj_adfly' - ), - 'klj_adfly_user_id' => - array( - 'value' => '', - 'html' => configField('klj_adfly_user_id'), - 'plg_id' => $plg_id, - 'type' => 'klj_adfly' - ), - 'klj_adfly_api_code' => - array( - 'value' => '', - 'html' => configField('klj_adfly_api_code'), - 'plg_id' => $plg_id, - 'type' => 'klj_adfly' - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'KLJ_ADFLY_ENABLE' => 'تفعيل adf.ly', - 'KLJ_ADFLY_IMAGES_ENABLE' => 'تفعيل adf.ly للصور', - 'KLJ_ADFLY_API_CODE' => 'كود الربط API لـ adf.ly', - 'KLJ_ADFLY_USER_ID' => 'رقم المستخدم لـ adf.ly', - 'CONFIG_KLJ_MENUS_KLJ_ADFLY' => 'خيارات adf.ly', - ), - 'ar', - $plg_id); - - add_olang(array( - 'KLJ_ADFLY_ENABLE' => 'Enable adf.ly', - 'KLJ_ADFLY_IMAGES_ENABLE' => 'Enable adf.ly for images', - 'KLJ_ADFLY_API_CODE' => 'Your API code of adf.ly', - 'KLJ_ADFLY_USER_ID' => 'Your user ID of adf.ly', - 'CONFIG_KLJ_MENUS_KLJ_ADFLY' => 'adf.ly Settings', - ), - 'en', - $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['klj_adfly']['update'] = function ($old_version, $new_version) { - - $plg_id = Plugins::getInstance()->installed_plugin_info('klj_adfly'); - - if(version_compare($old_version, '1.1', '<')){ - $options = array( - 'klj_adfly_images_enable' => - array( - 'value' => '0', - 'html' => configField('klj_adfly_images_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'klj_adfly' - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'KLJ_ADFLY_IMAGES_ENABLE' => 'تفعيل adf.ly للصور', - ), - 'ar', - $plg_id); - - add_olang(array( - 'KLJ_ADFLY_IMAGES_ENABLE' => 'Enable adf.ly for images', - ), - 'en', - $plg_id); - } -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['klj_adfly']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'klj_adfly_enable', - 'klj_adfly_images_enable', - 'klj_adfly_api_code', - 'klj_adfly_user_id' - )); - - //delete language variables - foreach (array('ar', 'en') as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# Plugin functions -$kleeja_plugin['klj_adfly']['functions'] = array( - 'kleeja_get_link_func2' => function ($args) { - global $config; - - if (!$config['klj_adfly_enable']) { - return; - } - - - if(defined('IN_REAL_INDEX')) - { - $link = $args['return_link']; - $current_pid = $args['pid']; - - - if($current_pid !== 'file' && $current_pid !== 'image') { - return; - } - - - if($current_pid === 'image' && !$config['klj_adfly_images_enable']){ - return; - } - - - $return_link = generate_klj_adfly_link($link); - - return compact('return_link'); - - } - } -); - - -/** - * special functions - */ - -if (!function_exists('generate_klj_adfly_link')) { - function generate_klj_adfly_link($link) - { - global $config; - - - if (!$config['klj_adfly_enable']) { - return $link; - } - - - if (empty($config['klj_adfly_api_code'])) { - return $link; - } - - - if (empty($config['klj_adfly_user_id'])) { - return $link; - } - - - - //TODO make it option - $domain = 'adf.ly'; - $advert_type = 'int'; - - - $api = 'http://api.adf.ly/api.php?'; - - // api queries - $query = array( - 'key' => $config['klj_adfly_api_code'], - 'uid' => $config['klj_adfly_user_id'], - 'advert_type' => $advert_type, - 'domain' => $domain, - 'url' => $link - ); - - - $service_url = $api . http_build_query($query); - - - $received_data = fetch_remote_file($service_url); - - - if(empty($received_data)) - { - return $link; - } - - return $received_data; - } -} diff --git a/plugins/language_switch/icon.png b/plugins/language_switch/icon.png deleted file mode 100644 index 33e320687bf12ea3364ee8b55a6faf4e239a1188..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11670 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 z - - - - Powered by Kleeja - - -
-

403 - Access forbidden!

-
-
Powered by Kleeja -
- - \ No newline at end of file diff --git a/plugins/language_switch/init.php b/plugins/language_switch/init.php deleted file mode 100644 index 887a470..0000000 --- a/plugins/language_switch/init.php +++ /dev/null @@ -1,169 +0,0 @@ - array( - 'en' => 'Language Switch', - 'ar' => 'تغيير اللغة' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.1', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'A language switch box in the top of every page', - 'ar' => 'صندوق تغيير لغة في أعلى كل صفحة' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['language_switch']['first_run']['ar'] = " -شكراً لاستخدامك هذه الإضافة قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -"; - -$kleeja_plugin['language_switch']['first_run']['en'] = " -Thanks for using this plugin, to report bugs contact us: -
-info@kleeja.com -"; - - -# Plugin Installation function -$kleeja_plugin['language_switch']['install'] = function ($plg_id) -{ -// //new language variables -// add_olang(array( -// -// ), -// 'ar', -// $plg_id); -// -// add_olang(array( -// -// ), -// 'en', -// $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['language_switch']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['language_switch']['uninstall'] = function ($plg_id) { - //delete language variables -// foreach (array('ar', 'en') as $language) { -// delete_olang(null, $language, $plg_id); -// } -}; - - -# Plugin functions -$kleeja_plugin['language_switch']['functions'] = array( - - 'Saaheader_func' => function($args){ - - global $config; - - $header = $args['header']; - - - $available_languages = language_switch_get_languages(); - $available_languages_options = ''; - - $current_language = $config['language']; - - - foreach ($available_languages as $lang) { - $available_languages_options .= '' . $lang . ''; - } - - - $lang_switch_html = '
' . "\n" . - '
' . "\n" . - $available_languages_options . "\n" . - '
'. "\n" . - '
'; - - $header = preg_replace('/]*)>/i', "\n\n" . $lang_switch_html . "\n", $header, 1); - - return compact('header'); - }, - - - - 'boot_common' => function ($args){ - global $config, $usrcp; - - $current_language = $config['language']; - - $available_languages = language_switch_get_languages(); - - if(ig('lang')){ - $chosen_lang = g('lang'); - if(in_array($chosen_lang, $available_languages)){ - $usrcp->kleeja_set_cookie('sllang', $chosen_lang, time() + 3600*24*30); - $config['language'] = $chosen_lang; - } - }else { - if (($cookie_lang = $usrcp->kleeja_get_cookie('sllang')) !== false) { - if (in_array($cookie_lang, $available_languages)) { - $config['language'] = $cookie_lang; - } - } - } - - } -); - - - -if(!function_exists('language_switch_get_languages')){ - function language_switch_get_languages(){ - $available_languages = array(); - - if ($dh = @opendir(PATH . 'lang')) - { - while (($file = @readdir($dh)) !== false) - { - if(strpos($file, '.') === false && $file != '..' && $file != '.') - { - $available_languages[] = $file; - } - } - @closedir($dh); - } - - return $available_languages; - } -} \ No newline at end of file diff --git a/plugins/menu_toggle/admin_menus_toggle.html b/plugins/menu_toggle/admin_menus_toggle.html deleted file mode 100644 index a9fbe33..0000000 --- a/plugins/menu_toggle/admin_menus_toggle.html +++ /dev/null @@ -1,106 +0,0 @@ - - -
- ... - -
- - - - -
{olang.MENU_TOGGLE_EXP}
- -
- -

{olang.MENU_TOGGLE_TOP_MENU}

- -
    - -
  • -
    -
    {{title}}
    -
    -
    -

    - - -

    -
    -
  • -
    -
- - - -

{olang.MENU_TOGGLE_SIDE_MENU}

- -
    - -
  • -
    -
    {{title}}
    -
    -
    -

    - - -

    -
    -
  • -
    -
- - -

{olang.MENU_TOGGLE_ADMIN_MENU}

- -
{olang.MENU_TOGGLE_ADMIN_MENU_EXP}
- -
    - -
  • -
    -
    {{title}}
    -
    -
    -

    - - -

    -
    -
  • -
    -
-
-
\ No newline at end of file diff --git a/plugins/menu_toggle/icon.png b/plugins/menu_toggle/icon.png deleted file mode 100644 index 68816850ddd327a9c57254a267cafd3a7d83bdf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87897 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%0A%P9k(#&9Ga~?9K%&1Zdg&^-4+^Wq{mHb6R0bAl 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 z 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

uM9u6rQSh=VFVSBgIP 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 A0RR91 diff --git a/plugins/menu_toggle/index.html b/plugins/menu_toggle/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/menu_toggle/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
-

-
-
- - \ No newline at end of file diff --git a/plugins/menu_toggle/init.php b/plugins/menu_toggle/init.php deleted file mode 100644 index 61e6b37..0000000 --- a/plugins/menu_toggle/init.php +++ /dev/null @@ -1,223 +0,0 @@ - array( - 'en' => 'Menu Toggle', - 'ar' => 'عرض/إخفاء القوائم' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.1', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Ability to hide/show Kleeja Menu items', - 'ar' => 'القدرة على عرض/إخفاء عناصر قائمة كليجا' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['menu_toggle']['first_run']['ar'] = " -شكراً لاستخدامك هذه الإضافة قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
-info@kleeja.com -"; - -$kleeja_plugin['menu_toggle']['first_run']['en'] = " -Thanks for using this plugin, to report bugs contact us: -
-info@kleeja.com -"; - - -# Plugin Installation function -$kleeja_plugin['menu_toggle']['install'] = function ($plg_id) -{ - add_config_r(array( - // 'menu_toggle_hide_all' => - // array( - // 'value' => '0', - // 'plg_id' => $plg_id, - // 'type' => 'menu_toggle' - // ), - 'menu_toggle_hidden_topmenu_items' => - array( - 'value' => '', - 'plg_id' => $plg_id, - 'type' => 'menu_toggle' - ), - 'menu_toggle_hidden_sidemenu_items' => - array( - 'value' => '', - 'plg_id' => $plg_id, - 'type' => 'menu_toggle' - ), - 'menu_toggle_hidden_adminmenu_items' => - array( - 'value' => '', - 'plg_id' => $plg_id, - 'type' => 'menu_toggle' - ), - )); - - - //new language variables - add_olang(array( - 'R_MENUS_TOGGLE' => 'تحكم بقوائم كليجا', - 'MENU_TOGGLE_EXP' => 'يمكنك التحكم بالعناصر التي تريد عرضها أو إخفائها من قوائم كليجا.', - 'MENU_TOGGLE_TOP_MENU' => 'القائمة العلوية', - 'MENU_TOGGLE_SIDE_MENU' => 'القائمة الجانبية', - 'MENU_TOGGLE_ADMIN_MENU' => 'قائمة لوحة التحكم', - 'MENU_TOGGLE_ADMIN_MENU_EXP' => 'يجب أن تكون عضو في مجموعة المسؤولين، وتملك صلاحية مؤسس لتستطيع التحكم بقائمة لوحة التحكم.', - 'MENU_TOGGLE_HIDE' => 'إخفاء', - 'MENU_TOGGLE_SHOW' => 'عرض', - - ), - 'ar', - $plg_id); - - add_olang(array( - 'R_MENUS_TOGGLE' => 'Menus Toggle', - 'MENU_TOGGLE_EXP' => 'You can control which items you want to hide/show of Kleeja menus.', - 'MENU_TOGGLE_TOP_MENU' => 'Top Menu', - 'MENU_TOGGLE_SIDE_MENU' => 'Side Menu', - 'MENU_TOGGLE_ADMIN_MENU' => 'Admin Panel Menu', - 'MENU_TOGGLE_ADMIN_MENU_EXP' => 'You have to be a member in Administrators group and have the founder permissions to be able to control Admin panel menu items.', - 'MENU_TOGGLE_HIDE' => 'hide', - 'MENU_TOGGLE_SHOW' => 'show', - ), - 'en', - $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['menu_toggle']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['menu_toggle']['uninstall'] = function ($plg_id) { - //delete language variables - delete_olang(null, null, $plg_id); - - //delete options - delete_config(array( - 'menu_toggle_hidden_topmenu_items', - 'menu_toggle_hidden_sidemenu_items', - 'menu_toggle_hidden_adminmenu_items' - )); -}; - - -# Plugin functions -$kleeja_plugin['menu_toggle']['functions'] = array( - //add to admin menu - 'require_admin_page_end_a_configs' => function($args) { - global $olang; - $go_menu = $args['go_menu']; - $last_item = $go_menu['all']; - unset($go_menu['all']); - $go_menu['menus_toggle'] = array( - 'name' => $olang['R_MENUS_TOGGLE'], - 'link' => './?cp=menus_toggle', - 'goto' => 'menus_toggle', - 'current' => g('cp') == 'menus_toggle' - ); - - $go_menu['all'] = $last_item; - - return compact('go_menu'); - }, - - 'begin_admin_page' => function ($args) { - global $config; - $adm_extensions = $args['adm_extensions']; - $adm_extensions[] = 'menus_toggle'; - - $hidden_admin_menu_items = explode(':', $config['menu_toggle_hidden_adminmenu_items'] . ':menus_toggle'); - $hidden_admin_menu_items = array_filter($hidden_admin_menu_items); - - $ext_expt = array_merge($args['ext_expt'], $hidden_admin_menu_items); - - return compact('adm_extensions', 'ext_expt'); - }, - - 'endforeach_ext_admin_page' => function($args) { - if(g('cp') == 'menus_toggle') - { - $adm_extensions_menu = $args['adm_extensions_menu']; - $adm_extensions_menu[1]['current'] = true; - return compact('adm_extensions_menu'); - } - }, - - //add as admin page to reach when click on admin menu item we added. - 'not_exists_menus_toggle' => function () { - $include_alternative = dirname(__FILE__) . '/menus_toggle.php'; - - return compact('include_alternative'); - }, - - 'Saaheader_links_func' => function($args){ - - global $config; - - $return = []; - - foreach(array('top', 'side') as $menu) - { - if(trim($config['menu_toggle_hidden_'.$menu.'menu_items']) != '') - { - $current_menu = $args[$menu.'_menu']; - - $hidden_items = explode(':', $config['menu_toggle_hidden_'.$menu.'menu_items']); - $hidden_items = array_filter($hidden_items); - $new_menu = array(); - foreach($current_menu as $order => $item) - { - if(! in_array($item['name'], $hidden_items)) - { - $new_menu[$order] = $item; - } - } - - $return[$menu . '_menu'] = $new_menu; - } - } - - - - if(sizeof($return)) - { - return $return; - } - }, -); - diff --git a/plugins/menu_toggle/menus_toggle.php b/plugins/menu_toggle/menus_toggle.php deleted file mode 100644 index a96ebd0..0000000 --- a/plugins/menu_toggle/menus_toggle.php +++ /dev/null @@ -1,114 +0,0 @@ - 'profile', 'title' => $lang['PROFILE'], 'hidden' => (int) in_array('profile', $hidden_side_menu_items)), - array('name' => 'fileuser', 'title' => $lang['YOUR_FILEUSER'], 'hidden' => (int) in_array('fileuser', $hidden_side_menu_items)), - array('name' => 'logout', 'title' => $lang['LOGOUT'], 'hidden' => (int) in_array('logout', $hidden_side_menu_items)), - array('name' => 'login', 'title' => $lang['LOGIN'], 'hidden' => (int) in_array('login', $hidden_side_menu_items)), - array('name' => 'register', 'title' => $lang['REGISTER'], 'hidden' => (int) in_array('register', $hidden_side_menu_items)), -); - -$hidden_top_menu_items = explode(':', $config['menu_toggle_hidden_topmenu_items']); - -$top_menu_items = array( - array('name' => 'index', 'title' => $lang['INDEX'], 'hidden' => (int) in_array('index', $hidden_top_menu_items)), - array('name' => 'rules', 'title' => $lang['RULES'], 'hidden' => (int) in_array('rules', $hidden_top_menu_items)), - array('name' => 'guide', 'title' => $lang['GUIDE'], 'hidden' => (int) in_array('guide', $hidden_top_menu_items)), - array('name' => 'stats', 'title' => $lang['STATS'], 'hidden' => (int) in_array('stats', $hidden_top_menu_items)), - array('name' => 'report', 'title' => $lang['REPORT'], 'hidden' => (int) in_array('report', $hidden_top_menu_items)), - array('name' => 'call', 'title' => $lang['CALL'], 'hidden' => (int) in_array('call', $hidden_top_menu_items)), -); - -$hidden_admin_menu_items = explode(':', $config['menu_toggle_hidden_adminmenu_items']); - -$admin_menu_items = array(); -foreach($adm_extensions as $item) -{ - $m = isset($item[1]) && $item[1] == '_' ? substr($item, 2) : $item; - - if(in_array($m, array('start', 'lgoutcp', 'exts', 'configs'))) - { - continue; - } - - $admin_menu_items[] = array( - 'name' => $item, - 'title' => !empty($lang['R_' . strtoupper($m)]) ? $lang['R_' . strtoupper($m)] : (!empty($olang['R_' . strtoupper($m)]) ? $olang['R_' . strtoupper($m)] : strtoupper($m)), - 'hidden' => (int) in_array($item, $hidden_admin_menu_items) - ); -} - -$go_menu = array( - 'menus_toggle' => array('name' => $olang['R_MENUS_TOGGLE'], 'link' => './?cp=menus_toggle', 'goto' => 'menus_toggle', 'current' => g('cp') == 'menus_toggle') -); - -if(ig('toggle')) -{ - if (! kleeja_check_form_key_get('adm_menus_toggle', 3600)) - { - header('HTTP/1.1 405 Method Not Allowed'); - $adminAjaxContent = $lang['INVALID_FORM_KEY']; - } - else - { - $name = g('name'); - $menu = g('menu'); - $hide = g('toggle', 'int') == 1; - - if($menu == 'admin' && ! $is_founder_admin) - { - header('HTTP/1.1 405 Method Not Allowed'); - $adminAjaxContent = $lang['HV_NOT_PRVLG_ACCESS']; - } - else - { - toggleMenuItem($name, $menu, $hide); - - $adminAjaxContent = $lang['CONFIGS_UPDATED']; - } - } -} - - -function toggleMenuItem($name, $menu, $hide) -{ - global $config; - - $items = explode(':', $config['menu_toggle_hidden_'.$menu.'menu_items']); - $items = array_filter($items); - - if(in_array($name, $items) && ! $hide) - { - $new_items = array_diff($items, [$name]); - } - else if($hide) - { - $new_items = $items; - $new_items[] = $name; - } - - if($new_items != $items) - { - update_config('menu_toggle_hidden_' . $menu . 'menu_items', implode(':', $new_items)); - } -} \ No newline at end of file diff --git a/plugins/pdf_viewer/icon.png b/plugins/pdf_viewer/icon.png deleted file mode 100644 index c1ff7553784bf20a492f6635b8dbe4bb6a04004a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94217 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
    QQQim_p@`;*8s@GTe164 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

    jP=!F)}buuALfaZSCOpHz$PcnH{aD;yc zym$Lew?6Ul-+l3=7xs2{VU4C-95f61t|^PUo){G?!i!}ADHwe&XaIzg+Fsi;X=tu3 z88m7;1nSiQtQyh6 z?*pvl%vABN=+guO3zPm@*{;?-J2BJ=R=To9v(;=f0{QXTB*&#jhS+OW$*3~QqUgJ1 z)6hRF%Vg++IUkh9jX|GW#=bnNOW$n}7~B-Ap!#;sfvR|%2s!{ur$ubnz01RBY-yky zGeTF~nj%fCQwwy|Wl%UCO)tEB{&zn5J4cW1v1PeGFs=e8Oby7T=`N&52M#YCeF<0B zHeTC=f{0G);b|_nIs?1mEX+e}`tn2-(M$o?$RHRm<91UVCV>mR9cuHUz8dN#;<%pH zVRO1UR5}P&cS%qraZaA8vIBk(iQh*%edcrplDLe9WGltI!;DUPPUWWStP9+1%*5I8 zU`KaPa{HYWQVD7|`-W{atO8?B%QO`Nc5d(iF;>`(G%5=WTOZKa$XI-uNYTdB7%j9d zH_BV8S-3%%7ppG>)$~69Y{%eSaCa@v38w0qB_h7x#uC7KYBjm}W}u==(IleY(vvsw zn~q%2@pI=1njPI7t0Pa@bQp*Y=tGBCR44^9R>Xq}`;ManWvGG(H6nxYC`L}^$U`e_ zJ;Xw7mNFiB!`NKu6L*~u+ml}b4KvidAF;YlpE-N`P0#SN#JhKh%TMrhsReeuwi}oJ zw(kl+NC_QEu^b&;f|P61HexxIg?uP0E=IKrYFyi!)G#pSIMjQ!AbCygW0t11@!ErK z6V@;%0|dNE6={otYbK%0Y;K=JS>lQz zpuT>^xPL?)9k`WkFDNxBNS8B)ExIBr6g6s_O2rtoS0WN{=q7rd1 ziC$+4X9u$F=2YCYdms^5F5DgpJM+49d?8C5H z5P+V_!t~O(JbLyk8l1=4`$*`Zg*_MDs_NxXtog<>N{*%?O!BsFf9#Yr{S?adX2JbGd*;R0jRBv>KPP{CWDiPRY|1B=wIKX)qnDFT!L1C~t_& zC>PyxW)%26DHe?6HEf)-aD@^jPRyKri8gFgw1J%Ut*)-BkTo;SVPRWCW&}6IFrgGB z{)~NXATx~nNSG-H%VfUs;+Nhu^1=tI*7IB1UtPp6{Ur_slVQc5t#LZxMSeQ^C}! zN5duLL}V$5!wl^E4)BpjALWH9v3dWaw$<0a6x>yve%pGpJ)ShtO;bD^wJ>fShyc!1 zXED-494C=9wr_JiVL|~-wwno7RlN$AuHa)S|GB|+w@4vXZc${Ivpn?XokyHJO}4O& zo58qwr&dry5f&=yp_>X6Wb2C&AJ9P9vokK#(}^7MW)BthduYJKH27x&i-)U8i-Nm^ zM3*(;>VhLcMzo=8B`Alb8A~=Ga#5pES(i}+w3Lb1XP<^({#5A}F0Yog@^OrAj%Prg z(aT{O46)cs2?~T8p>!fC0ltP8jY@`(TaWTd!^MjiKKhZ5-MM>bZ;zj7F*xpAOneXk zxAs46VZH*C(>PI_fhV}39}O-J3|B)@eRk4`dZnT)`NXd$;}I_sH1s0x<)AcbEfWpR z&E(c3B=E{8lkJjKHqY|@Q3r8NYsPjFyyigL)y5C@`1$IsW5-W8?qBdRl1?J?z37c+ zdII;&vxg5fJ>)0RnpGN3`zT~Sq>(XM_>WW~gEcXmPAUDrBP&<<`9{_;-YK5XU z*f}tlh<%Whn;xmFid+e8-3>c|$Bh*Y;23ZvS+tW*fI6#qX1$E7Y}|zy1A0&2#9*d% zocAuJqHxf~yTV+nh!tiy;JbjDzTqX${@V@XU=%G1MsQ)Y88_x_^%1Plr9YUFf#uq^ zec z{QsVgP;IwvKmF3nFMaG|A7`iB-7^r>F>=v>6yEqpxJ9IbaB6Z|IR)Ei1MzdHlIx3{ zvZB-5P9ctbw2gR$3uF;%jK`_h4DyQ9j2qZ0ZcOEzelw)Ix&5J4vYZPzF~wdasSDY= zV(A_5cz*TT)pO_g2?TG+G^(<+3EA6;|BBUubK&@BbzCSw#YEr&5)Ej;TM9U`sZVn0 zA0VYa=tMl#GDVES)Dckrgiv~VH>m{}O2(BOV}POLmT6cHMI3z=LL?(sTg_nDF0By@ zakOP?_6H`Nswlt~;y@d!Vd`(-jZ$)+ps`0Fb>U}WTir+?lbW|a<7p7F4I(D9`fpIb ziq|q$>Q>q{UnCJ7jRzeb%E8k0nym$4A9ABG#1u@GPIdqm!LNDyiz(sdK*W}*Bt~9! z(F??>w-hC(fZ14)C^N^-g0==BCSL%FpH<6(K|2TM&OP+zH=lj!#TS0}lfO%dz4KL1 z#?5ZlYK9~b_stnm2C7cf*P)HMs?N*x3>5BlR|`6mdy`5EN|nk}ahTiC0F#pLl!9R# z$_;N|QP>cGR>d6AWT4x=4tXguBB;vQQ4YNG%YBzFUA}PP+zwm$5r4r5Q}I1K`&~rd z>~#w^>u~bVx(pMUde%0^axf~1FlGL^z9~vZ#xlY`q5afE~h`H8&KuBC~SOPJ$l#B9t8ON+^6F&8-!2F!~9Rm21xSy?29 zLCFTfyW-J@9(tI+l=<>YFMi^apJaspZB?IW!3^G1g%e+zn*(7Av4F~zEsv5lVzZGR z;fVt;AZ50N0?72TETDp=J7@u}Hk0c=c&Tg!Svo?BB2d%3$)Pgd)kVjhqcZB&2hYow zFY{Mi+qTMvdS%k^w9w8B1fy$e$?aQNPwX0?Q*h}U59?u$%2RPg0Z-}^EQ#Q>5Ev!R zq@i@Ph?T39dq!uwlNl5T*2L=qss;`qYU}oiFN<4F;`+=$dr+0Re+ZObL?YYFNY^|1~OC9rQ0~ey;!KV-(cV~S~5HeB?Xu0Kq z4cuk1e7f;CaVzF7hBah_l>rWD3c+`2?Gf3Qwwmvpf9S&b^AElB%8Q@)_$T>{g2n9H zoT)fApq8ds`MV)?W zYhN%!DyXANdzlMCM;4CGAq0C@bgx{wa^~FmDy4bH$~1=56_<1{DP^GajPE*>v01@W z4h88@-&$?b7aMm*<9E6gb(a`usg^94f{uMPQR>YYxFtwO<_H}RBW**FA@jooR!Rnu zO2nE7oK(Y#UE5xLw~@1mh*r`?Rejt*n|WF_iKRF^s`m_SV#jf0WN~C?&#Dxn1h7{5 z#4kvK5~jKDb6TGj5PDI+RZ?)$a>STyi6tQeL=!ZhHIS7tA3HQdqv=?y#*IfE#@rw* z;lW8Ll}RQZbj7zP5Rtp2W>3)@9YI7d6}}ZQSJ{X;-I*gp1=z8I$ZQBBcSKVy^s0_g z&HdRqW)N?nvix_C9^p5?pZSXOufF^WOOYRC@R0+5mC;fg9~z7s|G+u_bP+khF}KDY6V~P;7)r|elm&-Mn9M{WS>@@F9Z;Rfd%p48 z-QBx(_41iBXD9)}WqRBW+=$9QpmG~PJ7#abn0<;%ihB0{lL56aMa45Aef|V6PGK+) z`!dWFH4in7zJyk)2w^V2QZYKZ)RY->Ua?>$Et^@jhHG>_d-i+~2m-%k=K5%krbY?d z;>fwQbH-_slPf)@p(D^SZx(^WPE+kP;N-Svn6g_dF+!$u;+stgEgxyhFDa)|pLz4` z-~Ynh7hZh+GoSvn`vZ@ySOjjdS(hs|Syq@j=g>8$l9-#JG}Kzq!wD=&U|}H2re|9r z0az<_O`dUh^-L-X8#iY|&s7)JPx zhb$;iSi2rpj!O{6mY*~rO=rrrPz)$Ih9)x59m&Wj!T0_mg@_uw8t6OSDiU^N3MhF0 zy)LWhFen=Qh{AC!yl)8Hu9f#GSF-XXL?abNu+RM<0Le(Z?SB!skB!-1E;r|J-wYj_`-EBFD zqL*1 zTK2FSc&&{xa^Y*%H`XXi-h6pKKrRgdgtpOLBANK3kK9M-9H@jZTq|`}Oa)hVIhKlt z4D`ui^gXx$#lJc_x^wc>sVk>WKk@jbS3m#iv%mN3=fCg;V&MIToCp1MU=1QMqH47q>ZdFRxnBe`eD|_s)HQ!wc20R1uoBJDo@QS|#`NZW*r%#>c zj||`xsF_M1Ks7}qHUmBqM@L|UdFG}j8E=gRt&t+(G)-lZM@FNOQ%P9JBioBiVj?H~+Y8R>SjFojz3^2L` zHO}cy5ul1U|D8n_NXzM!3U)g9A9+BQmSH`sQ?~7=ao7QN4X`2IfY% z(`poVTx95(ue;eInG=`(z57?ca_}Gj@jw6bfBxrRfBEaTe*J)I&z!|K^Hs0Cb%Au< zN*P4WlA*aOuo$L@fny7JlR_&_ZR;ixX?y!2UAzjg=w5qLUhT1vU_jq*q zxr~*OnRB^VK_r=Z(JDR|V~8mrf%RT4gzX0Lofks7Gl(M)0$Zi0w}yV}udDp)x4-?{ zzy16F`ak|x3$h#I|NejfcfSYMkKM$vH}o$A#>;VXIDj99eiuCBbP0S?82U#iWSgz?$eG6QM7SBuOp6=jU(V{_Ssn z``f?&dv6{46y&$>{U^2m`1^nTvz7V({NMlA_cWR0L`kfarKU%(5LQM@iJOEd(>Z23 z^xVpF)XlEnbN$zU=^681^YzznfBm_CE7@`%?*Z8Htx5dV4Bzl@&=uxXcp6qoQyZpsN(WA|6r+;_N_I3 zX`)k(gzrr_+@#NgI;S7~E@jShB!k4N6PS&6MZv6zGO|)+mju*ikY&ngZJ9!12K%<`W;o z$xc4tCAHyA!Mtq>m$T)Er!4;446%n*O1j(-T(8ano1pU&$pIubqoh=<(cz01OueKp z+~Ha^Ks^^5_eQzgWo~jz#zizoyx87)`7Hp;_k~u-BRd#e(NGth=299=PeL5NwKD$N zFU0-J-~M(0|7S{H{lB%p{`&o&U;72=mQxGsd#A7O{d>LNzW3X!U;pgKAiwkmuGh~! zSGL^xsfb?x+3mM){fB@5QhU?Q-J+F;cste_VN0BKXBFk52;CXX$_zyz zg|ojDQ#+JFb=s7~s8(#M`HgQCj3*9~P~owS(D3S$?nkEC%p*m0>8>$@z58vkSV_@1 z`&-uwjFnokk~(h==Km&sScg1-q1#J2_HCg|0P5+AOFaK8i zc~~?dwa2&Ut0;C}SY>rEbCgU3NrXkKW>?;mZ=P$cJA+``BpQ6E38$ZZQX{+1OM!m4 z^Q=AJREQvMSgsbgw8{SbTXa<2C{sV}T%g7nw~{bkZ;+<62->bV-48h&M=`fK7+K{| z(~i4{lh;xZ^MdC%ytDY!<+4{*ZJNL?E-`=}-{Pu)lMsu{&9!F_6?c6{0;Ra&qh($=N z7?XQtcKLb*csw^x6`i4BtH>=s4-+r5yuD0tS~$zua()ZpB`=JC5O83q&bKnI zX-Go;r}E&(=j{bT>Sdn@HbZy*;oppAvgCA`zkF)5wTGLc(~a)bcBgSNrs-9V~8$aaWVnxtCcOT5@e1xRFz(0L4zBIg`{5 zg)wU9m4j)G6;OKSb53>v<@O6l>W|7)#+Y z|DJIDz#;5U=W<6nSy$oi%(eu-$MTu-o%UAbl8S~5DFnnZ8rq=<*6`v?VSbjsi?Z<# zzZh8@R%|9$q>af(2d7M24Yn)ulxk#O^bacWw2YV706$anII-lnV zF&3DOQh*-F21jiUsV^NE<*kF?jZW!J_x8Zq5_}>A`BEV4s-#Sq^P%u6(nUF=5N8|w zoW7aZtn@j;ri53PyM`pCdt9q!X&CLYPoVOb1|{{`Seq6GtPBxnFdLqew#D5fow`ki z&Z&dfiq~=xp_edD1{T7fM1jo1*&XvFzK#J-2X3+uN-|g`_~1DW)(Xk)laJ0vOzIh@ z-O2fp85nfH)6b%Y#foI|MwbwsdaXcX3t2$&)_rGn0yO2BC3#U|=P)%eOmP~b~WBn;D>IUzvNLN?ca%(-ak0$vs-q>-RB-gE_lxfw3(5S*XHTEyhfOFx?U_I3 z#W${<=4=%JEErEKd>Kg1O=vffoMkVhJ*AYl=Ms&y7=ar}?WGQebjSis9(0y;EU*{Y zrY9>PCU67P_DaUG;H*P9GD{WS(jQjWY@yA5{&*F;5P4~=saQlX%q1DE;O=M2 zj`nTuhdj@CENRP!RPsu*6H_$gppV_=Vu0jwm2VR%|{{vk=yVndyvp?TNZ>e@YGVpLZS0<(Vjc>J}6oGtL;al3(kb+zPg^c`s(cIx>|s*fG;QrCAQ+eH@1WypBaJQHSwLg<}a4@MoqaF_7lr^~q{XU$^a zoj-X3CLIeIxapWRS2I{RpUnu?oC;0N!wZ1vQXb}61;R~TG1D1G1d`c&2(rYWSxuwp z7sUAh*^8dMq}c!DsC#kG+xjaUu3(AQLqhJ-#&73qHcZ&5!e-0&%D@y{mUuPVIF-3+ zEDoEhdD!U4$Q4JIiusi4b0R)tXdvb^#kzZ2ft&j)aDyFP>(4V;o_aZqoHtjhGVXP~ z?2{ym`)hi<(;9noxG+Pe^&n&R@+ zkII(Kvs-#HBFu7 zXn3&Hc>c*}nkLmrHMiH6h=JU|NZjt1O`3*BGIz2S^_2kNxy)OjD>$P$I+r=;DC=v~ z8kI?!CC_f~1~TT|jT=1nf@6@kvc|ErW1|bvF7T#hRu`EBPFd8ZK+y~{DLMpE+6|fm zX+rFxn}p|7deO3+14wi*ML*AXM*lojchekMsZ*MC<*P@GV(`KB$PY2RdM3T7_K<}K zHpw?%f>{9#<6{_C&-e`%*CB)>Qk{`Oj)^Y0l@6&ffifAwe#4DKR?7vC03+zt zq;t;)TI!;2a?;W_4@Y@+rl@cC2Ve}C&RMX$ihZAxaWQa6J7hPH=hFPQ&@9f(Y$I+@ zvseah<^~b+cAyd(61Q_hf3YQ*2kv_r?%3OB&b~Q4a$-MUF!)qPFSeK`Selj;L^l>@ zRBO+3*V>x+puG@oaZJmk9|Em{&Qsw^T1Rdm@7@I!H`@l&4GXHR`|`G=N?Y?sMam@T zY0rdCD{y3rsBgn=d0j>nA3p1epK&Bn4)b6erjw>v@mT`{vy7xb=AQXVH1vd_X8h88$ynCpm&xtjLLB#y zav|XULi_tQ=cQzmd^0_UX{7c7*Y0b0moGlK7fyc4gM2Qxq{$ZRo9$F@$|P^WQvM`! z+HVHo8L(6e^TRfHQ$D8&ML>m z1e--*a8%k$GfN=*LTEYJ+0OEDBMkGF!j$PPCwHOO2Q#ooh~qh9h29t~Pyqtr;%F-- z2JJjG-w+_jh}GuxAQ{uc;9deMOLP8oW^gIVOf{w)#!{{M!VD(gmkgr;+n{nrJ6A0_ zd}pZt8HP0tx+UgTC|a|ebR(Gr+jdAb zoo2N4Id%JJvO92?-o?J2(|xA8r~eHr)~A_?eLV3z))+$h4%cR7=yc3$xLy26=>Qo zC8`EBR4B0oe^_8Ej6n*MT6L7vyw%}pWzGIV6mCSe-cE9q@NX68Vuo40z5K`Iet4jH z{KR(-RwbizZb!mfi;+NR)E2<~p(jK$P+xsFE(|dq_upeQTsj!oPko&eHfGx3f*I9?K#^ol1Jf|3_$RUtisf=TaV@KN>Unc4+v@iPNH)LupwU z7u;Y{Y*$Qx;@NoHHz4OrO;)+$S^uSO-3mGfD|WiiV39Hp`k`)=Ml1sB2X{Dq5Lwz} zq7gnLPMYwEC4DX_c#dpdexxaIg$<__<^m4eb3@VX~_Yg!U zeC_}Py14e{UcxwmoISHu4GLQt=la>Cz%~3wB((!hER||KCsEqSTQgjnbjtVKusyqy zn!gch$XAxgPFG6dFt_L^I4ZDKypR%daeMXjWJwrV^)y90W)+$&)7%EUG%O!#^)|5@ z(YYNp)4Oe?nAM^QVhEpESlF4jXPBgO$!&-El_Sm2qYX@>i?7~^#SleuD zFpD)6#|_h?&O>mtsPF6GR#(jKrAqEODhnh($weH9XSD&EzbPCaAyY00j%0jsEH3Q( zkPr2dSU97?u|$pX(iV8B!RMG?>>#-_gQ1k<_X~(=y{MIv*$G8xo8)V7z8$^W5*tX#Ha8C_qH$r0b5PPbv&?~V%gXZB7c(IMHrNabh6s}#%nnkYY>TlWMj`4 zM8#pFx+#e+)}l{yZ1Tdt%*{F{{VR$Q3~w1575P$Dsa{y!;Alw)I8HReE5kqTsI~1JnFC)L?Y?4-% zRA_IeYOQjw60EY*VLCW*4{0?J>3Rq)Cew3~jnLeWR%OI~%tB6d@kZOl!5`B3wb4y#{!;qNf^wOjb#Su3gzSF4TkjvE)VOFx3X~Z8)5se<@AEHU(9Q5JgZ1m7H z2i}Er6XPdkmpi#;*23u2Amdyg!Z}XYwrbU4*`SBasWk8zCGwQnIXA@J_zDJ?Y)qh9 z8k|;sFiQ>cq}V-T`I+(0e&3C=)W7)`Z=27$qY1i3-MteN2zExAlazWj-9xtnx$^qH0cpKL`G?p)Ce{Ls?BBhXjXjn3H> z|M)(YE;ANT-dji#>o~VZv3zb#spi8(HB%-$Q(um_DFPF4(*jt|7us;80r8U8kdIJy zOvlMoIOoEo!Je}q@-M--E?14oKx$Xy)69Q^!)SrO1sZTD7E0_oi4*o^xfu9ZAc;qo zmKZXG)tQy(I-hPK{L;LhGnZ-aR+%(b_NC8gq$ynJn~wQx+;yW|iPsdU)Xu{U2GC|a z0&a!%Hd|?|)EmqMGnS;ySnuktrk9U7F@xnkkNM`ThN+i=9T?EBrQl;mjY8-|n$R7O5NHpr|WV49ob{|A-xh~ko0+@-# zA;04|UGb#A?eZ%@xJ_we*P26co{JFSTlBJ`vX-w%iVVhdq&E;hwTb|Pn=%<&tRH7O z3k2Gr6Qm8uDQ*%loe^Hp$tO-SLJiYd6(I1Dn)pT6W$EU&@1`L7s}u`|Ya1h&&tqnq z;x$xD8ecGPZ&6_o82-@28|s|6pn@SSq!C**PBGiZ{|HcaT4ZZaBmgE%jR|H-OT3Px zwI<$fAa$Dxu4|!w7R$ipwV`MpRHHCtZWWP_@UP?<=2(z1Ej=}84mjU3lVI{7ldoE9 z+Kfzmm^do!Iglu_ZHL1;Wfg%{|ZOr{q7Id6Ti=&>xGN zz4Y8}20c_WDGQbV80S*v2=j4{17@HGrj_rycVF3*>t-RVW11RUz?Y!VH*H0;4JQ)V<$r^8#!(DG9uSA}8NrV?8>X2Z$mOC3jh=Me!50!f7^bms3Ab{P z7`>Pw*p3^S?mqO55W~gQ%Sr#-h$79=;qFF%C`~K*GF<2Ew|-=2q?Zmm%zRk!jf=&S zM>j#SZ9EmRDwwQadMr4B({WmbER#i6f&%6}|X zazrOR9}DzY2($?jTEwWCG88f(b(L&!7suLZjytKs6b`-3O9*Ktoc4mKfBA!`mid7! z)}y-1I$7!*fMn$=8fteXWSE^q$>_ugtk-2(%V6_cR=Em8;p}Q6+Jxq1=6sCvw%iP0 z2+`8vl;JW=+&2nS1H!ennKYbvn@VFhLv#i(Lx7B0Fj=G|yg3*w-_t-fmIcVcYN(-A zhrS?nn=K}DVO_pP!2aDZ+LT9fjZsCkY|YLnqgQ{m33^3yNm_1jNGr8kF(2??t2tTm zWwl}4fm>k&VU)=0knP0*naqSs*zzzOtZ?fhH#fhS_eJpN@+iIp+m1Glmz8(wa(;eY zn)K+0zNnoJX*5w`HBowz9xSzDxZf=G@!z89%3vd+G6D0ny{*AwH7dAs0%r8Xo`g62 z3POJr|{mqvY^4rZ+(2=mN1&HhWdGQz=}Q6p#b>>62^pD6;gK}7przX*L3 zjFruQPLmbi{5F~;t!f1j?{4@t&9I7EXTfm9 z-5_WN=ouw)^|lS-6paO&tN|Q-@ZWd?=PY&Z#WMGhIIdfyqz#j>@`U4{sflHCEy1CB z4>r9rEO8Ae)+5LutiV#1Uw9yDS^)`N;gA@g%eu=lud63`g7n3Iqcb=^Ny7oTQQQ|? zm$V|-2A!~RT+*E1vVj55y+Th<3oCL4_4ZJW)j8PHJ5MW|MMJOkx}_fWWo(g*P9J%~ zIf!EhADx6FnBN@H-gi8F-Dbgp2b{5628AN?9!nX;jsxEU?ZRkYSKHe#rqW1A%og(i z6YFgrg4vo*p)GW%@bp4=`M2m?yu#?T~UkKiX)50r)Ei)Ha_uzL+xJ zbj3#Su=aj;eu2O?mcxy&0uiLVEhc#?CA=Dp(Q?#SHa7poxwHith0YC1Pbv%M*l>)t zD>CBiga`cwXYq13+n1}Ev1Th1nc82Hvt|xpqj`|&1R9ox9VQnWA33qf#YSg@ORsc0 zEVwe1fM0VaZrK!j$ClO#U}l;0)?#sN^pFN2{0|*b2HEuCv%IMBJ&*~9q{@T<04qXC zL_t(O*h;jkN#3HT!}>#&wxZ0xp#_A&j2gndb0Psl>T4~(@-nb9M1@fpQ)s~lm~Gk{ z8v+FrAQSh;8B90^CKk1bE$L61<8iZQf{YXJ@IFqfSdz-Dme5b#AJ4smYBQuh!no*Kc5jVzGZ7Ws%AK7;P5B1^crY8a+ZB2}Ftq zmUt1iaV?^Wxr>A>{5XxhJ?0{c*G2bPR5y+>yp{62$8zMv8pD=pb2R1)51nj2hn4ma z)hTjf8E6ROlPnx?%Qf@4jjQy{pgEdwWKt0RO(jobh*kpwO~jXXqR10Vy9dPrPG2Zg z5n$&=za|+fM`n355u-FJifvzH2f;D`olDLpuHOC(e$I#`Kj`SBooOZ0j#GXf13nti zjqugm#h3^uM!vD(OU?yzNmE5D+WU#}-J&USHdNrb&l<#v2F|eN7=QQ|^jQs^XJ!qK zzV_3!uP%4IjNvWJRu?6Zfocjt9nmYg(rj@und!(OmB2>>S-oeX%n2KlyfeWXs3FpN z#ohI#sXm44dNdq|3oREnwuch~bzdIj@^1Dq!FYC^rk1x?&I(2-`4CIrr#TyRjt48; zr0v#CzJTIP$gokfU5QvqWb{>j#)D;j3s@Y(9-r8bLU3Rij;X6shZPY}f(~X}_|W?t ztT{r_K=T3&&(Hk4zL48XPy^zg7)TPz^Dss9Ew>cqXr5$tgBQa5Gd?b=Y1J^0Qfr!h zjC{m57nvN*P+3MBhf(%O8o=ua=FMFqb+J4j5f#MUo=vr3ZFgCVp;vS2?DR%N!}qDkx|}S>PsikmRJ?|qgml21L#$0QOzN2t~E#DGrOtTEA1QmTiK&tj(M81nOJY~w2l z!I&Z3CwEmeVfI!|l4#Q`e>75f6HxiPl} z272B&GV41ah!twhRT`zb9Nol=|*xK|U+)PbYZ)G-8P@MyWtyI24|L0;BIdXw(hh61C`_ixA&!XdHp<~ftP&YXd=;5#7k3CBVF|} zYuvLm-!bO+2Ko0Ba5hD1k0+Aok!Q{Zv8<5mu=7zWUO^;Jt!yc$4(xj^68&<CGwi zcjirVMgpHmR+d6!0sH%cl7&J#oqU)ABslptAA<3#lRC!S^Go-fF82DIy2KpFB_sgu zg4oaxa;BL|J|ONbnJ)CM`#QA7#OgT%#W8Fo0ELsXNt51kL(=>UBu$L?XSSL?j>0+= zQ+qN>!kHg+B#7A##AgiWTHs3!ip$!C#I}&e>NZFgOHuqci8N9+wMtdySMz1N0Zc9k z!@M2~EkOAlhx6Gqc(@hs2wkPaT(X*{^XU;2anL=E7GEZJkgRv{P-(bhIUt->z3DF- zB{=FiCZsoFa;^XqZl|okGO_+Qze^B(^HU6mH%2sMEgUTMSV~dOT^hox-q2R6DN%Uf zcO#zxR>LiLc&x>%;>!*6t8H=8olgUE(7CTUobDh-(X5S~C?h<}>3}iv%!Yt0ENWMo zmvnJCY~Z_ zq}J4NSxT#Mm9BH?`9!Ps`Wg+0+qZEo-XFr^FV=;$8Y^83dPE}SP9bk_Hp6IrRIq9& zQhDz(9yCF2U>gsED^ysAvPo+OhFr%)@W54f!rF^Js-Q!_-;^1@u+|t~^KEE~rebOr z{?c?d(689(Zfgh}V))yBUWtx7Hw*rT(wHxd5)U!iYhala6sx1tAZDXAN3;kU7{n4o z7WvLljYe`HKb(kxMulgS)!oiP{NXugjZlPjX)r`I=hB za;D~w9W}LB-6#%ftZMzizw(wW1DnuvP+j`nq!bn#<~BSiqg69r!taVnmrc5`FE&7L zIlO$1!V#DXMgUczWJ7X5<}}X@EkG>N-pn@MC>6?S7&`NLSL<7S4=p7$2Ql!YkPh+} zZT3eAk&A!0Gqqq|Zvovd&Grssw{RqKQ$Ms(q_oDujMB%GsLviBVa`eIP04}szv)q- zl!)h!E2-JzD4@cTMkTteGHzg{w`;H@XR1wgjBfQNIE)uq?*^Es*p!UZT*Eh)iSo9` zhcTvk+fN!l9ux8bVK}=6d8E24Rg+AMhTTnoN|h5P^l8fLTsElYB7=@r=pTi-4X zG0XX9fZBE-dC9IZzIYN!nw?h>(JFAG_83=rup%f3TM+9ACa2stP6Z83}Hm19E{%D0_!9~9ut14Q7iN!RZ_YZi2Bxqg=a+YG> zn*>>k_GEEkn^)JsE`;5H7cz+aSSiH?*w`$A--im}!+^z4(_nopmSH7EFA|z`XeioKiOJ>994qWg#FhQWl?8k(G zmFMUwXLV5GWE67bsLKo4hu@M8Cx z6U%zOOpfWCO1o21nOj<|d@cuvS$UvLzw@iCOH7$cMXF~eH}xKb zbgmtzBOi|s-68V2dn?u_!P}%L6#$F80Js(_M)_Od%^_KX;ZV^7KoKOb3&yNpW9gMD zLyzD^Q3q-$JD`<4$fnplWRz>LXjvHqg6vW?u+BCY8$q4MX%&^AV5jJGF`pzZtIM1b zh#zQI5pXD0*OM9z8K;<3^XZOj`Q&G%vANPo%gHKQ$O0$c3%!R+=~A45s4cQ{IDaD% zpwYfZZi&9A=qK+IP?I;spe?pBV6*qX3bD}(xghLLR^)(%KL>0?U%f7hFo(}KsWoB+ z9+{Y$WdX+FW(z`{GuL?nq_1=8TW#`gr#rUR9y~Ee_rP;3=RNv+3dw(HeOC~Fi2u(Cqg2f4`( zG!3?S%lC50EXgrBx6@7OGl}&v3wesmzewmMT$nXJwVvf50aTqih=2$@jB!58dih7A zQn(qGh+uTiS5_j}w+Q6;+={}W5VVYJeFmG{nPX|61*U^BIxdj6cqrr(OrWi5P{F1a zSzTvsyEvVF2h7QziK@bu=2@oJ*rtM!ZYaG<7dCT3kdihuT9i(u*18NEl|=%&7c+$c zGzTL|E6LheIx<)}Ujh<(Z0vux*%+vWbR6d9FffIKsW@!Ti0D@TbPTV69Fg+bqD@)XAamOq}n;v>f$sRD}3kZY;e9vId~A883^|DgmWf z=y!n&4A7r+S%aBU8gvra4@}c>PsO^hPtu!8zG|PH_Hvpa50SqJ(66O_}wrLL>^K%bPTyrBIF76T;>tx zdK*e7)KSZngY-tg0=m4M(1>8N#iY~mT(glR60uTB$4+zlXIE%LIOiWO)VJQ}4K?;R zOF4%jy*S-u{TQb-+dL9H&kvzXJICIwcTzcfhm`Mb*ntErC?#-_n4pYCiarVp&OU^= zL@0(jqs8}-BFgt|N~rgBsmsIMbiOxFWo-PH##vC`bNAq5gO&;Catlbf(*m~m(cJcC z<5E61EH0cD--I<^9G+6Ff=$_+$eaM>K!iYc%7SwdO%dYI)K-Awe#su4<?QWi$zsIJWG*3@)rFtiKejwOwv-6v2Z{7@E29TImx@JyRFa@Ehc|sUA&F&0 zppH-AI1nNy$uJe~Mpj#MX9X@X z12anL*vQmIli=95SOf{4u*~PaR%KCU_T-%6$<{!chP%YOV~lzLU_KG!dXS^FUZ6f1 z85ztjxf@Csn-7tVMkR|4oDG#{#?wquzL(pu*~)G1$#nstd`WnyqNZ$KK3_XtEUGrhYTq zPIw%XZ^K9rRg~vGT-Z&?xui6Eh_$Jmu1#95DlP?Pt9{sPlgj~ihrHx+lvH`#*2@{I z?&2-RQEOb(pZbIHaKvSP0%UV>D&lp+VHea=wru&#fEwv83N4ow{t_Bg#0huI_uv+2 z+}@KV6fR?3OK6QWEa*8-FlI)yxx@Qr!DQmbckt(#XGW!&;oXa}TuT zH1$UMLf#5W`N@xKT|k(0s^;po?@}W?rBTwn+c^D8=vn32^iJQ2NsbJ5uDE5cglFZ&GAptpQJuyNAo1o( zhGdfSzCc5wlG8ipDCc9fyD;bxgVnKO%F*>aPFSL`c>&^@YW_#?)QdCAvB>Qva@CM( zbj463YJ7CL2y_N!X77U*{O6dVMp3%yW}s@~Vace$H%@75ywORiUSpBh>zeZogQ5&L=7dpy8tcX*kCMxp`W&{h=^4 zQ?@Uh&iYA(k(t&M%B1V12SX~Ggyr6i;Z0JFxX@*d%8P=^;vpRLt_7fsFCX~4+uy>U z{cySmWF)$n@q7pXFY`@?@%lakTEQBpj`y! zE_dQeP*zHHiA|UWpA;lZZpUpF<%5#-+&i7hh*S-Z#vqH_+$=M^;iE3;h_-=IyDoVm zR8NIPb-JRLL=heBn3~d6Zbmp9MU>Wz%MVq1?V=ln*=^&Q!qI9OM&jsne(9!CoJ>jY4)Yp^QMod#v zEcDaPJ;T{^I<)dba3xe?>Kf^&-Bcx55kbme>gfx5X%)j!iThjZz@WDC3<>K2=`Fq- z#%g)Ty4*tnIDZ$jDatJ*w?fVUy@*Qj)||^hPNHsS|Ou7&je@a!#N{a#nO$<1({V+M+adl~)7S zw^93=**@&EZ$PqmH3SWwg|^Gal0~ooN~K0GN|ospPQ9kW-68S%`)*zljc-PDRi_Jg zjU}AByQVjEkB{mdM!N5NOifPm5*ZYd5gY7M_Rt@XlBAWwPNrgHgcjTFm%w{_fnErO zjR3&DQ(hLL+;{05(5AG}#fKA3BQwk)NOC(U`i;i@fCJ%*G$m8SDaS z&e$}vorox;h!w@gmj~mFf-XNEkANXURD8RAN{2M;KHe3keq)6 zaV*SPH#}Cf`*Pm!CDJn6Kya6{P=*ChR(O>k=*Ex-w6CzF0?2m33<}8@3R8?o{^5+r^MTI%>ynz4fedFUNf4!%pH!@+z)DG-Uap&T`Qdy>#=;)n z*7K#3AtKA}1L)>;6$Ey>6jt1%*hsFiTSaxX6>&aq(?Njed@`ENm{6WxJvr}1$sdaA zXo%RuMgwDnu1MpDQsWuTml^%taG^ZCFhBTqxyXy3U?VPtEoz)@~9p|eRc9BNjlxLYp# z!7#;ah$(5dzW-EzKmuR^CjU9=N-5<`7*)q3p4KW#+WQ;%vNG_@xydNi1=m$LD+XSH z03L^JNmE>x@l%8ziix<3wy?)f_G-)$z4@5e^piFLBi%_wuv-|M=bFwU#YR3U1u|~b z^THd!&|}lSy?AIA4XZ4=^gSM3gRU+l2*$CRXB~*UMfNMqN9I`ZoJr$YtBh$=4{zzf zrG6k5Ly8t0Z*-oyDKn>=ueqCf!))acEH>EoHIXzut~tnm8od@Y|7TM;tz(gf#R0Lq zS98=k$OPQDyBTug!~;X}=XQFhZR^>H+~sIytORD{&56kO%rYwIxqs$iOq#quaBdC_ zzN*TQ)iOwJUHn%RvI%CcC6Xa)hl!Nl`I(}X()`JZzyv*;PR3ap?rgmaqQ@?}shURS zFqZYRh>x%52i{XoQ!upVYA`xPlcKgJ=Sy$_O4_0ug{kv)HulR1EKD}1J&>)r%1j2tj{*G%TBr6^r#ShiNG8i>hZd5k?`JzG}YsIf7Qn&xt$%SOIQqzy^CA zxcD%H(;TyA^CqU5L0UOBM3FcAcD~7{-_T0ADdD_w7^v!IDJ+X(@Ke2P-@;8QNMgOXViLm^~HJNx~-A?%;ZKyk5 zA^{infO2Fx)dxFIo7{T&ckYU>9<|R4;ZYQc*6Ai>@2kI5mAY*R4iMQJW;*SbxQ54e zO{;d8Mk92;sg^LMG>&C9S-=cyhZ4CLqXvzMoDj8+n}#(K9+McGAKR9S<3%2=!}(G^ zQ@zj<9<~rtqO3Z$T7eqvJ8}P+dc9fS`3Ppg1+|N`!C_y{%4pCNElnf3IBgk1bAU=~ zjm|Wmwh39-B(lD2r2UN8^`$C4ha8a(FlK=p${w+eB-rwk6f)dZ-)1Nm+_Z$}Zm`3^ ztdRkMw7eW7I-N|pT+B_Gd@Ph>IaNDAMk70>-iw8~f865_Dr%2qJ8r6VotE5r-{)y2 z1diW9;?b?5aJOP;0~H&GIl*%c%8hsFlv<3YUIaMRV`2>}ledXY^Ey55s06EVcH-Mo zpL@i^&yWc)=sD*bw~|1VQLR)sTjETiK5k=lbPW@G55eIe6R`EcBBOPEl#`nN{@<$3-ud%+1s0 z8lySt`e2RMwyL`hqV0^4HbRK@?bG>HNO7fYX^r5q&>kdMx8SsRs(T!Ss?z~48q!*a z;hzS7Xi$mB%I6T5a;`^M@HWbf4WugCgi@0r`>2e&t8Z@jEh=fy$%yWrphRHFV_35z zqR%v?VFC)6F|)bMMi6r_xbSUP6jWk<(!6&DwMhE*L@yR9^&v@+g|z!gdq5z|9oMn~K2Wy6#N zV6srH<4!z>EbEg$s;rBpMJb-Cm%su!R|!RWb|vE&VwBVc?R0Y{d%m}-1XTbj$qs7-16>m1dWqqjuT2OPvEp`L{D zjZvC=VtSJ~9#$0nCRJ3UwKT8rU(8l2H+av*1)#k<`*sXbgEIM&Xkv=yWfDSz>^ImF zsHaU^S!gHQ!y0p}wpGD|ILKo#LIpM+GKp&f$19u7 zE{9{578Cwe^qCjaMw9M(^NC-5qIVx#W@oinly9!NrIY%2cNHdM<^W9TR+ywDO4rE@ zU`=&8hZN`3XOPr%q->%Gd%*9$`T?C*H1k#tebfM9q~N2$ftulS^C`PmWY`+SH>tE} zc6g%#jGX}C42;PVG?}RGNN=|I)sUHvSz-734{8;H>A)!0s;p+R3LFhVn(J8~CKY49 z`TZ?^MoMGyah+UTgFiNxe>~pzVg-Dj$S-~z9D{u7^`^i!4EF@NS(Lj!KEJmDA7nHV zr!|}6C?%H{(l(E|iKQf0%1R1NnfKPm@!6hh;t=2hT@YzJWIo2AY!OLINS$-D^fh3_ zP*Dob#_TQm0+R=+zHE$8dLSF#WX7JWjxBB4JI=( zws`r8A8M0~5^_iP&WdC^_$%;Pu`EirUy-#KQrZD3#Fvt&VWn4O7QwN+(wGdL8gjE& z9bcxw3S+z&xuiDud*_gwi!jjkB$)SP$Y>c&0);|a~|1P zq+ui-PZM`YyA{^JMHJZEoYLG38Jn>P%rn#`FMW{NLgSj2?_0ClK+A0^LSNKlkWk2I zHYMD{fj|WCPeG)!@nO;UD9mu&mWkZco9<|=Q#VNNve#_r1-m*#Uve51+5!>7y7L9$ zpbgR=gQ+k^=Q)*1g4HcBocQ!A1%~-@T~20rF>!J%3h|TObVCqL7CQ}!$dlG#Utm!2 z!wc*xdY5XD=Nlf(-TpBE=QcQQ5otDJYvFNdCW&y7SZgaNHDjT)$WTs!w_gXS+9-aA|V^r+pukkEddz%vh*^mb&=7Iub`Yy zNM-==jG6mhhC9i^)lnVF9lTktu%Sy{rvoq<+|KiC*U;NN2 zZh-V*2IW*}N$i6S)c)&L4<8zY3hr6cd+aKDf03#t*a9H3u`=4d|Q-L|~H`FBpHKy*4#+hi2%N+8 za1i8Ie?aZ~c;G2JHvAkG|hzlY>n9+eslR z=KGzK5|Y{e6=?!+rmvl9;uiLA0WKNdF7-!_mbTv*_ish-FKI^$pb(<<`)^;8`};Sc zHdK4hC^W+ViYSUW%`u(8$t90izX3fKejEz+F88o;4S?bsQEr=Sc7s(l>GLnVtYZbCgmcVAA zRPRlB?v&Z43lW;l!R-ZAQM2<+0M$c*{`~dR*EiLq6f61WZwJoeQt3DMO{`4+oZT`l zz`ry*Dad=*uO=mXHNBe+X1kHD5zK-ZTzN{^G&g6muT0tjzW!2)Xiv4-j|OLv|JuI} z9;rkXSN1K^-+ueDtjHauGFrnTL192|n*ZZUq(!6y9nUiaD44@))5O9M}}TOhHE}T{3Dl zYw~X@_{m#}_|p`z<~S}mSe2HQL*><88P5={HMlLW{YOq2*m% z#U$NCN=*VewwqaRm=}r7b_sD`%F|bf(^C~Zx03+)!F?WvE*jJ_OeizWTDcg&FjmA{ z>oodaUa-iDHC~~wasBL&UkL7KJoqh*E=z5knoi6FSrsa7J)p(9A3&5glc|`N^+HWq z8cY}6Vx?k2TN~NEy)2o;93K47Z2ny7D7=|AJ6|Pnd)Uy%g=_Jogs@r~R^kwkOcGyQ zRGuhpnOA0(z;8cSv=&p-B$`wU&QgQh>4S(Ft?m-B+MHIa+;{9R&g`#eh;TDf@n;*1 zMGASdq&i2xQJ-*xj)$U&gS%Jv34AkY4&Dw`Xldk}sq^ps0(ZGqxfPc6`BkvL{QUKO z2+`3_;%BDssHp{=EY-9A*8Xo z70gfHm_ ziGxIzQ;$b^FNsj5Dq~Mg@LO<=ts+9XXj5Ml*_1R>yayMSmV&7Sdm+iFI2uZS*a0WH z4K7LafGiO-8lby8=r3%5n~GNQ=$37>zQPl!zxYy2L8~Q6SDq`EhP&(S9y}1B57$Cm ziDjcUt@c65*j55&m*?^%@xOoHS}P}IrFpEno7onjW;OEl+xM@pU%pq~wOWDSzE_U; zVCz2C18LlZ&k5nk#BY)m<)_p4#VB({E~H}`zb119v0&4+3Nn`?&llFG)mtyVy*eHN z-6pM@l|h9djRnY;*QE(wilLbpIoZzsTN_>i{)-mLhwN6dSmg8Tex*T(Q9y>3IxrC# zMy=l1jn-fK53cs)Vu}GRmL3>A(rrFR_VyvwL?^fnRRMv^*=)^9saFc=(7enYWOm8p zWMFBgaHhg(4Cl_#9_KpIwK)vOEDU$|<%9xO!R}xt@XH;eL#0R?GnF4*7~2xCZFB$a z_qLt(rO`}dtBV30(V6ih2_dU53+=o7M>$0lRYJQ;gO>(=@3@4ITiR*doX-I*n~|c; z*LLUp$v}>k&{|hkx$BNQP9pfxX3jgpE4+7*UUNJ$j)HTNU3liYdSn3Fkp z&ciB2-Sk0m%u!)fFmX7tL!2w9=*%5eAk7zAX^U$j%@HOk{`ej4&DJGaxL(1HDYeSfVgaGQ%I=P){|712e#Ez1_9ge?;g zzK}Z`>jX2RPcX-rDDo4piZJ-$2+Ddx3}bhUWSPZhxtH+12DCGs>5uLCdnkNA^p8eL zr?PmDHW|bvN&AXuQ#(*L-6i;}^6!}f_QE_ujX7j`BU{Zp4S8c(OF}SY3r6coXlD;1 z>><39L>?%Dv%Nl{2|eE1Xghs6so(1R^&kKI)-G2Vzx?uRt+pGLV@H3U zM0dT3jDE&8m)x)XZsAOjb+VAJ>B+=7!d)L4y+0{|-=(^fc3$;h0RZ6N?4?1eX9-#tQ2E)Y1ds zYcZyB)Q^zf2WxgCh#Bc@MrHtqFaxRRYmTn*;b0~%HijK?MEJoG^0jZwd9)FG7JtMc zS$%!>G73XK7Ned-jB|jHaZnu7zStAhc&i1*Xq@^Y$?nHjcfntO{c6em;~!RD3-FhJ z{QA$o{{0_6cMo*S{QCCGFW-LdBR+)B{kf~BOMJdRB;@M2ooCKSUM|LW2|ZJ~#tomE zCYvXnp`Z_T7igz{=r1~6mX1MapKB0Qe(-I)WAhI0|9{ZG6wMnAN&OKaZWtV_>nDN* zGb6L}sfPhvL@13IatsCkrseTFS`9V)+-Q9~P7ZwI)Xv``Uzc{TCBuck2{_*vuOyQ4 zp>7al2gv_cXLHV>>{6%=0rCV>=VW2mm;wRq^SL&anQx4Lk&T4#$Mtyqw}_XddDA-F ztC0hTJ?PFK$zciad@N5C|M0oQAHiu~G8WhnO~uC@0q&iJhr}D6$K`X#(-QfoOpY(Z zd##Vt^}7>(_15p#f3^t!{?EVv zgQi*E7}3HZke5?3G)FTL?DdA?G%_gEywpEN#wKUUPPW(9n9o7cGkCh?^;lp-JJ750 zn)C5PR`0@Q+3R}KI>UoJ^x1yAa6Sfi8mVy^i{k@luB{AY9!|EeePTMPZWyld&OeaX zCVeVkP(94^FbOFomW$^6JaP>d<6P0E+VKhc1AfZWnu96L$0?uLY=6WwcMM+$e=?lM zad|=ii0Y4U$LkYYwsQmn - - - - Powered by Kleeja - - -
    -

    403 - Access forbidden!

    -
    -
    - - \ No newline at end of file diff --git a/plugins/pdf_viewer/init.php b/plugins/pdf_viewer/init.php deleted file mode 100644 index d2bc629..0000000 --- a/plugins/pdf_viewer/init.php +++ /dev/null @@ -1,141 +0,0 @@ - array( - 'en' => 'PDF Viewer', - 'ar' => 'عارض بي دي أف' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.1', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Integrate a PDF viewer in download page', - 'ar' => 'عرض عارض ملفات بي دي اف في صفحة التحميل' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 10 -); - -//after installation message, you can remove it, it's not required -$kleeja_plugin['pdf_viewer']['first_run']['ar'] = " -شكراً لاستخدامك هذه الإضافة قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
    -info@kleeja.com -"; - -$kleeja_plugin['pdf_viewer']['first_run']['en'] = " -Thanks for using this plugin, to report bugs contact us: -
    -info@kleeja.com -"; - - -# Plugin Installation function -$kleeja_plugin['pdf_viewer']['install'] = function ($plg_id) -{ -// //new language variables -// add_olang(array( -// -// ), -// 'ar', -// $plg_id); -// -// add_olang(array( -// -// ), -// 'en', -// $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['pdf_viewer']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['pdf_viewer']['uninstall'] = function ($plg_id) { - //delete language variables -// foreach (array('ar', 'en') as $language) { -// delete_olang(null, $language, $plg_id); -// } -}; - - -# Plugin functions -$kleeja_plugin['pdf_viewer']['functions'] = array( - - - 'style_parse_func' => function($args) { - global $config; - - - if($args['template_name'] == 'download') { - - - $x = PHP_EOL . ' -
    -
    - -
    -
    '; - - - $html = $args['html'] . $x; - - return compact('html'); - } - }, - - 'b4_showsty_downlaod_id_filename' => function($args){ - - - $file_info = $args['file_info']; - - $show_pdf_viewer_code = false; - - $type_mimes = array( - 'pdf' - ); - - if(in_array(strtolower($file_info['type']), $type_mimes)){ - - $show_pdf_viewer_code = true; - - global $config; - - $pdf_path = $config['siteurl'] . "{$file_info['folder']}/{$file_info['name']}"; - - is_array($plugin_run_result = Plugins::getInstance()->run('plugin:pdf_viewer:do_display', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - } - - return compact('show_pdf_viewer_code', 'pdf_path'); - } -); - diff --git a/plugins/pdf_viewer/v/compatibility.js b/plugins/pdf_viewer/v/compatibility.js deleted file mode 100755 index 06f54bf..0000000 --- a/plugins/pdf_viewer/v/compatibility.js +++ /dev/null @@ -1,577 +0,0 @@ -/* -*- 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 VBArray, PDFJS */ - -'use strict'; - -// Initializing PDFJS global object here, it case if we need to change/disable -// some PDF.js features, e.g. range requests -if (typeof PDFJS === 'undefined') { - (typeof window !== 'undefined' ? window : this).PDFJS = {}; -} - -// Checking if the typed arrays are supported -// Support: iOS<6.0 (subarray), IE<10, Android<4.0 -(function checkTypedArrayCompatibility() { - if (typeof Uint8Array !== 'undefined') { - // Support: iOS<6.0 - if (typeof Uint8Array.prototype.subarray === 'undefined') { - Uint8Array.prototype.subarray = function subarray(start, end) { - return new Uint8Array(this.slice(start, end)); - }; - Float32Array.prototype.subarray = function subarray(start, end) { - return new Float32Array(this.slice(start, end)); - }; - } - - // Support: Android<4.1 - if (typeof Float64Array === 'undefined') { - window.Float64Array = Float32Array; - } - return; - } - - function subarray(start, end) { - return new TypedArray(this.slice(start, end)); - } - - function setArrayOffset(array, offset) { - if (arguments.length < 2) { - offset = 0; - } - for (var i = 0, n = array.length; i < n; ++i, ++offset) { - this[offset] = array[i] & 0xFF; - } - } - - function TypedArray(arg1) { - var result, i, n; - if (typeof arg1 === 'number') { - result = []; - for (i = 0; i < arg1; ++i) { - result[i] = 0; - } - } else if ('slice' in arg1) { - result = arg1.slice(0); - } else { - result = []; - for (i = 0, n = arg1.length; i < n; ++i) { - result[i] = arg1[i]; - } - } - - result.subarray = subarray; - result.buffer = result; - result.byteLength = result.length; - result.set = setArrayOffset; - - if (typeof arg1 === 'object' && arg1.buffer) { - result.buffer = arg1.buffer; - } - return result; - } - - window.Uint8Array = TypedArray; - window.Int8Array = TypedArray; - - // we don't need support for set, byteLength for 32-bit array - // so we can use the TypedArray as well - window.Uint32Array = TypedArray; - window.Int32Array = TypedArray; - window.Uint16Array = TypedArray; - window.Float32Array = TypedArray; - window.Float64Array = TypedArray; -})(); - -// URL = URL || webkitURL -// Support: Safari<7, Android 4.2+ -(function normalizeURLObject() { - if (!window.URL) { - window.URL = window.webkitURL; - } -})(); - -// Object.defineProperty()? -// Support: Android<4.0, Safari<5.1 -(function checkObjectDefinePropertyCompatibility() { - if (typeof Object.defineProperty !== 'undefined') { - var definePropertyPossible = true; - try { - // some browsers (e.g. safari) cannot use defineProperty() on DOM objects - // and thus the native version is not sufficient - Object.defineProperty(new Image(), 'id', { value: 'test' }); - // ... another test for android gb browser for non-DOM objects - var Test = function Test() {}; - Test.prototype = { get id() { } }; - Object.defineProperty(new Test(), 'id', - { value: '', configurable: true, enumerable: true, writable: false }); - } catch (e) { - definePropertyPossible = false; - } - if (definePropertyPossible) { - return; - } - } - - Object.defineProperty = function objectDefineProperty(obj, name, def) { - delete obj[name]; - if ('get' in def) { - obj.__defineGetter__(name, def['get']); - } - if ('set' in def) { - obj.__defineSetter__(name, def['set']); - } - if ('value' in def) { - obj.__defineSetter__(name, function objectDefinePropertySetter(value) { - this.__defineGetter__(name, function objectDefinePropertyGetter() { - return value; - }); - return value; - }); - obj[name] = def.value; - } - }; -})(); - - -// No XMLHttpRequest#response? -// Support: IE<11, Android <4.0 -(function checkXMLHttpRequestResponseCompatibility() { - var xhrPrototype = XMLHttpRequest.prototype; - var xhr = new XMLHttpRequest(); - if (!('overrideMimeType' in xhr)) { - // IE10 might have response, but not overrideMimeType - // Support: IE10 - Object.defineProperty(xhrPrototype, 'overrideMimeType', { - value: function xmlHttpRequestOverrideMimeType(mimeType) {} - }); - } - if ('responseType' in xhr) { - return; - } - - // The worker will be using XHR, so we can save time and disable worker. - PDFJS.disableWorker = true; - - Object.defineProperty(xhrPrototype, 'responseType', { - get: function xmlHttpRequestGetResponseType() { - return this._responseType || 'text'; - }, - set: function xmlHttpRequestSetResponseType(value) { - if (value === 'text' || value === 'arraybuffer') { - this._responseType = value; - if (value === 'arraybuffer' && - typeof this.overrideMimeType === 'function') { - this.overrideMimeType('text/plain; charset=x-user-defined'); - } - } - } - }); - - // Support: IE9 - if (typeof VBArray !== 'undefined') { - Object.defineProperty(xhrPrototype, 'response', { - get: function xmlHttpRequestResponseGet() { - if (this.responseType === 'arraybuffer') { - return new Uint8Array(new VBArray(this.responseBody).toArray()); - } else { - return this.responseText; - } - } - }); - return; - } - - Object.defineProperty(xhrPrototype, 'response', { - get: function xmlHttpRequestResponseGet() { - if (this.responseType !== 'arraybuffer') { - return this.responseText; - } - var text = this.responseText; - var i, n = text.length; - var result = new Uint8Array(n); - for (i = 0; i < n; ++i) { - result[i] = text.charCodeAt(i) & 0xFF; - } - return result.buffer; - } - }); -})(); - -// window.btoa (base64 encode function) ? -// Support: IE<10 -(function checkWindowBtoaCompatibility() { - if ('btoa' in window) { - return; - } - - var digits = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - - window.btoa = function windowBtoa(chars) { - var buffer = ''; - var i, n; - for (i = 0, n = chars.length; i < n; i += 3) { - var b1 = chars.charCodeAt(i) & 0xFF; - var b2 = chars.charCodeAt(i + 1) & 0xFF; - var b3 = chars.charCodeAt(i + 2) & 0xFF; - var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4); - var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64; - var d4 = i + 2 < n ? (b3 & 0x3F) : 64; - buffer += (digits.charAt(d1) + digits.charAt(d2) + - digits.charAt(d3) + digits.charAt(d4)); - } - return buffer; - }; -})(); - -// window.atob (base64 encode function)? -// Support: IE<10 -(function checkWindowAtobCompatibility() { - if ('atob' in window) { - return; - } - - // https://github.com/davidchambers/Base64.js - var digits = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - window.atob = function (input) { - input = input.replace(/=+$/, ''); - if (input.length % 4 === 1) { - throw new Error('bad atob input'); - } - for ( - // initialize result and counters - var bc = 0, bs, buffer, idx = 0, output = ''; - // get next character - buffer = input.charAt(idx++); - // character found in table? - // initialize bit storage and add its ascii value - ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, - // and if not first of each 4 characters, - // convert the first 8 bits to one ascii character - bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 - ) { - // try to find character in table (0-63, not found => -1) - buffer = digits.indexOf(buffer); - } - return output; - }; -})(); - -// Function.prototype.bind? -// Support: Android<4.0, iOS<6.0 -(function checkFunctionPrototypeBindCompatibility() { - if (typeof Function.prototype.bind !== 'undefined') { - return; - } - - Function.prototype.bind = function functionPrototypeBind(obj) { - var fn = this, headArgs = Array.prototype.slice.call(arguments, 1); - var bound = function functionPrototypeBindBound() { - var args = headArgs.concat(Array.prototype.slice.call(arguments)); - return fn.apply(obj, args); - }; - return bound; - }; -})(); - -// HTMLElement dataset property -// Support: IE<11, Safari<5.1, Android<4.0 -(function checkDatasetProperty() { - var div = document.createElement('div'); - if ('dataset' in div) { - return; // dataset property exists - } - - Object.defineProperty(HTMLElement.prototype, 'dataset', { - get: function() { - if (this._dataset) { - return this._dataset; - } - - var dataset = {}; - for (var j = 0, jj = this.attributes.length; j < jj; j++) { - var attribute = this.attributes[j]; - if (attribute.name.substring(0, 5) !== 'data-') { - continue; - } - var key = attribute.name.substring(5).replace(/\-([a-z])/g, - function(all, ch) { - return ch.toUpperCase(); - }); - dataset[key] = attribute.value; - } - - Object.defineProperty(this, '_dataset', { - value: dataset, - writable: false, - enumerable: false - }); - return dataset; - }, - enumerable: true - }); -})(); - -// HTMLElement classList property -// Support: IE<10, Android<4.0, iOS<5.0 -(function checkClassListProperty() { - var div = document.createElement('div'); - if ('classList' in div) { - return; // classList property exists - } - - function changeList(element, itemName, add, remove) { - var s = element.className || ''; - var list = s.split(/\s+/g); - if (list[0] === '') { - list.shift(); - } - var index = list.indexOf(itemName); - if (index < 0 && add) { - list.push(itemName); - } - if (index >= 0 && remove) { - list.splice(index, 1); - } - element.className = list.join(' '); - return (index >= 0); - } - - var classListPrototype = { - add: function(name) { - changeList(this.element, name, true, false); - }, - contains: function(name) { - return changeList(this.element, name, false, false); - }, - remove: function(name) { - changeList(this.element, name, false, true); - }, - toggle: function(name) { - changeList(this.element, name, true, true); - } - }; - - Object.defineProperty(HTMLElement.prototype, 'classList', { - get: function() { - if (this._classList) { - return this._classList; - } - - var classList = Object.create(classListPrototype, { - element: { - value: this, - writable: false, - enumerable: true - } - }); - Object.defineProperty(this, '_classList', { - value: classList, - writable: false, - enumerable: false - }); - return classList; - }, - enumerable: true - }); -})(); - -// Check console compatibility -// In older IE versions the console object is not available -// unless console is open. -// Support: IE<10 -(function checkConsoleCompatibility() { - if (!('console' in window)) { - window.console = { - log: function() {}, - error: function() {}, - warn: function() {} - }; - } else if (!('bind' in console.log)) { - // native functions in IE9 might not have bind - console.log = (function(fn) { - return function(msg) { return fn(msg); }; - })(console.log); - console.error = (function(fn) { - return function(msg) { return fn(msg); }; - })(console.error); - console.warn = (function(fn) { - return function(msg) { return fn(msg); }; - })(console.warn); - } -})(); - -// Check onclick compatibility in Opera -// Support: Opera<15 -(function checkOnClickCompatibility() { - // workaround for reported Opera bug DSK-354448: - // onclick fires on disabled buttons with opaque content - function ignoreIfTargetDisabled(event) { - if (isDisabled(event.target)) { - event.stopPropagation(); - } - } - function isDisabled(node) { - return node.disabled || (node.parentNode && isDisabled(node.parentNode)); - } - if (navigator.userAgent.indexOf('Opera') !== -1) { - // use browser detection since we cannot feature-check this bug - document.addEventListener('click', ignoreIfTargetDisabled, true); - } -})(); - -// Checks if possible to use URL.createObjectURL() -// Support: IE -(function checkOnBlobSupport() { - // sometimes IE loosing the data created with createObjectURL(), see #3977 - if (navigator.userAgent.indexOf('Trident') >= 0) { - PDFJS.disableCreateObjectURL = true; - } -})(); - -// Checks if navigator.language is supported -(function checkNavigatorLanguage() { - if ('language' in navigator) { - return; - } - PDFJS.locale = navigator.userLanguage || 'en-US'; -})(); - -(function checkRangeRequests() { - // Safari has issues with cached range requests see: - // https://github.com/mozilla/pdf.js/issues/3260 - // Last tested with version 6.0.4. - // Support: Safari 6.0+ - var isSafari = Object.prototype.toString.call( - window.HTMLElement).indexOf('Constructor') > 0; - - // Older versions of Android (pre 3.0) has issues with range requests, see: - // https://github.com/mozilla/pdf.js/issues/3381. - // Make sure that we only match webkit-based Android browsers, - // since Firefox/Fennec works as expected. - // Support: Android<3.0 - var regex = /Android\s[0-2][^\d]/; - var isOldAndroid = regex.test(navigator.userAgent); - - // Range requests are broken in Chrome 39 and 40, https://crbug.com/442318 - var isChromeWithRangeBug = /Chrome\/(39|40)\./.test(navigator.userAgent); - - if (isSafari || isOldAndroid || isChromeWithRangeBug) { - PDFJS.disableRange = true; - PDFJS.disableStream = true; - } -})(); - -// Check if the browser supports manipulation of the history. -// Support: IE<10, Android<4.2 -(function checkHistoryManipulation() { - // Android 2.x has so buggy pushState support that it was removed in - // Android 3.0 and restored as late as in Android 4.2. - // Support: Android 2.x - if (!history.pushState || navigator.userAgent.indexOf('Android 2.') >= 0) { - PDFJS.disableHistory = true; - } -})(); - -// Support: IE<11, Chrome<21, Android<4.4, Safari<6 -(function checkSetPresenceInImageData() { - // IE < 11 will use window.CanvasPixelArray which lacks set function. - if (window.CanvasPixelArray) { - if (typeof window.CanvasPixelArray.prototype.set !== 'function') { - window.CanvasPixelArray.prototype.set = function(arr) { - for (var i = 0, ii = this.length; i < ii; i++) { - this[i] = arr[i]; - } - }; - } - } else { - // Old Chrome and Android use an inaccessible CanvasPixelArray prototype. - // Because we cannot feature detect it, we rely on user agent parsing. - var polyfill = false, versionMatch; - if (navigator.userAgent.indexOf('Chrom') >= 0) { - versionMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); - // Chrome < 21 lacks the set function. - polyfill = versionMatch && parseInt(versionMatch[2]) < 21; - } else if (navigator.userAgent.indexOf('Android') >= 0) { - // Android < 4.4 lacks the set function. - // Android >= 4.4 will contain Chrome in the user agent, - // thus pass the Chrome check above and not reach this block. - polyfill = /Android\s[0-4][^\d]/g.test(navigator.userAgent); - } else if (navigator.userAgent.indexOf('Safari') >= 0) { - versionMatch = navigator.userAgent. - match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//); - // Safari < 6 lacks the set function. - polyfill = versionMatch && parseInt(versionMatch[1]) < 6; - } - - if (polyfill) { - var contextPrototype = window.CanvasRenderingContext2D.prototype; - contextPrototype._createImageData = contextPrototype.createImageData; - contextPrototype.createImageData = function(w, h) { - var imageData = this._createImageData(w, h); - imageData.data.set = function(arr) { - for (var i = 0, ii = this.length; i < ii; i++) { - this[i] = arr[i]; - } - }; - return imageData; - }; - } - } -})(); - -// Support: IE<10, Android<4.0, iOS -(function checkRequestAnimationFrame() { - function fakeRequestAnimationFrame(callback) { - window.setTimeout(callback, 20); - } - - var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent); - if (isIOS) { - // requestAnimationFrame on iOS is broken, replacing with fake one. - window.requestAnimationFrame = fakeRequestAnimationFrame; - return; - } - if ('requestAnimationFrame' in window) { - return; - } - window.requestAnimationFrame = - window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || - fakeRequestAnimationFrame; -})(); - -(function checkCanvasSizeLimitation() { - var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent); - var isAndroid = /Android/g.test(navigator.userAgent); - if (isIOS || isAndroid) { - // 5MP - PDFJS.maxCanvasPixels = 5242880; - } -})(); - -// Disable fullscreen support for certain problematic configurations. -// Support: IE11+ (when embedded). -(function checkFullscreenSupport() { - var isEmbeddedIE = (navigator.userAgent.indexOf('Trident') >= 0 && - window.parent !== window); - if (isEmbeddedIE) { - PDFJS.disableFullscreen = true; - } -})(); diff --git a/plugins/pdf_viewer/v/example.local.css b/plugins/pdf_viewer/v/example.local.css deleted file mode 100755 index 034347d..0000000 --- a/plugins/pdf_viewer/v/example.local.css +++ /dev/null @@ -1,27 +0,0 @@ -/* This is just a sample file with CSS rules. You should write your own @font-face declarations - * to add support for your desired fonts. - */ - -@font-face { - font-family: 'Novecentowide Book'; - src: url("/ViewerJS/fonts/Novecentowide-Bold-webfont.eot"); - src: url("/ViewerJS/fonts/Novecentowide-Bold-webfont.eot?#iefix") format("embedded-opentype"), - url("/ViewerJS/fonts/Novecentowide-Bold-webfont.woff") format("woff"), - url("/fonts/Novecentowide-Bold-webfont.ttf") format("truetype"), - url("/fonts/Novecentowide-Bold-webfont.svg#NovecentowideBookBold") format("svg"); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'exotica'; - src: url('/ViewerJS/fonts/Exotica-webfont.eot'); - src: url('/ViewerJS/fonts/Exotica-webfont.eot?#iefix') format('embedded-opentype'), - url('/ViewerJS/fonts/Exotica-webfont.woff') format('woff'), - url('/ViewerJS/fonts/Exotica-webfont.ttf') format('truetype'), - url('/ViewerJS/fonts/Exotica-webfont.svg#exoticamedium') format('svg'); - font-weight: normal; - font-style: normal; - -} - diff --git a/plugins/pdf_viewer/v/images/kogmbh.png b/plugins/pdf_viewer/v/images/kogmbh.png deleted file mode 100755 index 00e8f4debdda56ba5a57472b43a23b020080bfa9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2835 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 O5r8?-l2B*lk?>!&x?|k{ diff --git a/plugins/pdf_viewer/v/images/toolbarButton-download.png b/plugins/pdf_viewer/v/images/toolbarButton-download.png deleted file mode 100755 index 8676d8e2c2c0bac77cfce486f6f18639a8caa987..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmV+b0{{JqP)z}Is24wg34Vg0&(Nh)A4KqyCy|cYNsu~v@z2dmB9tj1uH`lp^J3U`8~E{N z-p=3On^hdg5sIR03L*9Y+kk-hD<6Ofzy>Vo6d1ck4*P?_;4T~v8^TAR$Zf0DN+pxY zdoYJGiL9nW@D^3_!$~5MNL4D8YtWAX>pTG(3u?~~8-RJKR61@po0nw&j-Zf}uM`Re z1IBnHvj;%lW(tv*fb&ZHFIX|iIJtqC9%tO0lVf5?1zr z%n1($UyPgb4t7C5rMH$zKiPV#uKO2UXNZ0M7GMAtm#g$qt>3!<0000gp@kF&{Rb5bN zGzijG&{UKVshtpNClNu)%Ekhbw2`1J>Z6HtgGN0xKEhh;{0EDsrSU_qGw%`SWF~jc zxpQak3{VFTy2*App+P}o)NW`Vy70=Y$@eYTjRgDq)}ID15R?~1J&mx+C#(qTX;VcI z7?3B$uiL;R>R}-rT@%F{Q^f$#FZUOjQcfPeZ$<}E18p$$rORXa`Z6Q;=m%OKw=v~i zDrMy^zYYg%xi!g`vmMKrqSFdWO=yItW9DoVJ*XuE>5afFEf*aJP=P8AjY%zNU{t}` z&6S2q!}*1UI~}}%g2r}h|1FKpX|M(R^hMUF<}P<`VJOHX(}C-46~4}~;<03|R$zne zd{Hvx6aP5;bXPIK`>N>asx-f>p5`o;?TlKMQ-6LJb45R#;%UHjic=P>Ck@ z+{d0AQcWVHUUFA4oxlhWu<(*~7(R)cs(MMk>=;Zw$5hvZ{W->}h6+FUwIhgP8WFVd hn-r{!B2=PuoIg4=n|)8MY<2(u002ovPDHLkV1hfJ)Vlxx diff --git a/plugins/pdf_viewer/v/images/toolbarButton-menuArrows.png b/plugins/pdf_viewer/v/images/toolbarButton-menuArrows.png deleted file mode 100755 index 31b06b5af9e548b15e274677b8ecaac1c1d06e77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 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 diff --git a/plugins/pdf_viewer/v/images/toolbarButton-zoomIn.png b/plugins/pdf_viewer/v/images/toolbarButton-zoomIn.png deleted file mode 100755 index 670acd93f5324c0f32e37e13d43c31890bdd123a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228 zcmVviSpk+Ka&^`vn5+K)IU-oAe*-xp*r - - - - - - - ViewerJS - - - - - - -
    -
    -
    -
    - - - -
    -
    -
    -
    -
    - - - - -
    -
    -
    -
    - -
    - -
    - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - ✖ -
    -
    -
    -
    - - diff --git a/plugins/pdf_viewer/v/pdf.js b/plugins/pdf_viewer/v/pdf.js deleted file mode 100755 index 463d7d0..0000000 --- a/plugins/pdf_viewer/v/pdf.js +++ /dev/null @@ -1,8052 +0,0 @@ -/* -*- 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()); - } -}); - -//#if !(FIREFOX || MOZCENTRAL || B2G || CHROME) -//// 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; -})(); -//#else -//PDFJS.hasCanvasTypedArrays = true; -//#endif - -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; - } -//#if !MOZCENTRAL - 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; -//#else -//throw new Error('DOM Promise is not present'); -//#endif -})(); - -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 !SINGLE_FILE - 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.'); - } - } -//#endif - // 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. -//#if !PRODUCTION - Util.loadScript(PDFJS.workerSrc); -//#endif -//#if PRODUCTION && SINGLE_FILE -// PDFJS.fakeWorkerFilesLoadedCapability.resolve(); -//#endif -//#if PRODUCTION && !SINGLE_FILE -// Util.loadScript(PDFJS.workerSrc, function() { -// PDFJS.fakeWorkerFilesLoadedCapability.resolve(); -// }); -//#endif - } - 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) : - '&#x' + (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; -})(); - - -// contexts store most of the state we need natively. -// However, PDF needs a bit more state, which we store here. - -// Minimal font size that would be used during canvas fillText operations. -var MIN_FONT_SIZE = 16; -// Maximum font size that would be used during canvas fillText operations. -var MAX_FONT_SIZE = 100; -var MAX_GROUP_SIZE = 4096; - -// Heuristic value used when enforcing minimum line widths. -var MIN_WIDTH_FACTOR = 0.65; - -var COMPILE_TYPE3_GLYPHS = true; -var MAX_SIZE_TO_COMPILE = 1000; - -var FULL_CHUNK_HEIGHT = 16; - -function createScratchCanvas(width, height) { - var canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - return canvas; -} - -function addContextCurrentTransform(ctx) { - // If the context doesn't expose a `mozCurrentTransform`, add a JS based one. - if (!ctx.mozCurrentTransform) { - ctx._originalSave = ctx.save; - ctx._originalRestore = ctx.restore; - ctx._originalRotate = ctx.rotate; - ctx._originalScale = ctx.scale; - ctx._originalTranslate = ctx.translate; - ctx._originalTransform = ctx.transform; - ctx._originalSetTransform = ctx.setTransform; - - ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0]; - ctx._transformStack = []; - - Object.defineProperty(ctx, 'mozCurrentTransform', { - get: function getCurrentTransform() { - return this._transformMatrix; - } - }); - - Object.defineProperty(ctx, 'mozCurrentTransformInverse', { - get: function getCurrentTransformInverse() { - // Calculation done using WolframAlpha: - // http://www.wolframalpha.com/input/? - // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} - - var m = this._transformMatrix; - var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; - - var ad_bc = a * d - b * c; - var bc_ad = b * c - a * d; - - return [ - d / ad_bc, - b / bc_ad, - c / bc_ad, - a / ad_bc, - (d * e - c * f) / bc_ad, - (b * e - a * f) / ad_bc - ]; - } - }); - - ctx.save = function ctxSave() { - var old = this._transformMatrix; - this._transformStack.push(old); - this._transformMatrix = old.slice(0, 6); - - this._originalSave(); - }; - - ctx.restore = function ctxRestore() { - var prev = this._transformStack.pop(); - if (prev) { - this._transformMatrix = prev; - this._originalRestore(); - } - }; - - ctx.translate = function ctxTranslate(x, y) { - var m = this._transformMatrix; - m[4] = m[0] * x + m[2] * y + m[4]; - m[5] = m[1] * x + m[3] * y + m[5]; - - this._originalTranslate(x, y); - }; - - ctx.scale = function ctxScale(x, y) { - var m = this._transformMatrix; - m[0] = m[0] * x; - m[1] = m[1] * x; - m[2] = m[2] * y; - m[3] = m[3] * y; - - this._originalScale(x, y); - }; - - ctx.transform = function ctxTransform(a, b, c, d, e, f) { - var m = this._transformMatrix; - this._transformMatrix = [ - m[0] * a + m[2] * b, - m[1] * a + m[3] * b, - m[0] * c + m[2] * d, - m[1] * c + m[3] * d, - m[0] * e + m[2] * f + m[4], - m[1] * e + m[3] * f + m[5] - ]; - - ctx._originalTransform(a, b, c, d, e, f); - }; - - ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { - this._transformMatrix = [a, b, c, d, e, f]; - - ctx._originalSetTransform(a, b, c, d, e, f); - }; - - ctx.rotate = function ctxRotate(angle) { - var cosValue = Math.cos(angle); - var sinValue = Math.sin(angle); - - var m = this._transformMatrix; - this._transformMatrix = [ - m[0] * cosValue + m[2] * sinValue, - m[1] * cosValue + m[3] * sinValue, - m[0] * (-sinValue) + m[2] * cosValue, - m[1] * (-sinValue) + m[3] * cosValue, - m[4], - m[5] - ]; - - this._originalRotate(angle); - }; - } -} - -var CachedCanvases = (function CachedCanvasesClosure() { - var cache = {}; - return { - getCanvas: function CachedCanvases_getCanvas(id, width, height, - trackTransform) { - var canvasEntry; - if (cache[id] !== undefined) { - canvasEntry = cache[id]; - canvasEntry.canvas.width = width; - canvasEntry.canvas.height = height; - // reset canvas transform for emulated mozCurrentTransform, if needed - canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0); - } else { - var canvas = createScratchCanvas(width, height); - var ctx = canvas.getContext('2d'); - if (trackTransform) { - addContextCurrentTransform(ctx); - } - cache[id] = canvasEntry = {canvas: canvas, context: ctx}; - } - return canvasEntry; - }, - clear: function () { - for (var id in cache) { - var canvasEntry = cache[id]; - // Zeroing the width and height causes Firefox to release graphics - // resources immediately, which can greatly reduce memory consumption. - canvasEntry.canvas.width = 0; - canvasEntry.canvas.height = 0; - delete cache[id]; - } - } - }; -})(); - -function compileType3Glyph(imgData) { - var POINT_TO_PROCESS_LIMIT = 1000; - - var width = imgData.width, height = imgData.height; - var i, j, j0, width1 = width + 1; - var points = new Uint8Array(width1 * (height + 1)); - var POINT_TYPES = - new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); - - // decodes bit-packed mask data - var lineSize = (width + 7) & ~7, data0 = imgData.data; - var data = new Uint8Array(lineSize * height), pos = 0, ii; - for (i = 0, ii = data0.length; i < ii; i++) { - var mask = 128, elem = data0[i]; - while (mask > 0) { - data[pos++] = (elem & mask) ? 0 : 255; - mask >>= 1; - } - } - - // finding iteresting points: every point is located between mask pixels, - // so there will be points of the (width + 1)x(height + 1) grid. Every point - // will have flags assigned based on neighboring mask pixels: - // 4 | 8 - // --P-- - // 2 | 1 - // We are interested only in points with the flags: - // - outside corners: 1, 2, 4, 8; - // - inside corners: 7, 11, 13, 14; - // - and, intersections: 5, 10. - var count = 0; - pos = 0; - if (data[pos] !== 0) { - points[0] = 1; - ++count; - } - for (j = 1; j < width; j++) { - if (data[pos] !== data[pos + 1]) { - points[j] = data[pos] ? 2 : 1; - ++count; - } - pos++; - } - if (data[pos] !== 0) { - points[j] = 2; - ++count; - } - for (i = 1; i < height; i++) { - pos = i * lineSize; - j0 = i * width1; - if (data[pos - lineSize] !== data[pos]) { - points[j0] = data[pos] ? 1 : 8; - ++count; - } - // 'sum' is the position of the current pixel configuration in the 'TYPES' - // array (in order 8-1-2-4, so we can use '>>2' to shift the column). - var sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); - for (j = 1; j < width; j++) { - sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + - (data[pos - lineSize + 1] ? 8 : 0); - if (POINT_TYPES[sum]) { - points[j0 + j] = POINT_TYPES[sum]; - ++count; - } - pos++; - } - if (data[pos - lineSize] !== data[pos]) { - points[j0 + j] = data[pos] ? 2 : 4; - ++count; - } - - if (count > POINT_TO_PROCESS_LIMIT) { - return null; - } - } - - pos = lineSize * (height - 1); - j0 = i * width1; - if (data[pos] !== 0) { - points[j0] = 8; - ++count; - } - for (j = 1; j < width; j++) { - if (data[pos] !== data[pos + 1]) { - points[j0 + j] = data[pos] ? 4 : 8; - ++count; - } - pos++; - } - if (data[pos] !== 0) { - points[j0 + j] = 4; - ++count; - } - if (count > POINT_TO_PROCESS_LIMIT) { - return null; - } - - // building outlines - var steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); - var outlines = []; - for (i = 0; count && i <= height; i++) { - var p = i * width1; - var end = p + width; - while (p < end && !points[p]) { - p++; - } - if (p === end) { - continue; - } - var coords = [p % width1, i]; - - var type = points[p], p0 = p, pp; - do { - var step = steps[type]; - do { - p += step; - } while (!points[p]); - - pp = points[p]; - if (pp !== 5 && pp !== 10) { - // set new direction - type = pp; - // delete mark - points[p] = 0; - } else { // type is 5 or 10, ie, a crossing - // set new direction - type = pp & ((0x33 * type) >> 4); - // set new type for "future hit" - points[p] &= (type >> 2 | type << 2); - } - - coords.push(p % width1); - coords.push((p / width1) | 0); - --count; - } while (p0 !== p); - outlines.push(coords); - --i; - } - - var drawOutline = function(c) { - c.save(); - // the path shall be painted in [0..1]x[0..1] space - c.scale(1 / width, -1 / height); - c.translate(0, -height); - c.beginPath(); - for (var i = 0, ii = outlines.length; i < ii; i++) { - var o = outlines[i]; - c.moveTo(o[0], o[1]); - for (var j = 2, jj = o.length; j < jj; j += 2) { - c.lineTo(o[j], o[j+1]); - } - } - c.fill(); - c.beginPath(); - c.restore(); - }; - - return drawOutline; -} - -var CanvasExtraState = (function CanvasExtraStateClosure() { - function CanvasExtraState(old) { - // Are soft masks and alpha values shapes or opacities? - this.alphaIsShape = false; - this.fontSize = 0; - this.fontSizeScale = 1; - this.textMatrix = IDENTITY_MATRIX; - this.textMatrixScale = 1; - this.fontMatrix = FONT_IDENTITY_MATRIX; - this.leading = 0; - // Current point (in user coordinates) - this.x = 0; - this.y = 0; - // Start of text line (in text coordinates) - this.lineX = 0; - this.lineY = 0; - // Character and word spacing - this.charSpacing = 0; - this.wordSpacing = 0; - this.textHScale = 1; - this.textRenderingMode = TextRenderingMode.FILL; - this.textRise = 0; - // Default fore and background colors - this.fillColor = '#000000'; - this.strokeColor = '#000000'; - this.patternFill = false; - // Note: fill alpha applies to all non-stroking operations - this.fillAlpha = 1; - this.strokeAlpha = 1; - this.lineWidth = 1; - this.activeSMask = null; // nonclonable field (see the save method below) - - this.old = old; - } - - CanvasExtraState.prototype = { - clone: function CanvasExtraState_clone() { - return Object.create(this); - }, - setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) { - this.x = x; - this.y = y; - } - }; - return CanvasExtraState; -})(); - -var CanvasGraphics = (function CanvasGraphicsClosure() { - // Defines the time the executeOperatorList is going to be executing - // before it stops and shedules a continue of execution. - var EXECUTION_TIME = 15; - // Defines the number of steps before checking the execution time - var EXECUTION_STEPS = 10; - - function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer) { - this.ctx = canvasCtx; - this.current = new CanvasExtraState(); - this.stateStack = []; - this.pendingClip = null; - this.pendingEOFill = false; - this.res = null; - this.xobjs = null; - this.commonObjs = commonObjs; - this.objs = objs; - this.imageLayer = imageLayer; - this.groupStack = []; - this.processingType3 = null; - // Patterns are painted relative to the initial page/form transform, see pdf - // spec 8.7.2 NOTE 1. - this.baseTransform = null; - this.baseTransformStack = []; - this.groupLevel = 0; - this.smaskStack = []; - this.smaskCounter = 0; - this.tempSMask = null; - if (canvasCtx) { - // NOTE: if mozCurrentTransform is polyfilled, then the current state of - // the transformation must already be set in canvasCtx._transformMatrix. - addContextCurrentTransform(canvasCtx); - } - this.cachedGetSinglePixelWidth = null; - } - - function putBinaryImageData(ctx, imgData) { - if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) { - ctx.putImageData(imgData, 0, 0); - return; - } - - // Put the image data to the canvas in chunks, rather than putting the - // whole image at once. This saves JS memory, because the ImageData object - // is smaller. It also possibly saves C++ memory within the implementation - // of putImageData(). (E.g. in Firefox we make two short-lived copies of - // the data passed to putImageData()). |n| shouldn't be too small, however, - // because too many putImageData() calls will slow things down. - // - // Note: as written, if the last chunk is partial, the putImageData() call - // will (conceptually) put pixels past the bounds of the canvas. But - // that's ok; any such pixels are ignored. - - var height = imgData.height, width = imgData.width; - var partialChunkHeight = height % FULL_CHUNK_HEIGHT; - var fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; - var totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; - - var chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); - var srcPos = 0, destPos; - var src = imgData.data; - var dest = chunkImgData.data; - var i, j, thisChunkHeight, elemsInThisChunk; - - // There are multiple forms in which the pixel data can be passed, and - // imgData.kind tells us which one this is. - if (imgData.kind === ImageKind.GRAYSCALE_1BPP) { - // Grayscale, 1 bit per pixel (i.e. black-and-white). - var srcLength = src.byteLength; - var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) : - new Uint32ArrayView(dest); - var dest32DataLength = dest32.length; - var fullSrcDiff = (width + 7) >> 3; - var white = 0xFFFFFFFF; - var black = (PDFJS.isLittleEndian || !PDFJS.hasCanvasTypedArrays) ? - 0xFF000000 : 0x000000FF; - for (i = 0; i < totalChunks; i++) { - thisChunkHeight = - (i < fullChunks) ? FULL_CHUNK_HEIGHT : partialChunkHeight; - destPos = 0; - for (j = 0; j < thisChunkHeight; j++) { - var srcDiff = srcLength - srcPos; - var k = 0; - var kEnd = (srcDiff > fullSrcDiff) ? width : srcDiff * 8 - 7; - var kEndUnrolled = kEnd & ~7; - var mask = 0; - var srcByte = 0; - for (; k < kEndUnrolled; k += 8) { - srcByte = src[srcPos++]; - dest32[destPos++] = (srcByte & 128) ? white : black; - dest32[destPos++] = (srcByte & 64) ? white : black; - dest32[destPos++] = (srcByte & 32) ? white : black; - dest32[destPos++] = (srcByte & 16) ? white : black; - dest32[destPos++] = (srcByte & 8) ? white : black; - dest32[destPos++] = (srcByte & 4) ? white : black; - dest32[destPos++] = (srcByte & 2) ? white : black; - dest32[destPos++] = (srcByte & 1) ? white : black; - } - for (; k < kEnd; k++) { - if (mask === 0) { - srcByte = src[srcPos++]; - mask = 128; - } - - dest32[destPos++] = (srcByte & mask) ? white : black; - mask >>= 1; - } - } - // We ran out of input. Make all remaining pixels transparent. - while (destPos < dest32DataLength) { - dest32[destPos++] = 0; - } - - ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); - } - } else if (imgData.kind === ImageKind.RGBA_32BPP) { - // RGBA, 32-bits per pixel. - - j = 0; - elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; - for (i = 0; i < fullChunks; i++) { - dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); - srcPos += elemsInThisChunk; - - ctx.putImageData(chunkImgData, 0, j); - j += FULL_CHUNK_HEIGHT; - } - if (i < totalChunks) { - elemsInThisChunk = width * partialChunkHeight * 4; - dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); - ctx.putImageData(chunkImgData, 0, j); - } - - } else if (imgData.kind === ImageKind.RGB_24BPP) { - // RGB, 24-bits per pixel. - thisChunkHeight = FULL_CHUNK_HEIGHT; - elemsInThisChunk = width * thisChunkHeight; - for (i = 0; i < totalChunks; i++) { - if (i >= fullChunks) { - thisChunkHeight = partialChunkHeight; - elemsInThisChunk = width * thisChunkHeight; - } - - destPos = 0; - for (j = elemsInThisChunk; j--;) { - dest[destPos++] = src[srcPos++]; - dest[destPos++] = src[srcPos++]; - dest[destPos++] = src[srcPos++]; - dest[destPos++] = 255; - } - ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); - } - } else { - error('bad image kind: ' + imgData.kind); - } - } - - function putBinaryImageMask(ctx, imgData) { - var height = imgData.height, width = imgData.width; - var partialChunkHeight = height % FULL_CHUNK_HEIGHT; - var fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; - var totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; - - var chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); - var srcPos = 0; - var src = imgData.data; - var dest = chunkImgData.data; - - for (var i = 0; i < totalChunks; i++) { - var thisChunkHeight = - (i < fullChunks) ? FULL_CHUNK_HEIGHT : partialChunkHeight; - - // Expand the mask so it can be used by the canvas. Any required - // inversion has already been handled. - var destPos = 3; // alpha component offset - for (var j = 0; j < thisChunkHeight; j++) { - var mask = 0; - for (var k = 0; k < width; k++) { - if (!mask) { - var elem = src[srcPos++]; - mask = 128; - } - dest[destPos] = (elem & mask) ? 0 : 255; - destPos += 4; - mask >>= 1; - } - } - ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); - } - } - - function copyCtxState(sourceCtx, destCtx) { - var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha', - 'lineWidth', 'lineCap', 'lineJoin', 'miterLimit', - 'globalCompositeOperation', 'font']; - for (var i = 0, ii = properties.length; i < ii; i++) { - var property = properties[i]; - if (sourceCtx[property] !== undefined) { - destCtx[property] = sourceCtx[property]; - } - } - if (sourceCtx.setLineDash !== undefined) { - destCtx.setLineDash(sourceCtx.getLineDash()); - destCtx.lineDashOffset = sourceCtx.lineDashOffset; - } else if (sourceCtx.mozDashOffset !== undefined) { - destCtx.mozDash = sourceCtx.mozDash; - destCtx.mozDashOffset = sourceCtx.mozDashOffset; - } - } - - function composeSMaskBackdrop(bytes, r0, g0, b0) { - var length = bytes.length; - for (var i = 3; i < length; i += 4) { - var alpha = bytes[i]; - if (alpha === 0) { - bytes[i - 3] = r0; - bytes[i - 2] = g0; - bytes[i - 1] = b0; - } else if (alpha < 255) { - var alpha_ = 255 - alpha; - bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8; - bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8; - bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8; - } - } - } - - function composeSMaskAlpha(maskData, layerData) { - var length = maskData.length; - var scale = 1 / 255; - for (var i = 3; i < length; i += 4) { - var alpha = maskData[i]; - layerData[i] = (layerData[i] * alpha * scale) | 0; - } - } - - function composeSMaskLuminosity(maskData, layerData) { - var length = maskData.length; - for (var i = 3; i < length; i += 4) { - var y = (maskData[i - 3] * 77) + // * 0.3 / 255 * 0x10000 - (maskData[i - 2] * 152) + // * 0.59 .... - (maskData[i - 1] * 28); // * 0.11 .... - layerData[i] = (layerData[i] * y) >> 16; - } - } - - function genericComposeSMask(maskCtx, layerCtx, width, height, - subtype, backdrop) { - var hasBackdrop = !!backdrop; - var r0 = hasBackdrop ? backdrop[0] : 0; - var g0 = hasBackdrop ? backdrop[1] : 0; - var b0 = hasBackdrop ? backdrop[2] : 0; - - var composeFn; - if (subtype === 'Luminosity') { - composeFn = composeSMaskLuminosity; - } else { - composeFn = composeSMaskAlpha; - } - - // processing image in chunks to save memory - var PIXELS_TO_PROCESS = 1048576; - var chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); - for (var row = 0; row < height; row += chunkSize) { - var chunkHeight = Math.min(chunkSize, height - row); - var maskData = maskCtx.getImageData(0, row, width, chunkHeight); - var layerData = layerCtx.getImageData(0, row, width, chunkHeight); - - if (hasBackdrop) { - composeSMaskBackdrop(maskData.data, r0, g0, b0); - } - composeFn(maskData.data, layerData.data); - - maskCtx.putImageData(layerData, 0, row); - } - } - - function composeSMask(ctx, smask, layerCtx) { - var mask = smask.canvas; - var maskCtx = smask.context; - - ctx.setTransform(smask.scaleX, 0, 0, smask.scaleY, - smask.offsetX, smask.offsetY); - - var backdrop = smask.backdrop || null; - if (WebGLUtils.isEnabled) { - var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, - {subtype: smask.subtype, backdrop: backdrop}); - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.drawImage(composed, smask.offsetX, smask.offsetY); - return; - } - genericComposeSMask(maskCtx, layerCtx, mask.width, mask.height, - smask.subtype, backdrop); - ctx.drawImage(mask, 0, 0); - } - - var LINE_CAP_STYLES = ['butt', 'round', 'square']; - var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; - var NORMAL_CLIP = {}; - var EO_CLIP = {}; - - CanvasGraphics.prototype = { - - beginDrawing: function CanvasGraphics_beginDrawing(viewport, transparency) { - // For pdfs that use blend modes we have to clear the canvas else certain - // blend modes can look wrong since we'd be blending with a white - // backdrop. The problem with a transparent backdrop though is we then - // don't get sub pixel anti aliasing on text, so we fill with white if - // we can. - var width = this.ctx.canvas.width; - var height = this.ctx.canvas.height; - if (transparency) { - this.ctx.clearRect(0, 0, width, height); - } else { - this.ctx.mozOpaque = true; - this.ctx.save(); - this.ctx.fillStyle = 'rgb(255, 255, 255)'; - this.ctx.fillRect(0, 0, width, height); - this.ctx.restore(); - } - - var transform = viewport.transform; - - this.ctx.save(); - this.ctx.transform.apply(this.ctx, transform); - - this.baseTransform = this.ctx.mozCurrentTransform.slice(); - - if (this.imageLayer) { - this.imageLayer.beginLayout(); - } - }, - - executeOperatorList: function CanvasGraphics_executeOperatorList( - operatorList, - executionStartIdx, continueCallback, - stepper) { - var argsArray = operatorList.argsArray; - var fnArray = operatorList.fnArray; - var i = executionStartIdx || 0; - var argsArrayLen = argsArray.length; - - // Sometimes the OperatorList to execute is empty. - if (argsArrayLen === i) { - return i; - } - - var chunkOperations = (argsArrayLen - i > EXECUTION_STEPS && - typeof continueCallback === 'function'); - var endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; - var steps = 0; - - var commonObjs = this.commonObjs; - var objs = this.objs; - var fnId; - - while (true) { - if (stepper !== undefined && i === stepper.nextBreakPoint) { - stepper.breakIt(i, continueCallback); - return i; - } - - fnId = fnArray[i]; - - if (fnId !== OPS.dependency) { - this[fnId].apply(this, argsArray[i]); - } else { - var deps = argsArray[i]; - for (var n = 0, nn = deps.length; n < nn; n++) { - var depObjId = deps[n]; - var common = depObjId[0] === 'g' && depObjId[1] === '_'; - var objsPool = common ? commonObjs : objs; - - // If the promise isn't resolved yet, add the continueCallback - // to the promise and bail out. - if (!objsPool.isResolved(depObjId)) { - objsPool.get(depObjId, continueCallback); - return i; - } - } - } - - i++; - - // If the entire operatorList was executed, stop as were done. - if (i === argsArrayLen) { - return i; - } - - // If the execution took longer then a certain amount of time and - // `continueCallback` is specified, interrupt the execution. - if (chunkOperations && ++steps > EXECUTION_STEPS) { - if (Date.now() > endTime) { - continueCallback(); - return i; - } - steps = 0; - } - - // If the operatorList isn't executed completely yet OR the execution - // time was short enough, do another execution round. - } - }, - - endDrawing: function CanvasGraphics_endDrawing() { - this.ctx.restore(); - CachedCanvases.clear(); - WebGLUtils.clear(); - - if (this.imageLayer) { - this.imageLayer.endLayout(); - } - }, - - // Graphics state - setLineWidth: function CanvasGraphics_setLineWidth(width) { - this.current.lineWidth = width; - this.ctx.lineWidth = width; - }, - setLineCap: function CanvasGraphics_setLineCap(style) { - this.ctx.lineCap = LINE_CAP_STYLES[style]; - }, - setLineJoin: function CanvasGraphics_setLineJoin(style) { - this.ctx.lineJoin = LINE_JOIN_STYLES[style]; - }, - setMiterLimit: function CanvasGraphics_setMiterLimit(limit) { - this.ctx.miterLimit = limit; - }, - setDash: function CanvasGraphics_setDash(dashArray, dashPhase) { - var ctx = this.ctx; - if (ctx.setLineDash !== undefined) { - ctx.setLineDash(dashArray); - ctx.lineDashOffset = dashPhase; - } else { - ctx.mozDash = dashArray; - ctx.mozDashOffset = dashPhase; - } - }, - setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) { - // Maybe if we one day fully support color spaces this will be important - // for now we can ignore. - // TODO set rendering intent? - }, - setFlatness: function CanvasGraphics_setFlatness(flatness) { - // There's no way to control this with canvas, but we can safely ignore. - // TODO set flatness? - }, - setGState: function CanvasGraphics_setGState(states) { - for (var i = 0, ii = states.length; i < ii; i++) { - var state = states[i]; - var key = state[0]; - var value = state[1]; - - switch (key) { - case 'LW': - this.setLineWidth(value); - break; - case 'LC': - this.setLineCap(value); - break; - case 'LJ': - this.setLineJoin(value); - break; - case 'ML': - this.setMiterLimit(value); - break; - case 'D': - this.setDash(value[0], value[1]); - break; - case 'RI': - this.setRenderingIntent(value); - break; - case 'FL': - this.setFlatness(value); - break; - case 'Font': - this.setFont(value[0], value[1]); - break; - case 'CA': - this.current.strokeAlpha = state[1]; - break; - case 'ca': - this.current.fillAlpha = state[1]; - this.ctx.globalAlpha = state[1]; - break; - case 'BM': - if (value && value.name && (value.name !== 'Normal')) { - var mode = value.name.replace(/([A-Z])/g, - function(c) { - return '-' + c.toLowerCase(); - } - ).substring(1); - this.ctx.globalCompositeOperation = mode; - if (this.ctx.globalCompositeOperation !== mode) { - warn('globalCompositeOperation "' + mode + - '" is not supported'); - } - } else { - this.ctx.globalCompositeOperation = 'source-over'; - } - break; - case 'SMask': - if (this.current.activeSMask) { - this.endSMaskGroup(); - } - this.current.activeSMask = value ? this.tempSMask : null; - if (this.current.activeSMask) { - this.beginSMaskGroup(); - } - this.tempSMask = null; - break; - } - } - }, - beginSMaskGroup: function CanvasGraphics_beginSMaskGroup() { - - var activeSMask = this.current.activeSMask; - var drawnWidth = activeSMask.canvas.width; - var drawnHeight = activeSMask.canvas.height; - var cacheId = 'smaskGroupAt' + this.groupLevel; - var scratchCanvas = CachedCanvases.getCanvas( - cacheId, drawnWidth, drawnHeight, true); - - var currentCtx = this.ctx; - var currentTransform = currentCtx.mozCurrentTransform; - this.ctx.save(); - - var groupCtx = scratchCanvas.context; - groupCtx.scale(1 / activeSMask.scaleX, 1 / activeSMask.scaleY); - groupCtx.translate(-activeSMask.offsetX, -activeSMask.offsetY); - groupCtx.transform.apply(groupCtx, currentTransform); - - copyCtxState(currentCtx, groupCtx); - this.ctx = groupCtx; - this.setGState([ - ['BM', 'Normal'], - ['ca', 1], - ['CA', 1] - ]); - this.groupStack.push(currentCtx); - this.groupLevel++; - }, - endSMaskGroup: function CanvasGraphics_endSMaskGroup() { - var groupCtx = this.ctx; - this.groupLevel--; - this.ctx = this.groupStack.pop(); - - composeSMask(this.ctx, this.current.activeSMask, groupCtx); - this.ctx.restore(); - }, - save: function CanvasGraphics_save() { - this.ctx.save(); - var old = this.current; - this.stateStack.push(old); - this.current = old.clone(); - this.current.activeSMask = null; - }, - restore: function CanvasGraphics_restore() { - if (this.stateStack.length !== 0) { - if (this.current.activeSMask !== null) { - this.endSMaskGroup(); - } - - this.current = this.stateStack.pop(); - this.ctx.restore(); - - this.cachedGetSinglePixelWidth = null; - } - }, - transform: function CanvasGraphics_transform(a, b, c, d, e, f) { - this.ctx.transform(a, b, c, d, e, f); - - this.cachedGetSinglePixelWidth = null; - }, - - // Path - constructPath: function CanvasGraphics_constructPath(ops, args) { - var ctx = this.ctx; - var current = this.current; - var x = current.x, y = current.y; - for (var i = 0, j = 0, ii = ops.length; i < ii; i++) { - switch (ops[i] | 0) { - case OPS.rectangle: - x = args[j++]; - y = args[j++]; - var width = args[j++]; - var height = args[j++]; - if (width === 0) { - width = this.getSinglePixelWidth(); - } - if (height === 0) { - height = this.getSinglePixelWidth(); - } - var xw = x + width; - var yh = y + height; - this.ctx.moveTo(x, y); - this.ctx.lineTo(xw, y); - this.ctx.lineTo(xw, yh); - this.ctx.lineTo(x, yh); - this.ctx.lineTo(x, y); - this.ctx.closePath(); - break; - case OPS.moveTo: - x = args[j++]; - y = args[j++]; - ctx.moveTo(x, y); - break; - case OPS.lineTo: - x = args[j++]; - y = args[j++]; - ctx.lineTo(x, y); - break; - case OPS.curveTo: - x = args[j + 4]; - y = args[j + 5]; - ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], - x, y); - j += 6; - break; - case OPS.curveTo2: - ctx.bezierCurveTo(x, y, args[j], args[j + 1], - args[j + 2], args[j + 3]); - x = args[j + 2]; - y = args[j + 3]; - j += 4; - break; - case OPS.curveTo3: - x = args[j + 2]; - y = args[j + 3]; - ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); - j += 4; - break; - case OPS.closePath: - ctx.closePath(); - break; - } - } - current.setCurrentPoint(x, y); - }, - closePath: function CanvasGraphics_closePath() { - this.ctx.closePath(); - }, - stroke: function CanvasGraphics_stroke(consumePath) { - consumePath = typeof consumePath !== 'undefined' ? consumePath : true; - var ctx = this.ctx; - var strokeColor = this.current.strokeColor; - // Prevent drawing too thin lines by enforcing a minimum line width. - ctx.lineWidth = Math.max(this.getSinglePixelWidth() * MIN_WIDTH_FACTOR, - this.current.lineWidth); - // For stroke we want to temporarily change the global alpha to the - // stroking alpha. - ctx.globalAlpha = this.current.strokeAlpha; - if (strokeColor && strokeColor.hasOwnProperty('type') && - strokeColor.type === 'Pattern') { - // for patterns, we transform to pattern space, calculate - // the pattern, call stroke, and restore to user space - ctx.save(); - ctx.strokeStyle = strokeColor.getPattern(ctx, this); - ctx.stroke(); - ctx.restore(); - } else { - ctx.stroke(); - } - if (consumePath) { - this.consumePath(); - } - // Restore the global alpha to the fill alpha - ctx.globalAlpha = this.current.fillAlpha; - }, - closeStroke: function CanvasGraphics_closeStroke() { - this.closePath(); - this.stroke(); - }, - fill: function CanvasGraphics_fill(consumePath) { - consumePath = typeof consumePath !== 'undefined' ? consumePath : true; - var ctx = this.ctx; - var fillColor = this.current.fillColor; - var isPatternFill = this.current.patternFill; - var needRestore = false; - - if (isPatternFill) { - ctx.save(); - ctx.fillStyle = fillColor.getPattern(ctx, this); - needRestore = true; - } - - if (this.pendingEOFill) { - if (ctx.mozFillRule !== undefined) { - ctx.mozFillRule = 'evenodd'; - ctx.fill(); - ctx.mozFillRule = 'nonzero'; - } else { - try { - ctx.fill('evenodd'); - } catch (ex) { - // shouldn't really happen, but browsers might think differently - ctx.fill(); - } - } - this.pendingEOFill = false; - } else { - ctx.fill(); - } - - if (needRestore) { - ctx.restore(); - } - if (consumePath) { - this.consumePath(); - } - }, - eoFill: function CanvasGraphics_eoFill() { - this.pendingEOFill = true; - this.fill(); - }, - fillStroke: function CanvasGraphics_fillStroke() { - this.fill(false); - this.stroke(false); - - this.consumePath(); - }, - eoFillStroke: function CanvasGraphics_eoFillStroke() { - this.pendingEOFill = true; - this.fillStroke(); - }, - closeFillStroke: function CanvasGraphics_closeFillStroke() { - this.closePath(); - this.fillStroke(); - }, - closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() { - this.pendingEOFill = true; - this.closePath(); - this.fillStroke(); - }, - endPath: function CanvasGraphics_endPath() { - this.consumePath(); - }, - - // Clipping - clip: function CanvasGraphics_clip() { - this.pendingClip = NORMAL_CLIP; - }, - eoClip: function CanvasGraphics_eoClip() { - this.pendingClip = EO_CLIP; - }, - - // Text - beginText: function CanvasGraphics_beginText() { - this.current.textMatrix = IDENTITY_MATRIX; - this.current.textMatrixScale = 1; - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; - }, - endText: function CanvasGraphics_endText() { - var paths = this.pendingTextPaths; - var ctx = this.ctx; - if (paths === undefined) { - ctx.beginPath(); - return; - } - - ctx.save(); - ctx.beginPath(); - for (var i = 0; i < paths.length; i++) { - var path = paths[i]; - ctx.setTransform.apply(ctx, path.transform); - ctx.translate(path.x, path.y); - path.addToPath(ctx, path.fontSize); - } - ctx.restore(); - ctx.clip(); - ctx.beginPath(); - delete this.pendingTextPaths; - }, - setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) { - this.current.charSpacing = spacing; - }, - setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) { - this.current.wordSpacing = spacing; - }, - setHScale: function CanvasGraphics_setHScale(scale) { - this.current.textHScale = scale / 100; - }, - setLeading: function CanvasGraphics_setLeading(leading) { - this.current.leading = -leading; - }, - setFont: function CanvasGraphics_setFont(fontRefName, size) { - var fontObj = this.commonObjs.get(fontRefName); - var current = this.current; - - if (!fontObj) { - error('Can\'t find font for ' + fontRefName); - } - - current.fontMatrix = (fontObj.fontMatrix ? - fontObj.fontMatrix : FONT_IDENTITY_MATRIX); - - // A valid matrix needs all main diagonal elements to be non-zero - // This also ensures we bypass FF bugzilla bug #719844. - if (current.fontMatrix[0] === 0 || - current.fontMatrix[3] === 0) { - warn('Invalid font matrix for font ' + fontRefName); - } - - // The spec for Tf (setFont) says that 'size' specifies the font 'scale', - // and in some docs this can be negative (inverted x-y axes). - if (size < 0) { - size = -size; - current.fontDirection = -1; - } else { - current.fontDirection = 1; - } - - this.current.font = fontObj; - this.current.fontSize = size; - - if (fontObj.isType3Font) { - return; // we don't need ctx.font for Type3 fonts - } - - var name = fontObj.loadedName || 'sans-serif'; - var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') : - (fontObj.bold ? 'bold' : 'normal'); - - var italic = fontObj.italic ? 'italic' : 'normal'; - var typeface = '"' + name + '", ' + fontObj.fallbackName; - - // Some font backends cannot handle fonts below certain size. - // Keeping the font at minimal size and using the fontSizeScale to change - // the current transformation matrix before the fillText/strokeText. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=726227 - var browserFontSize = size < MIN_FONT_SIZE ? MIN_FONT_SIZE : - size > MAX_FONT_SIZE ? MAX_FONT_SIZE : size; - this.current.fontSizeScale = size / browserFontSize; - - var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface; - this.ctx.font = rule; - }, - setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) { - this.current.textRenderingMode = mode; - }, - setTextRise: function CanvasGraphics_setTextRise(rise) { - this.current.textRise = rise; - }, - moveText: function CanvasGraphics_moveText(x, y) { - this.current.x = this.current.lineX += x; - this.current.y = this.current.lineY += y; - }, - setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) { - this.setLeading(-y); - this.moveText(x, y); - }, - setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { - this.current.textMatrix = [a, b, c, d, e, f]; - this.current.textMatrixScale = Math.sqrt(a * a + b * b); - - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; - }, - nextLine: function CanvasGraphics_nextLine() { - this.moveText(0, this.current.leading); - }, - - paintChar: function CanvasGraphics_paintChar(character, x, y) { - var ctx = this.ctx; - var current = this.current; - var font = current.font; - var textRenderingMode = current.textRenderingMode; - var fontSize = current.fontSize / current.fontSizeScale; - var fillStrokeMode = textRenderingMode & - TextRenderingMode.FILL_STROKE_MASK; - var isAddToPathSet = !!(textRenderingMode & - TextRenderingMode.ADD_TO_PATH_FLAG); - - var addToPath; - if (font.disableFontFace || isAddToPathSet) { - addToPath = font.getPathGenerator(this.commonObjs, character); - } - - if (font.disableFontFace) { - ctx.save(); - ctx.translate(x, y); - ctx.beginPath(); - addToPath(ctx, fontSize); - if (fillStrokeMode === TextRenderingMode.FILL || - fillStrokeMode === TextRenderingMode.FILL_STROKE) { - ctx.fill(); - } - if (fillStrokeMode === TextRenderingMode.STROKE || - fillStrokeMode === TextRenderingMode.FILL_STROKE) { - ctx.stroke(); - } - ctx.restore(); - } else { - if (fillStrokeMode === TextRenderingMode.FILL || - fillStrokeMode === TextRenderingMode.FILL_STROKE) { - ctx.fillText(character, x, y); - } - if (fillStrokeMode === TextRenderingMode.STROKE || - fillStrokeMode === TextRenderingMode.FILL_STROKE) { - ctx.strokeText(character, x, y); - } - } - - if (isAddToPathSet) { - var paths = this.pendingTextPaths || (this.pendingTextPaths = []); - paths.push({ - transform: ctx.mozCurrentTransform, - x: x, - y: y, - fontSize: fontSize, - addToPath: addToPath - }); - } - }, - - get isFontSubpixelAAEnabled() { - // Checks if anti-aliasing is enabled when scaled text is painted. - // On Windows GDI scaled fonts looks bad. - var ctx = document.createElement('canvas').getContext('2d'); - ctx.scale(1.5, 1); - ctx.fillText('I', 0, 10); - var data = ctx.getImageData(0, 0, 10, 10).data; - var enabled = false; - for (var i = 3; i < data.length; i += 4) { - if (data[i] > 0 && data[i] < 255) { - enabled = true; - break; - } - } - return shadow(this, 'isFontSubpixelAAEnabled', enabled); - }, - - showText: function CanvasGraphics_showText(glyphs) { - var current = this.current; - var font = current.font; - if (font.isType3Font) { - return this.showType3Text(glyphs); - } - - var fontSize = current.fontSize; - if (fontSize === 0) { - return; - } - - var ctx = this.ctx; - var fontSizeScale = current.fontSizeScale; - var charSpacing = current.charSpacing; - var wordSpacing = current.wordSpacing; - var fontDirection = current.fontDirection; - var textHScale = current.textHScale * fontDirection; - var glyphsLength = glyphs.length; - var vertical = font.vertical; - var defaultVMetrics = font.defaultVMetrics; - var widthAdvanceScale = fontSize * current.fontMatrix[0]; - - var simpleFillText = - current.textRenderingMode === TextRenderingMode.FILL && - !font.disableFontFace; - - ctx.save(); - ctx.transform.apply(ctx, current.textMatrix); - ctx.translate(current.x, current.y + current.textRise); - - if (fontDirection > 0) { - ctx.scale(textHScale, -1); - } else { - ctx.scale(textHScale, 1); - } - - var lineWidth = current.lineWidth; - var scale = current.textMatrixScale; - if (scale === 0 || lineWidth === 0) { - var fillStrokeMode = current.textRenderingMode & - TextRenderingMode.FILL_STROKE_MASK; - if (fillStrokeMode === TextRenderingMode.STROKE || - fillStrokeMode === TextRenderingMode.FILL_STROKE) { - this.cachedGetSinglePixelWidth = null; - lineWidth = this.getSinglePixelWidth() * MIN_WIDTH_FACTOR; - } - } else { - lineWidth /= scale; - } - - if (fontSizeScale !== 1.0) { - ctx.scale(fontSizeScale, fontSizeScale); - lineWidth /= fontSizeScale; - } - - ctx.lineWidth = lineWidth; - - var x = 0, i; - for (i = 0; i < glyphsLength; ++i) { - var glyph = glyphs[i]; - if (glyph === null) { - // word break - x += fontDirection * wordSpacing; - continue; - } else if (isNum(glyph)) { - x += -glyph * fontSize * 0.001; - continue; - } - - var restoreNeeded = false; - var character = glyph.fontChar; - var accent = glyph.accent; - var scaledX, scaledY, scaledAccentX, scaledAccentY; - var width = glyph.width; - if (vertical) { - var vmetric, vx, vy; - vmetric = glyph.vmetric || defaultVMetrics; - vx = glyph.vmetric ? vmetric[1] : width * 0.5; - vx = -vx * widthAdvanceScale; - vy = vmetric[2] * widthAdvanceScale; - - width = vmetric ? -vmetric[0] : width; - scaledX = vx / fontSizeScale; - scaledY = (x + vy) / fontSizeScale; - } else { - scaledX = x / fontSizeScale; - scaledY = 0; - } - - if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) { - // some standard fonts may not have the exact width, trying to - // rescale per character - var measuredWidth = ctx.measureText(character).width * 1000 / - fontSize * fontSizeScale; - var characterScaleX = width / measuredWidth; - restoreNeeded = true; - ctx.save(); - ctx.scale(characterScaleX, 1); - scaledX /= characterScaleX; - } - - if (simpleFillText && !accent) { - // common case - ctx.fillText(character, scaledX, scaledY); - } else { - this.paintChar(character, scaledX, scaledY); - if (accent) { - scaledAccentX = scaledX + accent.offset.x / fontSizeScale; - scaledAccentY = scaledY - accent.offset.y / fontSizeScale; - this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY); - } - } - - var charWidth = width * widthAdvanceScale + charSpacing * fontDirection; - x += charWidth; - - if (restoreNeeded) { - ctx.restore(); - } - } - if (vertical) { - current.y -= x * textHScale; - } else { - current.x += x * textHScale; - } - ctx.restore(); - }, - - showType3Text: function CanvasGraphics_showType3Text(glyphs) { - // Type3 fonts - each glyph is a "mini-PDF" - var ctx = this.ctx; - var current = this.current; - var font = current.font; - var fontSize = current.fontSize; - var fontDirection = current.fontDirection; - var charSpacing = current.charSpacing; - var wordSpacing = current.wordSpacing; - var textHScale = current.textHScale * fontDirection; - var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX; - var glyphsLength = glyphs.length; - var isTextInvisible = - current.textRenderingMode === TextRenderingMode.INVISIBLE; - var i, glyph, width; - - if (isTextInvisible || fontSize === 0) { - return; - } - - ctx.save(); - ctx.transform.apply(ctx, current.textMatrix); - ctx.translate(current.x, current.y); - - ctx.scale(textHScale, fontDirection); - - for (i = 0; i < glyphsLength; ++i) { - glyph = glyphs[i]; - if (glyph === null) { - // word break - this.ctx.translate(wordSpacing, 0); - current.x += wordSpacing * textHScale; - continue; - } else if (isNum(glyph)) { - var spacingLength = -glyph * 0.001 * fontSize; - this.ctx.translate(spacingLength, 0); - current.x += spacingLength * textHScale; - continue; - } - - var operatorList = font.charProcOperatorList[glyph.operatorListId]; - if (!operatorList) { - warn('Type3 character \"' + glyph.operatorListId + - '\" is not available'); - continue; - } - this.processingType3 = glyph; - this.save(); - ctx.scale(fontSize, fontSize); - ctx.transform.apply(ctx, fontMatrix); - this.executeOperatorList(operatorList); - this.restore(); - - var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); - width = transformed[0] * fontSize + charSpacing; - - ctx.translate(width, 0); - current.x += width * textHScale; - } - ctx.restore(); - this.processingType3 = null; - }, - - // Type3 fonts - setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { - // We can safely ignore this since the width should be the same - // as the width in the Widths array. - }, - setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth, - yWidth, - llx, - lly, - urx, - ury) { - // TODO According to the spec we're also suppose to ignore any operators - // that set color or include images while processing this type3 font. - this.ctx.rect(llx, lly, urx - llx, ury - lly); - this.clip(); - this.endPath(); - }, - - // Color - getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR) { - var pattern; - if (IR[0] === 'TilingPattern') { - var color = IR[1]; - pattern = new TilingPattern(IR, color, this.ctx, this.objs, - this.commonObjs, this.baseTransform); - } else { - pattern = getShadingPatternFromIR(IR); - } - return pattern; - }, - setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { - this.current.strokeColor = this.getColorN_Pattern(arguments); - }, - setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { - this.current.fillColor = this.getColorN_Pattern(arguments); - this.current.patternFill = true; - }, - setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { - var color = Util.makeCssRgb(r, g, b); - this.ctx.strokeStyle = color; - this.current.strokeColor = color; - }, - setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { - var color = Util.makeCssRgb(r, g, b); - this.ctx.fillStyle = color; - this.current.fillColor = color; - this.current.patternFill = false; - }, - - shadingFill: function CanvasGraphics_shadingFill(patternIR) { - var ctx = this.ctx; - - this.save(); - var pattern = getShadingPatternFromIR(patternIR); - ctx.fillStyle = pattern.getPattern(ctx, this, true); - - var inv = ctx.mozCurrentTransformInverse; - if (inv) { - var canvas = ctx.canvas; - var width = canvas.width; - var height = canvas.height; - - var bl = Util.applyTransform([0, 0], inv); - var br = Util.applyTransform([0, height], inv); - var ul = Util.applyTransform([width, 0], inv); - var ur = Util.applyTransform([width, height], inv); - - var x0 = Math.min(bl[0], br[0], ul[0], ur[0]); - var y0 = Math.min(bl[1], br[1], ul[1], ur[1]); - var x1 = Math.max(bl[0], br[0], ul[0], ur[0]); - var y1 = Math.max(bl[1], br[1], ul[1], ur[1]); - - this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); - } else { - // HACK to draw the gradient onto an infinite rectangle. - // PDF gradients are drawn across the entire image while - // Canvas only allows gradients to be drawn in a rectangle - // The following bug should allow us to remove this. - // https://bugzilla.mozilla.org/show_bug.cgi?id=664884 - - this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); - } - - this.restore(); - }, - - // Images - beginInlineImage: function CanvasGraphics_beginInlineImage() { - error('Should not call beginInlineImage'); - }, - beginImageData: function CanvasGraphics_beginImageData() { - error('Should not call beginImageData'); - }, - - paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, - bbox) { - this.save(); - this.baseTransformStack.push(this.baseTransform); - - if (isArray(matrix) && 6 === matrix.length) { - this.transform.apply(this, matrix); - } - - this.baseTransform = this.ctx.mozCurrentTransform; - - if (isArray(bbox) && 4 === bbox.length) { - var width = bbox[2] - bbox[0]; - var height = bbox[3] - bbox[1]; - this.ctx.rect(bbox[0], bbox[1], width, height); - this.clip(); - this.endPath(); - } - }, - - paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { - this.restore(); - this.baseTransform = this.baseTransformStack.pop(); - }, - - beginGroup: function CanvasGraphics_beginGroup(group) { - this.save(); - var currentCtx = this.ctx; - // TODO non-isolated groups - according to Rik at adobe non-isolated - // group results aren't usually that different and they even have tools - // that ignore this setting. Notes from Rik on implmenting: - // - When you encounter an transparency group, create a new canvas with - // the dimensions of the bbox - // - copy the content from the previous canvas to the new canvas - // - draw as usual - // - remove the backdrop alpha: - // alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha - // value of your transparency group and 'alphaBackdrop' the alpha of the - // backdrop - // - remove background color: - // colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew) - if (!group.isolated) { - info('TODO: Support non-isolated groups.'); - } - - // TODO knockout - supposedly possible with the clever use of compositing - // modes. - if (group.knockout) { - warn('Knockout groups not supported.'); - } - - var currentTransform = currentCtx.mozCurrentTransform; - if (group.matrix) { - currentCtx.transform.apply(currentCtx, group.matrix); - } - assert(group.bbox, 'Bounding box is required.'); - - // Based on the current transform figure out how big the bounding box - // will actually be. - var bounds = Util.getAxialAlignedBoundingBox( - group.bbox, - currentCtx.mozCurrentTransform); - // Clip the bounding box to the current canvas. - var canvasBounds = [0, - 0, - currentCtx.canvas.width, - currentCtx.canvas.height]; - bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; - // Use ceil in case we're between sizes so we don't create canvas that is - // too small and make the canvas at least 1x1 pixels. - var offsetX = Math.floor(bounds[0]); - var offsetY = Math.floor(bounds[1]); - var drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); - var drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); - var scaleX = 1, scaleY = 1; - if (drawnWidth > MAX_GROUP_SIZE) { - scaleX = drawnWidth / MAX_GROUP_SIZE; - drawnWidth = MAX_GROUP_SIZE; - } - if (drawnHeight > MAX_GROUP_SIZE) { - scaleY = drawnHeight / MAX_GROUP_SIZE; - drawnHeight = MAX_GROUP_SIZE; - } - - var cacheId = 'groupAt' + this.groupLevel; - if (group.smask) { - // Using two cache entries is case if masks are used one after another. - cacheId += '_smask_' + ((this.smaskCounter++) % 2); - } - var scratchCanvas = CachedCanvases.getCanvas( - cacheId, drawnWidth, drawnHeight, true); - var groupCtx = scratchCanvas.context; - - // Since we created a new canvas that is just the size of the bounding box - // we have to translate the group ctx. - groupCtx.scale(1 / scaleX, 1 / scaleY); - groupCtx.translate(-offsetX, -offsetY); - groupCtx.transform.apply(groupCtx, currentTransform); - - if (group.smask) { - // Saving state and cached mask to be used in setGState. - this.smaskStack.push({ - canvas: scratchCanvas.canvas, - context: groupCtx, - offsetX: offsetX, - offsetY: offsetY, - scaleX: scaleX, - scaleY: scaleY, - subtype: group.smask.subtype, - backdrop: group.smask.backdrop - }); - } else { - // Setup the current ctx so when the group is popped we draw it at the - // right location. - currentCtx.setTransform(1, 0, 0, 1, 0, 0); - currentCtx.translate(offsetX, offsetY); - currentCtx.scale(scaleX, scaleY); - } - // The transparency group inherits all off the current graphics state - // except the blend mode, soft mask, and alpha constants. - copyCtxState(currentCtx, groupCtx); - this.ctx = groupCtx; - this.setGState([ - ['BM', 'Normal'], - ['ca', 1], - ['CA', 1] - ]); - this.groupStack.push(currentCtx); - this.groupLevel++; - }, - - endGroup: function CanvasGraphics_endGroup(group) { - this.groupLevel--; - var groupCtx = this.ctx; - this.ctx = this.groupStack.pop(); - // Turn off image smoothing to avoid sub pixel interpolation which can - // look kind of blurry for some pdfs. - if (this.ctx.imageSmoothingEnabled !== undefined) { - this.ctx.imageSmoothingEnabled = false; - } else { - this.ctx.mozImageSmoothingEnabled = false; - } - if (group.smask) { - this.tempSMask = this.smaskStack.pop(); - } else { - this.ctx.drawImage(groupCtx.canvas, 0, 0); - } - this.restore(); - }, - - beginAnnotations: function CanvasGraphics_beginAnnotations() { - this.save(); - this.current = new CanvasExtraState(); - }, - - endAnnotations: function CanvasGraphics_endAnnotations() { - this.restore(); - }, - - beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform, - matrix) { - this.save(); - - if (isArray(rect) && 4 === rect.length) { - var width = rect[2] - rect[0]; - var height = rect[3] - rect[1]; - this.ctx.rect(rect[0], rect[1], width, height); - this.clip(); - this.endPath(); - } - - this.transform.apply(this, transform); - this.transform.apply(this, matrix); - }, - - endAnnotation: function CanvasGraphics_endAnnotation() { - this.restore(); - }, - - paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) { - var domImage = this.objs.get(objId); - if (!domImage) { - warn('Dependent image isn\'t ready yet'); - return; - } - - this.save(); - - var ctx = this.ctx; - // scale the image to the unit square - ctx.scale(1 / w, -1 / h); - - ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, - 0, -h, w, h); - if (this.imageLayer) { - var currentTransform = ctx.mozCurrentTransformInverse; - var position = this.getCanvasPosition(0, 0); - this.imageLayer.appendImage({ - objId: objId, - left: position[0], - top: position[1], - width: w / currentTransform[0], - height: h / currentTransform[3] - }); - } - this.restore(); - }, - - paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(img) { - var ctx = this.ctx; - var width = img.width, height = img.height; - var fillColor = this.current.fillColor; - var isPatternFill = this.current.patternFill; - - var glyph = this.processingType3; - - if (COMPILE_TYPE3_GLYPHS && glyph && glyph.compiled === undefined) { - if (width <= MAX_SIZE_TO_COMPILE && height <= MAX_SIZE_TO_COMPILE) { - glyph.compiled = - compileType3Glyph({data: img.data, width: width, height: height}); - } else { - glyph.compiled = null; - } - } - - if (glyph && glyph.compiled) { - glyph.compiled(ctx); - return; - } - - var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height); - var maskCtx = maskCanvas.context; - maskCtx.save(); - - putBinaryImageMask(maskCtx, img); - - maskCtx.globalCompositeOperation = 'source-in'; - - maskCtx.fillStyle = isPatternFill ? - fillColor.getPattern(maskCtx, this) : fillColor; - maskCtx.fillRect(0, 0, width, height); - - maskCtx.restore(); - - this.paintInlineImageXObject(maskCanvas.canvas); - }, - - paintImageMaskXObjectRepeat: - function CanvasGraphics_paintImageMaskXObjectRepeat(imgData, scaleX, - scaleY, positions) { - var width = imgData.width; - var height = imgData.height; - var fillColor = this.current.fillColor; - var isPatternFill = this.current.patternFill; - - var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height); - var maskCtx = maskCanvas.context; - maskCtx.save(); - - putBinaryImageMask(maskCtx, imgData); - - maskCtx.globalCompositeOperation = 'source-in'; - - maskCtx.fillStyle = isPatternFill ? - fillColor.getPattern(maskCtx, this) : fillColor; - maskCtx.fillRect(0, 0, width, height); - - maskCtx.restore(); - - var ctx = this.ctx; - for (var i = 0, ii = positions.length; i < ii; i += 2) { - ctx.save(); - ctx.transform(scaleX, 0, 0, scaleY, positions[i], positions[i + 1]); - ctx.scale(1, -1); - ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, - 0, -1, 1, 1); - ctx.restore(); - } - }, - - paintImageMaskXObjectGroup: - function CanvasGraphics_paintImageMaskXObjectGroup(images) { - var ctx = this.ctx; - - var fillColor = this.current.fillColor; - var isPatternFill = this.current.patternFill; - for (var i = 0, ii = images.length; i < ii; i++) { - var image = images[i]; - var width = image.width, height = image.height; - - var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height); - var maskCtx = maskCanvas.context; - maskCtx.save(); - - putBinaryImageMask(maskCtx, image); - - maskCtx.globalCompositeOperation = 'source-in'; - - maskCtx.fillStyle = isPatternFill ? - fillColor.getPattern(maskCtx, this) : fillColor; - maskCtx.fillRect(0, 0, width, height); - - maskCtx.restore(); - - ctx.save(); - ctx.transform.apply(ctx, image.transform); - ctx.scale(1, -1); - ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, - 0, -1, 1, 1); - ctx.restore(); - } - }, - - paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { - var imgData = this.objs.get(objId); - if (!imgData) { - warn('Dependent image isn\'t ready yet'); - return; - } - - this.paintInlineImageXObject(imgData); - }, - - paintImageXObjectRepeat: - function CanvasGraphics_paintImageXObjectRepeat(objId, scaleX, scaleY, - positions) { - var imgData = this.objs.get(objId); - if (!imgData) { - warn('Dependent image isn\'t ready yet'); - return; - } - - var width = imgData.width; - var height = imgData.height; - var map = []; - for (var i = 0, ii = positions.length; i < ii; i += 2) { - map.push({transform: [scaleX, 0, 0, scaleY, positions[i], - positions[i + 1]], x: 0, y: 0, w: width, h: height}); - } - this.paintInlineImageXObjectGroup(imgData, map); - }, - - paintInlineImageXObject: - function CanvasGraphics_paintInlineImageXObject(imgData) { - var width = imgData.width; - var height = imgData.height; - var ctx = this.ctx; - - this.save(); - // scale the image to the unit square - ctx.scale(1 / width, -1 / height); - - var currentTransform = ctx.mozCurrentTransformInverse; - var a = currentTransform[0], b = currentTransform[1]; - var widthScale = Math.max(Math.sqrt(a * a + b * b), 1); - var c = currentTransform[2], d = currentTransform[3]; - var heightScale = Math.max(Math.sqrt(c * c + d * d), 1); - - var imgToPaint, tmpCanvas; - // instanceof HTMLElement does not work in jsdom node.js module - if (imgData instanceof HTMLElement || !imgData.data) { - imgToPaint = imgData; - } else { - tmpCanvas = CachedCanvases.getCanvas('inlineImage', width, height); - var tmpCtx = tmpCanvas.context; - putBinaryImageData(tmpCtx, imgData); - imgToPaint = tmpCanvas.canvas; - } - - var paintWidth = width, paintHeight = height; - var tmpCanvasId = 'prescale1'; - // Vertial or horizontal scaling shall not be more than 2 to not loose the - // pixels during drawImage operation, painting on the temporary canvas(es) - // that are twice smaller in size - while ((widthScale > 2 && paintWidth > 1) || - (heightScale > 2 && paintHeight > 1)) { - var newWidth = paintWidth, newHeight = paintHeight; - if (widthScale > 2 && paintWidth > 1) { - newWidth = Math.ceil(paintWidth / 2); - widthScale /= paintWidth / newWidth; - } - if (heightScale > 2 && paintHeight > 1) { - newHeight = Math.ceil(paintHeight / 2); - heightScale /= paintHeight / newHeight; - } - tmpCanvas = CachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight); - tmpCtx = tmpCanvas.context; - tmpCtx.clearRect(0, 0, newWidth, newHeight); - tmpCtx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, - 0, 0, newWidth, newHeight); - imgToPaint = tmpCanvas.canvas; - paintWidth = newWidth; - paintHeight = newHeight; - tmpCanvasId = tmpCanvasId === 'prescale1' ? 'prescale2' : 'prescale1'; - } - ctx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, - 0, -height, width, height); - - if (this.imageLayer) { - var position = this.getCanvasPosition(0, -height); - this.imageLayer.appendImage({ - imgData: imgData, - left: position[0], - top: position[1], - width: width / currentTransform[0], - height: height / currentTransform[3] - }); - } - this.restore(); - }, - - paintInlineImageXObjectGroup: - function CanvasGraphics_paintInlineImageXObjectGroup(imgData, map) { - var ctx = this.ctx; - var w = imgData.width; - var h = imgData.height; - - var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h); - var tmpCtx = tmpCanvas.context; - putBinaryImageData(tmpCtx, imgData); - - for (var i = 0, ii = map.length; i < ii; i++) { - var entry = map[i]; - ctx.save(); - ctx.transform.apply(ctx, entry.transform); - ctx.scale(1, -1); - ctx.drawImage(tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, - 0, -1, 1, 1); - if (this.imageLayer) { - var position = this.getCanvasPosition(entry.x, entry.y); - this.imageLayer.appendImage({ - imgData: imgData, - left: position[0], - top: position[1], - width: w, - height: h - }); - } - ctx.restore(); - } - }, - - paintSolidColorImageMask: - function CanvasGraphics_paintSolidColorImageMask() { - this.ctx.fillRect(0, 0, 1, 1); - }, - - // Marked content - - markPoint: function CanvasGraphics_markPoint(tag) { - // TODO Marked content. - }, - markPointProps: function CanvasGraphics_markPointProps(tag, properties) { - // TODO Marked content. - }, - beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) { - // TODO Marked content. - }, - beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps( - tag, properties) { - // TODO Marked content. - }, - endMarkedContent: function CanvasGraphics_endMarkedContent() { - // TODO Marked content. - }, - - // Compatibility - - beginCompat: function CanvasGraphics_beginCompat() { - // TODO ignore undefined operators (should we do that anyway?) - }, - endCompat: function CanvasGraphics_endCompat() { - // TODO stop ignoring undefined operators - }, - - // Helper functions - - consumePath: function CanvasGraphics_consumePath() { - var ctx = this.ctx; - if (this.pendingClip) { - if (this.pendingClip === EO_CLIP) { - if (ctx.mozFillRule !== undefined) { - ctx.mozFillRule = 'evenodd'; - ctx.clip(); - ctx.mozFillRule = 'nonzero'; - } else { - try { - ctx.clip('evenodd'); - } catch (ex) { - // shouldn't really happen, but browsers might think differently - ctx.clip(); - } - } - } else { - ctx.clip(); - } - this.pendingClip = null; - } - ctx.beginPath(); - }, - getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) { - if (this.cachedGetSinglePixelWidth === null) { - var inverse = this.ctx.mozCurrentTransformInverse; - // max of the current horizontal and vertical scale - this.cachedGetSinglePixelWidth = Math.sqrt(Math.max( - (inverse[0] * inverse[0] + inverse[1] * inverse[1]), - (inverse[2] * inverse[2] + inverse[3] * inverse[3]))); - } - return this.cachedGetSinglePixelWidth; - }, - getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) { - var transform = this.ctx.mozCurrentTransform; - return [ - transform[0] * x + transform[2] * y + transform[4], - transform[1] * x + transform[3] * y + transform[5] - ]; - } - }; - - for (var op in OPS) { - CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op]; - } - - return CanvasGraphics; -})(); - - -var WebGLUtils = (function WebGLUtilsClosure() { - function loadShader(gl, code, shaderType) { - var shader = gl.createShader(shaderType); - gl.shaderSource(shader, code); - gl.compileShader(shader); - var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - if (!compiled) { - var errorMsg = gl.getShaderInfoLog(shader); - throw new Error('Error during shader compilation: ' + errorMsg); - } - return shader; - } - function createVertexShader(gl, code) { - return loadShader(gl, code, gl.VERTEX_SHADER); - } - function createFragmentShader(gl, code) { - return loadShader(gl, code, gl.FRAGMENT_SHADER); - } - function createProgram(gl, shaders) { - var program = gl.createProgram(); - for (var i = 0, ii = shaders.length; i < ii; ++i) { - gl.attachShader(program, shaders[i]); - } - gl.linkProgram(program); - var linked = gl.getProgramParameter(program, gl.LINK_STATUS); - if (!linked) { - var errorMsg = gl.getProgramInfoLog(program); - throw new Error('Error during program linking: ' + errorMsg); - } - return program; - } - function createTexture(gl, image, textureId) { - gl.activeTexture(textureId); - var texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - - // Set the parameters so we can render any size image. - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - // Upload the image into the texture. - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); - return texture; - } - - var currentGL, currentCanvas; - function generateGL() { - if (currentGL) { - return; - } - currentCanvas = document.createElement('canvas'); - currentGL = currentCanvas.getContext('webgl', - { premultipliedalpha: false }); - } - - var smaskVertexShaderCode = '\ - attribute vec2 a_position; \ - attribute vec2 a_texCoord; \ - \ - uniform vec2 u_resolution; \ - \ - varying vec2 v_texCoord; \ - \ - void main() { \ - vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0; \ - gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \ - \ - v_texCoord = a_texCoord; \ - } '; - - var smaskFragmentShaderCode = '\ - precision mediump float; \ - \ - uniform vec4 u_backdrop; \ - uniform int u_subtype; \ - uniform sampler2D u_image; \ - uniform sampler2D u_mask; \ - \ - varying vec2 v_texCoord; \ - \ - void main() { \ - vec4 imageColor = texture2D(u_image, v_texCoord); \ - vec4 maskColor = texture2D(u_mask, v_texCoord); \ - if (u_backdrop.a > 0.0) { \ - maskColor.rgb = maskColor.rgb * maskColor.a + \ - u_backdrop.rgb * (1.0 - maskColor.a); \ - } \ - float lum; \ - if (u_subtype == 0) { \ - lum = maskColor.a; \ - } else { \ - lum = maskColor.r * 0.3 + maskColor.g * 0.59 + \ - maskColor.b * 0.11; \ - } \ - imageColor.a *= lum; \ - imageColor.rgb *= imageColor.a; \ - gl_FragColor = imageColor; \ - } '; - - var smaskCache = null; - - function initSmaskGL() { - var canvas, gl; - - generateGL(); - canvas = currentCanvas; - currentCanvas = null; - gl = currentGL; - currentGL = null; - - // setup a GLSL program - var vertexShader = createVertexShader(gl, smaskVertexShaderCode); - var fragmentShader = createFragmentShader(gl, smaskFragmentShaderCode); - var program = createProgram(gl, [vertexShader, fragmentShader]); - gl.useProgram(program); - - var cache = {}; - cache.gl = gl; - cache.canvas = canvas; - cache.resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); - cache.positionLocation = gl.getAttribLocation(program, 'a_position'); - cache.backdropLocation = gl.getUniformLocation(program, 'u_backdrop'); - cache.subtypeLocation = gl.getUniformLocation(program, 'u_subtype'); - - var texCoordLocation = gl.getAttribLocation(program, 'a_texCoord'); - var texLayerLocation = gl.getUniformLocation(program, 'u_image'); - var texMaskLocation = gl.getUniformLocation(program, 'u_mask'); - - // provide texture coordinates for the rectangle. - var texCoordBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ - 0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 0.0, 1.0, - 1.0, 0.0, - 1.0, 1.0]), gl.STATIC_DRAW); - gl.enableVertexAttribArray(texCoordLocation); - gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0); - - gl.uniform1i(texLayerLocation, 0); - gl.uniform1i(texMaskLocation, 1); - - smaskCache = cache; - } - - function composeSMask(layer, mask, properties) { - var width = layer.width, height = layer.height; - - if (!smaskCache) { - initSmaskGL(); - } - var cache = smaskCache,canvas = cache.canvas, gl = cache.gl; - canvas.width = width; - canvas.height = height; - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - gl.uniform2f(cache.resolutionLocation, width, height); - - if (properties.backdrop) { - gl.uniform4f(cache.resolutionLocation, properties.backdrop[0], - properties.backdrop[1], properties.backdrop[2], 1); - } else { - gl.uniform4f(cache.resolutionLocation, 0, 0, 0, 0); - } - gl.uniform1i(cache.subtypeLocation, - properties.subtype === 'Luminosity' ? 1 : 0); - - // Create a textures - var texture = createTexture(gl, layer, gl.TEXTURE0); - var maskTexture = createTexture(gl, mask, gl.TEXTURE1); - - - // Create a buffer and put a single clipspace rectangle in - // it (2 triangles) - var buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ - 0, 0, - width, 0, - 0, height, - 0, height, - width, 0, - width, height]), gl.STATIC_DRAW); - gl.enableVertexAttribArray(cache.positionLocation); - gl.vertexAttribPointer(cache.positionLocation, 2, gl.FLOAT, false, 0, 0); - - // draw - gl.clearColor(0, 0, 0, 0); - gl.enable(gl.BLEND); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.drawArrays(gl.TRIANGLES, 0, 6); - - gl.flush(); - - gl.deleteTexture(texture); - gl.deleteTexture(maskTexture); - gl.deleteBuffer(buffer); - - return canvas; - } - - var figuresVertexShaderCode = '\ - attribute vec2 a_position; \ - attribute vec3 a_color; \ - \ - uniform vec2 u_resolution; \ - uniform vec2 u_scale; \ - uniform vec2 u_offset; \ - \ - varying vec4 v_color; \ - \ - void main() { \ - vec2 position = (a_position + u_offset) * u_scale; \ - vec2 clipSpace = (position / u_resolution) * 2.0 - 1.0; \ - gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \ - \ - v_color = vec4(a_color / 255.0, 1.0); \ - } '; - - var figuresFragmentShaderCode = '\ - precision mediump float; \ - \ - varying vec4 v_color; \ - \ - void main() { \ - gl_FragColor = v_color; \ - } '; - - var figuresCache = null; - - function initFiguresGL() { - var canvas, gl; - - generateGL(); - canvas = currentCanvas; - currentCanvas = null; - gl = currentGL; - currentGL = null; - - // setup a GLSL program - var vertexShader = createVertexShader(gl, figuresVertexShaderCode); - var fragmentShader = createFragmentShader(gl, figuresFragmentShaderCode); - var program = createProgram(gl, [vertexShader, fragmentShader]); - gl.useProgram(program); - - var cache = {}; - cache.gl = gl; - cache.canvas = canvas; - cache.resolutionLocation = gl.getUniformLocation(program, 'u_resolution'); - cache.scaleLocation = gl.getUniformLocation(program, 'u_scale'); - cache.offsetLocation = gl.getUniformLocation(program, 'u_offset'); - cache.positionLocation = gl.getAttribLocation(program, 'a_position'); - cache.colorLocation = gl.getAttribLocation(program, 'a_color'); - - figuresCache = cache; - } - - function drawFigures(width, height, backgroundColor, figures, context) { - if (!figuresCache) { - initFiguresGL(); - } - var cache = figuresCache, canvas = cache.canvas, gl = cache.gl; - - canvas.width = width; - canvas.height = height; - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - gl.uniform2f(cache.resolutionLocation, width, height); - - // count triangle points - var count = 0; - var i, ii, rows; - for (i = 0, ii = figures.length; i < ii; i++) { - switch (figures[i].type) { - case 'lattice': - rows = (figures[i].coords.length / figures[i].verticesPerRow) | 0; - count += (rows - 1) * (figures[i].verticesPerRow - 1) * 6; - break; - case 'triangles': - count += figures[i].coords.length; - break; - } - } - // transfer data - var coords = new Float32Array(count * 2); - var colors = new Uint8Array(count * 3); - var coordsMap = context.coords, colorsMap = context.colors; - var pIndex = 0, cIndex = 0; - for (i = 0, ii = figures.length; i < ii; i++) { - var figure = figures[i], ps = figure.coords, cs = figure.colors; - switch (figure.type) { - case 'lattice': - var cols = figure.verticesPerRow; - rows = (ps.length / cols) | 0; - for (var row = 1; row < rows; row++) { - var offset = row * cols + 1; - for (var col = 1; col < cols; col++, offset++) { - coords[pIndex] = coordsMap[ps[offset - cols - 1]]; - coords[pIndex + 1] = coordsMap[ps[offset - cols - 1] + 1]; - coords[pIndex + 2] = coordsMap[ps[offset - cols]]; - coords[pIndex + 3] = coordsMap[ps[offset - cols] + 1]; - coords[pIndex + 4] = coordsMap[ps[offset - 1]]; - coords[pIndex + 5] = coordsMap[ps[offset - 1] + 1]; - colors[cIndex] = colorsMap[cs[offset - cols - 1]]; - colors[cIndex + 1] = colorsMap[cs[offset - cols - 1] + 1]; - colors[cIndex + 2] = colorsMap[cs[offset - cols - 1] + 2]; - colors[cIndex + 3] = colorsMap[cs[offset - cols]]; - colors[cIndex + 4] = colorsMap[cs[offset - cols] + 1]; - colors[cIndex + 5] = colorsMap[cs[offset - cols] + 2]; - colors[cIndex + 6] = colorsMap[cs[offset - 1]]; - colors[cIndex + 7] = colorsMap[cs[offset - 1] + 1]; - colors[cIndex + 8] = colorsMap[cs[offset - 1] + 2]; - - coords[pIndex + 6] = coords[pIndex + 2]; - coords[pIndex + 7] = coords[pIndex + 3]; - coords[pIndex + 8] = coords[pIndex + 4]; - coords[pIndex + 9] = coords[pIndex + 5]; - coords[pIndex + 10] = coordsMap[ps[offset]]; - coords[pIndex + 11] = coordsMap[ps[offset] + 1]; - colors[cIndex + 9] = colors[cIndex + 3]; - colors[cIndex + 10] = colors[cIndex + 4]; - colors[cIndex + 11] = colors[cIndex + 5]; - colors[cIndex + 12] = colors[cIndex + 6]; - colors[cIndex + 13] = colors[cIndex + 7]; - colors[cIndex + 14] = colors[cIndex + 8]; - colors[cIndex + 15] = colorsMap[cs[offset]]; - colors[cIndex + 16] = colorsMap[cs[offset] + 1]; - colors[cIndex + 17] = colorsMap[cs[offset] + 2]; - pIndex += 12; - cIndex += 18; - } - } - break; - case 'triangles': - for (var j = 0, jj = ps.length; j < jj; j++) { - coords[pIndex] = coordsMap[ps[j]]; - coords[pIndex + 1] = coordsMap[ps[j] + 1]; - colors[cIndex] = colorsMap[cs[i]]; - colors[cIndex + 1] = colorsMap[cs[j] + 1]; - colors[cIndex + 2] = colorsMap[cs[j] + 2]; - pIndex += 2; - cIndex += 3; - } - break; - } - } - - // draw - if (backgroundColor) { - gl.clearColor(backgroundColor[0] / 255, backgroundColor[1] / 255, - backgroundColor[2] / 255, 1.0); - } else { - gl.clearColor(0, 0, 0, 0); - } - gl.clear(gl.COLOR_BUFFER_BIT); - - var coordsBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, coordsBuffer); - gl.bufferData(gl.ARRAY_BUFFER, coords, gl.STATIC_DRAW); - gl.enableVertexAttribArray(cache.positionLocation); - gl.vertexAttribPointer(cache.positionLocation, 2, gl.FLOAT, false, 0, 0); - - var colorsBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, colorsBuffer); - gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - gl.enableVertexAttribArray(cache.colorLocation); - gl.vertexAttribPointer(cache.colorLocation, 3, gl.UNSIGNED_BYTE, false, - 0, 0); - - gl.uniform2f(cache.scaleLocation, context.scaleX, context.scaleY); - gl.uniform2f(cache.offsetLocation, context.offsetX, context.offsetY); - - gl.drawArrays(gl.TRIANGLES, 0, count); - - gl.flush(); - - gl.deleteBuffer(coordsBuffer); - gl.deleteBuffer(colorsBuffer); - - return canvas; - } - - function cleanup() { - if (smaskCache && smaskCache.canvas) { - smaskCache.canvas.width = 0; - smaskCache.canvas.height = 0; - } - if (figuresCache && figuresCache.canvas) { - figuresCache.canvas.width = 0; - figuresCache.canvas.height = 0; - } - smaskCache = null; - figuresCache = null; - } - - return { - get isEnabled() { - if (PDFJS.disableWebGL) { - return false; - } - var enabled = false; - try { - generateGL(); - enabled = !!currentGL; - } catch (e) { } - return shadow(this, 'isEnabled', enabled); - }, - composeSMask: composeSMask, - drawFigures: drawFigures, - clear: cleanup - }; -})(); - - -var ShadingIRs = {}; - -ShadingIRs.RadialAxial = { - fromIR: function RadialAxial_fromIR(raw) { - var type = raw[1]; - var colorStops = raw[2]; - var p0 = raw[3]; - var p1 = raw[4]; - var r0 = raw[5]; - var r1 = raw[6]; - return { - type: 'Pattern', - getPattern: function RadialAxial_getPattern(ctx) { - var grad; - if (type === 'axial') { - grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]); - } else if (type === 'radial') { - grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1); - } - - for (var i = 0, ii = colorStops.length; i < ii; ++i) { - var c = colorStops[i]; - grad.addColorStop(c[0], c[1]); - } - return grad; - } - }; - } -}; - -var createMeshCanvas = (function createMeshCanvasClosure() { - function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { - // Very basic Gouraud-shaded triangle rasterization algorithm. - var coords = context.coords, colors = context.colors; - var bytes = data.data, rowSize = data.width * 4; - var tmp; - if (coords[p1 + 1] > coords[p2 + 1]) { - tmp = p1; p1 = p2; p2 = tmp; tmp = c1; c1 = c2; c2 = tmp; - } - if (coords[p2 + 1] > coords[p3 + 1]) { - tmp = p2; p2 = p3; p3 = tmp; tmp = c2; c2 = c3; c3 = tmp; - } - if (coords[p1 + 1] > coords[p2 + 1]) { - tmp = p1; p1 = p2; p2 = tmp; tmp = c1; c1 = c2; c2 = tmp; - } - var x1 = (coords[p1] + context.offsetX) * context.scaleX; - var y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; - var x2 = (coords[p2] + context.offsetX) * context.scaleX; - var y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; - var x3 = (coords[p3] + context.offsetX) * context.scaleX; - var y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; - if (y1 >= y3) { - return; - } - var c1r = colors[c1], c1g = colors[c1 + 1], c1b = colors[c1 + 2]; - var c2r = colors[c2], c2g = colors[c2 + 1], c2b = colors[c2 + 2]; - var c3r = colors[c3], c3g = colors[c3 + 1], c3b = colors[c3 + 2]; - - var minY = Math.round(y1), maxY = Math.round(y3); - var xa, car, cag, cab; - var xb, cbr, cbg, cbb; - var k; - for (var y = minY; y <= maxY; y++) { - if (y < y2) { - k = y < y1 ? 0 : y1 === y2 ? 1 : (y1 - y) / (y1 - y2); - xa = x1 - (x1 - x2) * k; - car = c1r - (c1r - c2r) * k; - cag = c1g - (c1g - c2g) * k; - cab = c1b - (c1b - c2b) * k; - } else { - k = y > y3 ? 1 : y2 === y3 ? 0 : (y2 - y) / (y2 - y3); - xa = x2 - (x2 - x3) * k; - car = c2r - (c2r - c3r) * k; - cag = c2g - (c2g - c3g) * k; - cab = c2b - (c2b - c3b) * k; - } - k = y < y1 ? 0 : y > y3 ? 1 : (y1 - y) / (y1 - y3); - xb = x1 - (x1 - x3) * k; - cbr = c1r - (c1r - c3r) * k; - cbg = c1g - (c1g - c3g) * k; - cbb = c1b - (c1b - c3b) * k; - var x1_ = Math.round(Math.min(xa, xb)); - var x2_ = Math.round(Math.max(xa, xb)); - var j = rowSize * y + x1_ * 4; - for (var x = x1_; x <= x2_; x++) { - k = (xa - x) / (xa - xb); - k = k < 0 ? 0 : k > 1 ? 1 : k; - bytes[j++] = (car - (car - cbr) * k) | 0; - bytes[j++] = (cag - (cag - cbg) * k) | 0; - bytes[j++] = (cab - (cab - cbb) * k) | 0; - bytes[j++] = 255; - } - } - } - - function drawFigure(data, figure, context) { - var ps = figure.coords; - var cs = figure.colors; - var i, ii; - switch (figure.type) { - case 'lattice': - var verticesPerRow = figure.verticesPerRow; - var rows = Math.floor(ps.length / verticesPerRow) - 1; - var cols = verticesPerRow - 1; - for (i = 0; i < rows; i++) { - var q = i * verticesPerRow; - for (var j = 0; j < cols; j++, q++) { - drawTriangle(data, context, - ps[q], ps[q + 1], ps[q + verticesPerRow], - cs[q], cs[q + 1], cs[q + verticesPerRow]); - drawTriangle(data, context, - ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], - cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); - } - } - break; - case 'triangles': - for (i = 0, ii = ps.length; i < ii; i += 3) { - drawTriangle(data, context, - ps[i], ps[i + 1], ps[i + 2], - cs[i], cs[i + 1], cs[i + 2]); - } - break; - default: - error('illigal figure'); - break; - } - } - - function createMeshCanvas(bounds, combinesScale, coords, colors, figures, - backgroundColor) { - // we will increase scale on some weird factor to let antialiasing take - // care of "rough" edges - var EXPECTED_SCALE = 1.1; - // MAX_PATTERN_SIZE is used to avoid OOM situation. - var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough - - var offsetX = Math.floor(bounds[0]); - var offsetY = Math.floor(bounds[1]); - var boundsWidth = Math.ceil(bounds[2]) - offsetX; - var boundsHeight = Math.ceil(bounds[3]) - offsetY; - - var width = Math.min(Math.ceil(Math.abs(boundsWidth * combinesScale[0] * - EXPECTED_SCALE)), MAX_PATTERN_SIZE); - var height = Math.min(Math.ceil(Math.abs(boundsHeight * combinesScale[1] * - EXPECTED_SCALE)), MAX_PATTERN_SIZE); - var scaleX = boundsWidth / width; - var scaleY = boundsHeight / height; - - var context = { - coords: coords, - colors: colors, - offsetX: -offsetX, - offsetY: -offsetY, - scaleX: 1 / scaleX, - scaleY: 1 / scaleY - }; - - var canvas, tmpCanvas, i, ii; - if (WebGLUtils.isEnabled) { - canvas = WebGLUtils.drawFigures(width, height, backgroundColor, - figures, context); - - // https://bugzilla.mozilla.org/show_bug.cgi?id=972126 - tmpCanvas = CachedCanvases.getCanvas('mesh', width, height, false); - tmpCanvas.context.drawImage(canvas, 0, 0); - canvas = tmpCanvas.canvas; - } else { - tmpCanvas = CachedCanvases.getCanvas('mesh', width, height, false); - var tmpCtx = tmpCanvas.context; - - var data = tmpCtx.createImageData(width, height); - if (backgroundColor) { - var bytes = data.data; - for (i = 0, ii = bytes.length; i < ii; i += 4) { - bytes[i] = backgroundColor[0]; - bytes[i + 1] = backgroundColor[1]; - bytes[i + 2] = backgroundColor[2]; - bytes[i + 3] = 255; - } - } - for (i = 0; i < figures.length; i++) { - drawFigure(data, figures[i], context); - } - tmpCtx.putImageData(data, 0, 0); - canvas = tmpCanvas.canvas; - } - - return {canvas: canvas, offsetX: offsetX, offsetY: offsetY, - scaleX: scaleX, scaleY: scaleY}; - } - return createMeshCanvas; -})(); - -ShadingIRs.Mesh = { - fromIR: function Mesh_fromIR(raw) { - //var type = raw[1]; - var coords = raw[2]; - var colors = raw[3]; - var figures = raw[4]; - var bounds = raw[5]; - var matrix = raw[6]; - //var bbox = raw[7]; - var background = raw[8]; - return { - type: 'Pattern', - getPattern: function Mesh_getPattern(ctx, owner, shadingFill) { - var scale; - if (shadingFill) { - scale = Util.singularValueDecompose2dScale(ctx.mozCurrentTransform); - } else { - // Obtain scale from matrix and current transformation matrix. - scale = Util.singularValueDecompose2dScale(owner.baseTransform); - if (matrix) { - var matrixScale = Util.singularValueDecompose2dScale(matrix); - scale = [scale[0] * matrixScale[0], - scale[1] * matrixScale[1]]; - } - } - - - // Rasterizing on the main thread since sending/queue large canvases - // might cause OOM. - var temporaryPatternCanvas = createMeshCanvas(bounds, scale, coords, - colors, figures, shadingFill ? null : background); - - if (!shadingFill) { - ctx.setTransform.apply(ctx, owner.baseTransform); - if (matrix) { - ctx.transform.apply(ctx, matrix); - } - } - - ctx.translate(temporaryPatternCanvas.offsetX, - temporaryPatternCanvas.offsetY); - ctx.scale(temporaryPatternCanvas.scaleX, - temporaryPatternCanvas.scaleY); - - return ctx.createPattern(temporaryPatternCanvas.canvas, 'no-repeat'); - } - }; - } -}; - -ShadingIRs.Dummy = { - fromIR: function Dummy_fromIR() { - return { - type: 'Pattern', - getPattern: function Dummy_fromIR_getPattern() { - return 'hotpink'; - } - }; - } -}; - -function getShadingPatternFromIR(raw) { - var shadingIR = ShadingIRs[raw[0]]; - if (!shadingIR) { - error('Unknown IR type: ' + raw[0]); - } - return shadingIR.fromIR(raw); -} - -var TilingPattern = (function TilingPatternClosure() { - var PaintType = { - COLORED: 1, - UNCOLORED: 2 - }; - - var MAX_PATTERN_SIZE = 3000; // 10in @ 300dpi shall be enough - - function TilingPattern(IR, color, ctx, objs, commonObjs, baseTransform) { - this.operatorList = IR[2]; - this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; - this.bbox = IR[4]; - this.xstep = IR[5]; - this.ystep = IR[6]; - this.paintType = IR[7]; - this.tilingType = IR[8]; - this.color = color; - this.objs = objs; - this.commonObjs = commonObjs; - this.baseTransform = baseTransform; - this.type = 'Pattern'; - this.ctx = ctx; - } - - TilingPattern.prototype = { - createPatternCanvas: function TilinPattern_createPatternCanvas(owner) { - var operatorList = this.operatorList; - var bbox = this.bbox; - var xstep = this.xstep; - var ystep = this.ystep; - var paintType = this.paintType; - var tilingType = this.tilingType; - var color = this.color; - var objs = this.objs; - var commonObjs = this.commonObjs; - - info('TilingType: ' + tilingType); - - var x0 = bbox[0], y0 = bbox[1], x1 = bbox[2], y1 = bbox[3]; - - var topLeft = [x0, y0]; - // we want the canvas to be as large as the step size - var botRight = [x0 + xstep, y0 + ystep]; - - var width = botRight[0] - topLeft[0]; - var height = botRight[1] - topLeft[1]; - - // Obtain scale from matrix and current transformation matrix. - var matrixScale = Util.singularValueDecompose2dScale(this.matrix); - var curMatrixScale = Util.singularValueDecompose2dScale( - this.baseTransform); - var combinedScale = [matrixScale[0] * curMatrixScale[0], - matrixScale[1] * curMatrixScale[1]]; - - // MAX_PATTERN_SIZE is used to avoid OOM situation. - // Use width and height values that are as close as possible to the end - // result when the pattern is used. Too low value makes the pattern look - // blurry. Too large value makes it look too crispy. - width = Math.min(Math.ceil(Math.abs(width * combinedScale[0])), - MAX_PATTERN_SIZE); - - height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])), - MAX_PATTERN_SIZE); - - var tmpCanvas = CachedCanvases.getCanvas('pattern', width, height, true); - var tmpCtx = tmpCanvas.context; - var graphics = new CanvasGraphics(tmpCtx, commonObjs, objs); - graphics.groupLevel = owner.groupLevel; - - this.setFillAndStrokeStyleToContext(tmpCtx, paintType, color); - - this.setScale(width, height, xstep, ystep); - this.transformToScale(graphics); - - // transform coordinates to pattern space - var tmpTranslate = [1, 0, 0, 1, -topLeft[0], -topLeft[1]]; - graphics.transform.apply(graphics, tmpTranslate); - - this.clipBbox(graphics, bbox, x0, y0, x1, y1); - - graphics.executeOperatorList(operatorList); - return tmpCanvas.canvas; - }, - - setScale: function TilingPattern_setScale(width, height, xstep, ystep) { - this.scale = [width / xstep, height / ystep]; - }, - - transformToScale: function TilingPattern_transformToScale(graphics) { - var scale = this.scale; - var tmpScale = [scale[0], 0, 0, scale[1], 0, 0]; - graphics.transform.apply(graphics, tmpScale); - }, - - scaleToContext: function TilingPattern_scaleToContext() { - var scale = this.scale; - this.ctx.scale(1 / scale[0], 1 / scale[1]); - }, - - clipBbox: function clipBbox(graphics, bbox, x0, y0, x1, y1) { - if (bbox && isArray(bbox) && bbox.length === 4) { - var bboxWidth = x1 - x0; - var bboxHeight = y1 - y0; - graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight); - graphics.clip(); - graphics.endPath(); - } - }, - - setFillAndStrokeStyleToContext: - function setFillAndStrokeStyleToContext(context, paintType, color) { - switch (paintType) { - case PaintType.COLORED: - var ctx = this.ctx; - context.fillStyle = ctx.fillStyle; - context.strokeStyle = ctx.strokeStyle; - break; - case PaintType.UNCOLORED: - var cssColor = Util.makeCssRgb(color[0], color[1], color[2]); - context.fillStyle = cssColor; - context.strokeStyle = cssColor; - break; - default: - error('Unsupported paint type: ' + paintType); - } - }, - - getPattern: function TilingPattern_getPattern(ctx, owner) { - var temporaryPatternCanvas = this.createPatternCanvas(owner); - - ctx = this.ctx; - ctx.setTransform.apply(ctx, this.baseTransform); - ctx.transform.apply(ctx, this.matrix); - this.scaleToContext(); - - return ctx.createPattern(temporaryPatternCanvas, 'repeat'); - } - }; - - return TilingPattern; -})(); - - -PDFJS.disableFontFace = false; - -var FontLoader = { - insertRule: function fontLoaderInsertRule(rule) { - var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG'); - if (!styleElement) { - styleElement = document.createElement('style'); - styleElement.id = 'PDFJS_FONT_STYLE_TAG'; - document.documentElement.getElementsByTagName('head')[0].appendChild( - styleElement); - } - - var styleSheet = styleElement.sheet; - styleSheet.insertRule(rule, styleSheet.cssRules.length); - }, - - clear: function fontLoaderClear() { - var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG'); - if (styleElement) { - styleElement.parentNode.removeChild(styleElement); - } -//#if !(MOZCENTRAL) - this.nativeFontFaces.forEach(function(nativeFontFace) { - document.fonts.delete(nativeFontFace); - }); - this.nativeFontFaces.length = 0; -//#endif - }, -//#if !(MOZCENTRAL) - get loadTestFont() { - // This is a CFF font with 1 glyph for '.' that fills its entire width and - // height. - return shadow(this, 'loadTestFont', atob( - 'T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQ' + - 'AABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwA' + - 'AAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbm' + - 'FtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAA' + - 'AADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6A' + - 'ABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAA' + - 'MQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAA' + - 'AAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAA' + - 'AAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQ' + - 'AAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMA' + - 'AQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAA' + - 'EAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAA' + - 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + - 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA' + - 'AAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgc' + - 'A/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF' + - 'hYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQA' + - 'AAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAg' + - 'ABAAAAAAAAAAAD6AAAAAAAAA==' - )); - }, - - loadTestFontId: 0, - - loadingContext: { - requests: [], - nextRequestId: 0 - }, - - isSyncFontLoadingSupported: (function detectSyncFontLoadingSupport() { - if (isWorker) { - return false; - } - - // User agent string sniffing is bad, but there is no reliable way to tell - // if font is fully loaded and ready to be used with canvas. - var userAgent = window.navigator.userAgent; - var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(userAgent); - if (m && m[1] >= 14) { - return true; - } - // TODO other browsers - if (userAgent === 'node') { - return true; - } - return false; - })(), - - nativeFontFaces: [], - - isFontLoadingAPISupported: (!isWorker && typeof document !== 'undefined' && - !!document.fonts), - - addNativeFontFace: function fontLoader_addNativeFontFace(nativeFontFace) { - this.nativeFontFaces.push(nativeFontFace); - document.fonts.add(nativeFontFace); - }, - - bind: function fontLoaderBind(fonts, callback) { - assert(!isWorker, 'bind() shall be called from main thread'); - - var rules = []; - var fontsToLoad = []; - var fontLoadPromises = []; - for (var i = 0, ii = fonts.length; i < ii; i++) { - var font = fonts[i]; - - // Add the font to the DOM only once or skip if the font - // is already loaded. - if (font.attached || font.loading === false) { - continue; - } - font.attached = true; - - if (this.isFontLoadingAPISupported) { - var nativeFontFace = font.createNativeFontFace(); - if (nativeFontFace) { - fontLoadPromises.push(nativeFontFace.loaded); - } - } else { - var rule = font.bindDOM(); - if (rule) { - rules.push(rule); - fontsToLoad.push(font); - } - } - } - - var request = FontLoader.queueLoadingCallback(callback); - if (this.isFontLoadingAPISupported) { - Promise.all(fontsToLoad).then(function() { - request.complete(); - }); - } else if (rules.length > 0 && !this.isSyncFontLoadingSupported) { - FontLoader.prepareFontLoadEvent(rules, fontsToLoad, request); - } else { - request.complete(); - } - }, - - queueLoadingCallback: function FontLoader_queueLoadingCallback(callback) { - function LoadLoader_completeRequest() { - assert(!request.end, 'completeRequest() cannot be called twice'); - request.end = Date.now(); - - // sending all completed requests in order how they were queued - while (context.requests.length > 0 && context.requests[0].end) { - var otherRequest = context.requests.shift(); - setTimeout(otherRequest.callback, 0); - } - } - - var context = FontLoader.loadingContext; - var requestId = 'pdfjs-font-loading-' + (context.nextRequestId++); - var request = { - id: requestId, - complete: LoadLoader_completeRequest, - callback: callback, - started: Date.now() - }; - context.requests.push(request); - return request; - }, - - prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, - fonts, - request) { - /** Hack begin */ - // There's currently no event when a font has finished downloading so the - // following code is a dirty hack to 'guess' when a font is - // ready. It's assumed fonts are loaded in order, so add a known test - // font after the desired fonts and then test for the loading of that - // test font. - - function int32(data, offset) { - return (data.charCodeAt(offset) << 24) | - (data.charCodeAt(offset + 1) << 16) | - (data.charCodeAt(offset + 2) << 8) | - (data.charCodeAt(offset + 3) & 0xff); - } - - function spliceString(s, offset, remove, insert) { - var chunk1 = s.substr(0, offset); - var chunk2 = s.substr(offset + remove); - return chunk1 + insert + chunk2; - } - - var i, ii; - - var canvas = document.createElement('canvas'); - canvas.width = 1; - canvas.height = 1; - var ctx = canvas.getContext('2d'); - - var called = 0; - function isFontReady(name, callback) { - called++; - // With setTimeout clamping this gives the font ~100ms to load. - if(called > 30) { - warn('Load test font never loaded.'); - callback(); - return; - } - ctx.font = '30px ' + name; - ctx.fillText('.', 0, 20); - var imageData = ctx.getImageData(0, 0, 1, 1); - if (imageData.data[3] > 0) { - callback(); - return; - } - setTimeout(isFontReady.bind(null, name, callback)); - } - - var loadTestFontId = 'lt' + Date.now() + this.loadTestFontId++; - // Chromium seems to cache fonts based on a hash of the actual font data, - // so the font must be modified for each load test else it will appear to - // be loaded already. - // TODO: This could maybe be made faster by avoiding the btoa of the full - // font by splitting it in chunks before hand and padding the font id. - var data = this.loadTestFont; - var COMMENT_OFFSET = 976; // has to be on 4 byte boundary (for checksum) - data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, - loadTestFontId); - // CFF checksum is important for IE, adjusting it - var CFF_CHECKSUM_OFFSET = 16; - var XXXX_VALUE = 0x58585858; // the "comment" filled with 'X' - var checksum = int32(data, CFF_CHECKSUM_OFFSET); - for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) { - checksum = (checksum - XXXX_VALUE + int32(loadTestFontId, i)) | 0; - } - if (i < loadTestFontId.length) { // align to 4 bytes boundary - checksum = (checksum - XXXX_VALUE + - int32(loadTestFontId + 'XXX', i)) | 0; - } - data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, string32(checksum)); - - var url = 'url(data:font/opentype;base64,' + btoa(data) + ');'; - var rule = '@font-face { font-family:"' + loadTestFontId + '";src:' + - url + '}'; - FontLoader.insertRule(rule); - - var names = []; - for (i = 0, ii = fonts.length; i < ii; i++) { - names.push(fonts[i].loadedName); - } - names.push(loadTestFontId); - - var div = document.createElement('div'); - div.setAttribute('style', - 'visibility: hidden;' + - 'width: 10px; height: 10px;' + - 'position: absolute; top: 0px; left: 0px;'); - for (i = 0, ii = names.length; i < ii; ++i) { - var span = document.createElement('span'); - span.textContent = 'Hi'; - span.style.fontFamily = names[i]; - div.appendChild(span); - } - document.body.appendChild(div); - - isFontReady(loadTestFontId, function() { - document.body.removeChild(div); - request.complete(); - }); - /** Hack end */ - } -//#else -//bind: function fontLoaderBind(fonts, callback) { -// assert(!isWorker, 'bind() shall be called from main thread'); -// -// for (var i = 0, ii = fonts.length; i < ii; i++) { -// var font = fonts[i]; -// if (font.attached) { -// continue; -// } -// -// font.attached = true; -// font.bindDOM() -// } -// -// setTimeout(callback); -//} -//#endif -}; - -var FontFaceObject = (function FontFaceObjectClosure() { - function FontFaceObject(name, file, properties) { - this.compiledGlyphs = {}; - if (arguments.length === 1) { - // importing translated data - var data = arguments[0]; - for (var i in data) { - this[i] = data[i]; - } - return; - } - } - FontFaceObject.prototype = { -//#if !(MOZCENTRAL) - createNativeFontFace: function FontFaceObject_createNativeFontFace() { - if (!this.data) { - return null; - } - - if (PDFJS.disableFontFace) { - this.disableFontFace = true; - return null; - } - - var nativeFontFace = new FontFace(this.loadedName, this.data, {}); - - FontLoader.addNativeFontFace(nativeFontFace); - - if (PDFJS.pdfBug && 'FontInspector' in globalScope && - globalScope['FontInspector'].enabled) { - globalScope['FontInspector'].fontAdded(this); - } - return nativeFontFace; - }, -//#endif - - bindDOM: function FontFaceObject_bindDOM() { - if (!this.data) { - return null; - } - - if (PDFJS.disableFontFace) { - this.disableFontFace = true; - return null; - } - - var data = bytesToString(new Uint8Array(this.data)); - var fontName = this.loadedName; - - // Add the font-face rule to the document - var url = ('url(data:' + this.mimetype + ';base64,' + - window.btoa(data) + ');'); - var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}'; - FontLoader.insertRule(rule); - - if (PDFJS.pdfBug && 'FontInspector' in globalScope && - globalScope['FontInspector'].enabled) { - globalScope['FontInspector'].fontAdded(this, url); - } - - return rule; - }, - - getPathGenerator: function FontLoader_getPathGenerator(objs, character) { - if (!(character in this.compiledGlyphs)) { - var js = objs.get(this.loadedName + '_path_' + character); - /*jshint -W054 */ - this.compiledGlyphs[character] = new Function('c', 'size', js); - } - return this.compiledGlyphs[character]; - } - }; - return FontFaceObject; -})(); - - -var ANNOT_MIN_SIZE = 10; // px - -var AnnotationUtils = (function AnnotationUtilsClosure() { - // TODO(mack): This dupes some of the logic in CanvasGraphics.setFont() - function setTextStyles(element, item, fontObj) { - - var style = element.style; - style.fontSize = item.fontSize + 'px'; - style.direction = item.fontDirection < 0 ? 'rtl': 'ltr'; - - if (!fontObj) { - return; - } - - style.fontWeight = fontObj.black ? - (fontObj.bold ? 'bolder' : 'bold') : - (fontObj.bold ? 'bold' : 'normal'); - style.fontStyle = fontObj.italic ? 'italic' : 'normal'; - - var fontName = fontObj.loadedName; - var fontFamily = fontName ? '"' + fontName + '", ' : ''; - // Use a reasonable default font if the font doesn't specify a fallback - var fallbackName = fontObj.fallbackName || 'Helvetica, sans-serif'; - style.fontFamily = fontFamily + fallbackName; - } - - function initContainer(item, drawBorder) { - var container = document.createElement('section'); - var cstyle = container.style; - var width = item.rect[2] - item.rect[0]; - var height = item.rect[3] - item.rect[1]; - - var bWidth = item.borderWidth || 0; - if (bWidth) { - width = width - 2 * bWidth; - height = height - 2 * bWidth; - cstyle.borderWidth = bWidth + 'px'; - var color = item.color; - if (drawBorder && color) { - cstyle.borderStyle = 'solid'; - cstyle.borderColor = Util.makeCssRgb(Math.round(color[0] * 255), - Math.round(color[1] * 255), - Math.round(color[2] * 255)); - } - } - cstyle.width = width + 'px'; - cstyle.height = height + 'px'; - return container; - } - - function getHtmlElementForTextWidgetAnnotation(item, commonObjs) { - var element = document.createElement('div'); - var width = item.rect[2] - item.rect[0]; - var height = item.rect[3] - item.rect[1]; - element.style.width = width + 'px'; - element.style.height = height + 'px'; - element.style.display = 'table'; - - var content = document.createElement('div'); - content.textContent = item.fieldValue; - var textAlignment = item.textAlignment; - content.style.textAlign = ['left', 'center', 'right'][textAlignment]; - content.style.verticalAlign = 'middle'; - content.style.display = 'table-cell'; - - var fontObj = item.fontRefName ? - commonObjs.getData(item.fontRefName) : null; - setTextStyles(content, item, fontObj); - - element.appendChild(content); - - return element; - } - - function getHtmlElementForTextAnnotation(item) { - var rect = item.rect; - - // sanity check because of OOo-generated PDFs - if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { - rect[3] = rect[1] + ANNOT_MIN_SIZE; - } - if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { - rect[2] = rect[0] + (rect[3] - rect[1]); // make it square - } - - var container = initContainer(item, false); - container.className = 'annotText'; - - var image = document.createElement('img'); - image.style.height = container.style.height; - image.style.width = container.style.width; - var iconName = item.name; - image.src = PDFJS.imageResourcesPath + 'annotation-' + - iconName.toLowerCase() + '.svg'; - image.alt = '[{{type}} Annotation]'; - image.dataset.l10nId = 'text_annotation_type'; - image.dataset.l10nArgs = JSON.stringify({type: iconName}); - - var contentWrapper = document.createElement('div'); - contentWrapper.className = 'annotTextContentWrapper'; - contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; - contentWrapper.style.top = '-10px'; - - var content = document.createElement('div'); - content.className = 'annotTextContent'; - content.setAttribute('hidden', true); - - var i, ii; - if (item.hasBgColor) { - var color = item.color; - - // Enlighten the color (70%) - var BACKGROUND_ENLIGHT = 0.7; - var r = BACKGROUND_ENLIGHT * (1.0 - color[0]) + color[0]; - var g = BACKGROUND_ENLIGHT * (1.0 - color[1]) + color[1]; - var b = BACKGROUND_ENLIGHT * (1.0 - color[2]) + color[2]; - content.style.backgroundColor = Util.makeCssRgb((r * 255) | 0, - (g * 255) | 0, - (b * 255) | 0); - } - - var title = document.createElement('h1'); - var text = document.createElement('p'); - title.textContent = item.title; - - if (!item.content && !item.title) { - content.setAttribute('hidden', true); - } else { - var e = document.createElement('span'); - var lines = item.content.split(/(?:\r\n?|\n)/); - for (i = 0, ii = lines.length; i < ii; ++i) { - var line = lines[i]; - e.appendChild(document.createTextNode(line)); - if (i < (ii - 1)) { - e.appendChild(document.createElement('br')); - } - } - text.appendChild(e); - - var pinned = false; - - var showAnnotation = function showAnnotation(pin) { - if (pin) { - pinned = true; - } - if (content.hasAttribute('hidden')) { - container.style.zIndex += 1; - content.removeAttribute('hidden'); - } - }; - - var hideAnnotation = function hideAnnotation(unpin) { - if (unpin) { - pinned = false; - } - if (!content.hasAttribute('hidden') && !pinned) { - container.style.zIndex -= 1; - content.setAttribute('hidden', true); - } - }; - - var toggleAnnotation = function toggleAnnotation() { - if (pinned) { - hideAnnotation(true); - } else { - showAnnotation(true); - } - }; - - image.addEventListener('click', function image_clickHandler() { - toggleAnnotation(); - }, false); - image.addEventListener('mouseover', function image_mouseOverHandler() { - showAnnotation(); - }, false); - image.addEventListener('mouseout', function image_mouseOutHandler() { - hideAnnotation(); - }, false); - - content.addEventListener('click', function content_clickHandler() { - hideAnnotation(true); - }, false); - } - - content.appendChild(title); - content.appendChild(text); - contentWrapper.appendChild(content); - container.appendChild(image); - container.appendChild(contentWrapper); - - return container; - } - - function getHtmlElementForLinkAnnotation(item) { - var container = initContainer(item, true); - container.className = 'annotLink'; - - var link = document.createElement('a'); - link.href = link.title = item.url || ''; - if (item.url && PDFJS.openExternalLinksInNewWindow) { - link.target = '_blank'; - } - - container.appendChild(link); - - return container; - } - - function getHtmlElement(data, objs) { - switch (data.annotationType) { - case AnnotationType.WIDGET: - return getHtmlElementForTextWidgetAnnotation(data, objs); - case AnnotationType.TEXT: - return getHtmlElementForTextAnnotation(data); - case AnnotationType.LINK: - return getHtmlElementForLinkAnnotation(data); - default: - throw new Error('Unsupported annotationType: ' + data.annotationType); - } - } - - return { - getHtmlElement: getHtmlElement - }; -})(); -PDFJS.AnnotationUtils = AnnotationUtils; - - -//#if (GENERIC || SINGLE_FILE) -var SVG_DEFAULTS = { - fontStyle: 'normal', - fontWeight: 'normal', - fillColor: '#000000' -}; - -var convertImgDataToPng = (function convertImgDataToPngClosure() { - var PNG_HEADER = - new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); - - var CHUNK_WRAPPER_SIZE = 12; - - var crcTable = new Int32Array(256); - for (var i = 0; i < 256; i++) { - var c = i; - for (var h = 0; h < 8; h++) { - if (c & 1) { - c = 0xedB88320 ^ ((c >> 1) & 0x7fffffff); - } else { - c = (c >> 1) & 0x7fffffff; - } - } - crcTable[i] = c; - } - - function crc32(data, start, end) { - var crc = -1; - for (var i = start; i < end; i++) { - var a = (crc ^ data[i]) & 0xff; - var b = crcTable[a]; - crc = (crc >>> 8) ^ b; - } - return crc ^ -1; - } - - function writePngChunk(type, body, data, offset) { - var p = offset; - var len = body.length; - - data[p] = len >> 24 & 0xff; - data[p + 1] = len >> 16 & 0xff; - data[p + 2] = len >> 8 & 0xff; - data[p + 3] = len & 0xff; - p += 4; - - data[p] = type.charCodeAt(0) & 0xff; - data[p + 1] = type.charCodeAt(1) & 0xff; - data[p + 2] = type.charCodeAt(2) & 0xff; - data[p + 3] = type.charCodeAt(3) & 0xff; - p += 4; - - data.set(body, p); - p += body.length; - - var crc = crc32(data, offset + 4, p); - - data[p] = crc >> 24 & 0xff; - data[p + 1] = crc >> 16 & 0xff; - data[p + 2] = crc >> 8 & 0xff; - data[p + 3] = crc & 0xff; - } - - function adler32(data, start, end) { - var a = 1; - var b = 0; - for (var i = start; i < end; ++i) { - a = (a + (data[i] & 0xff)) % 65521; - b = (b + a) % 65521; - } - return (b << 16) | a; - } - - function encode(imgData, kind) { - var width = imgData.width; - var height = imgData.height; - var bitDepth, colorType, lineSize; - var bytes = imgData.data; - - switch (kind) { - case ImageKind.GRAYSCALE_1BPP: - colorType = 0; - bitDepth = 1; - lineSize = (width + 7) >> 3; - break; - case ImageKind.RGB_24BPP: - colorType = 2; - bitDepth = 8; - lineSize = width * 3; - break; - case ImageKind.RGBA_32BPP: - colorType = 6; - bitDepth = 8; - lineSize = width * 4; - break; - default: - throw new Error('invalid format'); - } - - // prefix every row with predictor 0 - var literals = new Uint8Array((1 + lineSize) * height); - var offsetLiterals = 0, offsetBytes = 0; - var y, i; - for (y = 0; y < height; ++y) { - literals[offsetLiterals++] = 0; // no prediction - literals.set(bytes.subarray(offsetBytes, offsetBytes + lineSize), - offsetLiterals); - offsetBytes += lineSize; - offsetLiterals += lineSize; - } - - if (kind === ImageKind.GRAYSCALE_1BPP) { - // inverting for B/W - offsetLiterals = 0; - for (y = 0; y < height; y++) { - offsetLiterals++; // skipping predictor - for (i = 0; i < lineSize; i++) { - literals[offsetLiterals++] ^= 0xFF; - } - } - } - - var ihdr = new Uint8Array([ - width >> 24 & 0xff, - width >> 16 & 0xff, - width >> 8 & 0xff, - width & 0xff, - height >> 24 & 0xff, - height >> 16 & 0xff, - height >> 8 & 0xff, - height & 0xff, - bitDepth, // bit depth - colorType, // color type - 0x00, // compression method - 0x00, // filter method - 0x00 // interlace method - ]); - - var len = literals.length; - var maxBlockLength = 0xFFFF; - - var deflateBlocks = Math.ceil(len / maxBlockLength); - var idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4); - var pi = 0; - idat[pi++] = 0x78; // compression method and flags - idat[pi++] = 0x9c; // flags - - var pos = 0; - while (len > maxBlockLength) { - // writing non-final DEFLATE blocks type 0 and length of 65535 - idat[pi++] = 0x00; - idat[pi++] = 0xff; - idat[pi++] = 0xff; - idat[pi++] = 0x00; - idat[pi++] = 0x00; - idat.set(literals.subarray(pos, pos + maxBlockLength), pi); - pi += maxBlockLength; - pos += maxBlockLength; - len -= maxBlockLength; - } - - // writing non-final DEFLATE blocks type 0 - idat[pi++] = 0x01; - idat[pi++] = len & 0xff; - idat[pi++] = len >> 8 & 0xff; - idat[pi++] = (~len & 0xffff) & 0xff; - idat[pi++] = (~len & 0xffff) >> 8 & 0xff; - idat.set(literals.subarray(pos), pi); - pi += literals.length - pos; - - var adler = adler32(literals, 0, literals.length); // checksum - idat[pi++] = adler >> 24 & 0xff; - idat[pi++] = adler >> 16 & 0xff; - idat[pi++] = adler >> 8 & 0xff; - idat[pi++] = adler & 0xff; - - // PNG will consists: header, IHDR+data, IDAT+data, and IEND. - var pngLength = PNG_HEADER.length + (CHUNK_WRAPPER_SIZE * 3) + - ihdr.length + idat.length; - var data = new Uint8Array(pngLength); - var offset = 0; - data.set(PNG_HEADER, offset); - offset += PNG_HEADER.length; - writePngChunk('IHDR', ihdr, data, offset); - offset += CHUNK_WRAPPER_SIZE + ihdr.length; - writePngChunk('IDATA', idat, data, offset); - offset += CHUNK_WRAPPER_SIZE + idat.length; - writePngChunk('IEND', new Uint8Array(0), data, offset); - - return PDFJS.createObjectURL(data, 'image/png'); - } - - return function convertImgDataToPng(imgData) { - var kind = (imgData.kind === undefined ? - ImageKind.GRAYSCALE_1BPP : imgData.kind); - return encode(imgData, kind); - }; -})(); - -var SVGExtraState = (function SVGExtraStateClosure() { - function SVGExtraState() { - this.fontSizeScale = 1; - this.fontWeight = SVG_DEFAULTS.fontWeight; - this.fontSize = 0; - - this.textMatrix = IDENTITY_MATRIX; - this.fontMatrix = FONT_IDENTITY_MATRIX; - this.leading = 0; - - // Current point (in user coordinates) - this.x = 0; - this.y = 0; - - // Start of text line (in text coordinates) - this.lineX = 0; - this.lineY = 0; - - // Character and word spacing - this.charSpacing = 0; - this.wordSpacing = 0; - this.textHScale = 1; - this.textRise = 0; - - // Default foreground and background colors - this.fillColor = SVG_DEFAULTS.fillColor; - this.strokeColor = '#000000'; - - this.fillAlpha = 1; - this.strokeAlpha = 1; - this.lineWidth = 1; - this.lineJoin = ''; - this.lineCap = ''; - this.miterLimit = 0; - - this.dashArray = []; - this.dashPhase = 0; - - this.dependencies = []; - - // Clipping - this.clipId = ''; - this.pendingClip = false; - - this.maskId = ''; - } - - SVGExtraState.prototype = { - clone: function SVGExtraState_clone() { - return Object.create(this); - }, - setCurrentPoint: function SVGExtraState_setCurrentPoint(x, y) { - this.x = x; - this.y = y; - } - }; - return SVGExtraState; -})(); - -var SVGGraphics = (function SVGGraphicsClosure() { - function createScratchSVG(width, height) { - var NS = 'http://www.w3.org/2000/svg'; - var svg = document.createElementNS(NS, 'svg:svg'); - svg.setAttributeNS(null, 'version', '1.1'); - svg.setAttributeNS(null, 'width', width + 'px'); - svg.setAttributeNS(null, 'height', height + 'px'); - svg.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height); - return svg; - } - - function opListToTree(opList) { - var opTree = []; - var tmp = []; - var opListLen = opList.length; - - for (var x = 0; x < opListLen; x++) { - if (opList[x].fn === 'save') { - opTree.push({'fnId': 92, 'fn': 'group', 'items': []}); - tmp.push(opTree); - opTree = opTree[opTree.length - 1].items; - continue; - } - - if(opList[x].fn === 'restore') { - opTree = tmp.pop(); - } else { - opTree.push(opList[x]); - } - } - return opTree; - } - - /** - * Formats float number. - * @param value {number} number to format. - * @returns {string} - */ - function pf(value) { - if (value === (value | 0)) { // integer number - return value.toString(); - } - var s = value.toFixed(10); - var i = s.length - 1; - if (s[i] !== '0') { - return s; - } - // removing trailing zeros - do { - i--; - } while (s[i] === '0'); - return s.substr(0, s[i] === '.' ? i : i + 1); - } - - /** - * Formats transform matrix. The standard rotation, scale and translate - * matrices are replaced by their shorter forms, and for identity matrix - * returns empty string to save the memory. - * @param m {Array} matrix to format. - * @returns {string} - */ - function pm(m) { - if (m[4] === 0 && m[5] === 0) { - if (m[1] === 0 && m[2] === 0) { - if (m[0] === 1 && m[3] === 1) { - return ''; - } - return 'scale(' + pf(m[0]) + ' ' + pf(m[3]) + ')'; - } - if (m[0] === m[3] && m[1] === -m[2]) { - var a = Math.acos(m[0]) * 180 / Math.PI; - return 'rotate(' + pf(a) + ')'; - } - } else { - if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) { - return 'translate(' + pf(m[4]) + ' ' + pf(m[5]) + ')'; - } - } - return 'matrix(' + pf(m[0]) + ' ' + pf(m[1]) + ' ' + pf(m[2]) + ' ' + - pf(m[3]) + ' ' + pf(m[4]) + ' ' + pf(m[5]) + ')'; - } - - function SVGGraphics(commonObjs, objs) { - this.current = new SVGExtraState(); - this.transformMatrix = IDENTITY_MATRIX; // Graphics state matrix - this.transformStack = []; - this.extraStack = []; - this.commonObjs = commonObjs; - this.objs = objs; - this.pendingEOFill = false; - - this.embedFonts = false; - this.embeddedFonts = {}; - this.cssStyle = null; - } - - var NS = 'http://www.w3.org/2000/svg'; - var XML_NS = 'http://www.w3.org/XML/1998/namespace'; - var XLINK_NS = 'http://www.w3.org/1999/xlink'; - var LINE_CAP_STYLES = ['butt', 'round', 'square']; - var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; - var clipCount = 0; - var maskCount = 0; - - SVGGraphics.prototype = { - save: function SVGGraphics_save() { - this.transformStack.push(this.transformMatrix); - var old = this.current; - this.extraStack.push(old); - this.current = old.clone(); - }, - - restore: function SVGGraphics_restore() { - this.transformMatrix = this.transformStack.pop(); - this.current = this.extraStack.pop(); - - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - this.pgrp.appendChild(this.tgrp); - }, - - group: function SVGGraphics_group(items) { - this.save(); - this.executeOpTree(items); - this.restore(); - }, - - loadDependencies: function SVGGraphics_loadDependencies(operatorList) { - var fnArray = operatorList.fnArray; - var fnArrayLen = fnArray.length; - var argsArray = operatorList.argsArray; - - var self = this; - for (var i = 0; i < fnArrayLen; i++) { - if (OPS.dependency === fnArray[i]) { - var deps = argsArray[i]; - for (var n = 0, nn = deps.length; n < nn; n++) { - var obj = deps[n]; - var common = obj.substring(0, 2) === 'g_'; - var promise; - if (common) { - promise = new Promise(function(resolve) { - self.commonObjs.get(obj, resolve); - }); - } else { - promise = new Promise(function(resolve) { - self.objs.get(obj, resolve); - }); - } - this.current.dependencies.push(promise); - } - } - } - return Promise.all(this.current.dependencies); - }, - - transform: function SVGGraphics_transform(a, b, c, d, e, f) { - var transformMatrix = [a, b, c, d, e, f]; - this.transformMatrix = PDFJS.Util.transform(this.transformMatrix, - transformMatrix); - - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - }, - - getSVG: function SVGGraphics_getSVG(operatorList, viewport) { - this.svg = createScratchSVG(viewport.width, viewport.height); - this.viewport = viewport; - - return this.loadDependencies(operatorList).then(function () { - this.transformMatrix = IDENTITY_MATRIX; - this.pgrp = document.createElementNS(NS, 'svg:g'); // Parent group - this.pgrp.setAttributeNS(null, 'transform', pm(viewport.transform)); - this.tgrp = document.createElementNS(NS, 'svg:g'); // Transform group - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - this.defs = document.createElementNS(NS, 'svg:defs'); - this.pgrp.appendChild(this.defs); - this.pgrp.appendChild(this.tgrp); - this.svg.appendChild(this.pgrp); - var opTree = this.convertOpList(operatorList); - this.executeOpTree(opTree); - return this.svg; - }.bind(this)); - }, - - convertOpList: function SVGGraphics_convertOpList(operatorList) { - var argsArray = operatorList.argsArray; - var fnArray = operatorList.fnArray; - var fnArrayLen = fnArray.length; - var REVOPS = []; - var opList = []; - - for (var op in OPS) { - REVOPS[OPS[op]] = op; - } - - for (var x = 0; x < fnArrayLen; x++) { - var fnId = fnArray[x]; - opList.push({'fnId' : fnId, 'fn': REVOPS[fnId], 'args': argsArray[x]}); - } - return opListToTree(opList); - }, - - executeOpTree: function SVGGraphics_executeOpTree(opTree) { - var opTreeLen = opTree.length; - for(var x = 0; x < opTreeLen; x++) { - var fn = opTree[x].fn; - var fnId = opTree[x].fnId; - var args = opTree[x].args; - - switch (fnId | 0) { - case OPS.beginText: - this.beginText(); - break; - case OPS.setLeading: - this.setLeading(args); - break; - case OPS.setLeadingMoveText: - this.setLeadingMoveText(args[0], args[1]); - break; - case OPS.setFont: - this.setFont(args); - break; - case OPS.showText: - this.showText(args[0]); - break; - case OPS.showSpacedText: - this.showText(args[0]); - break; - case OPS.endText: - this.endText(); - break; - case OPS.moveText: - this.moveText(args[0], args[1]); - break; - case OPS.setCharSpacing: - this.setCharSpacing(args[0]); - break; - case OPS.setWordSpacing: - this.setWordSpacing(args[0]); - break; - case OPS.setHScale: - this.setHScale(args[0]); - break; - case OPS.setTextMatrix: - this.setTextMatrix(args[0], args[1], args[2], - args[3], args[4], args[5]); - break; - case OPS.setLineWidth: - this.setLineWidth(args[0]); - break; - case OPS.setLineJoin: - this.setLineJoin(args[0]); - break; - case OPS.setLineCap: - this.setLineCap(args[0]); - break; - case OPS.setMiterLimit: - this.setMiterLimit(args[0]); - break; - case OPS.setFillRGBColor: - this.setFillRGBColor(args[0], args[1], args[2]); - break; - case OPS.setStrokeRGBColor: - this.setStrokeRGBColor(args[0], args[1], args[2]); - break; - case OPS.setDash: - this.setDash(args[0], args[1]); - break; - case OPS.setGState: - this.setGState(args[0]); - break; - case OPS.fill: - this.fill(); - break; - case OPS.eoFill: - this.eoFill(); - break; - case OPS.stroke: - this.stroke(); - break; - case OPS.fillStroke: - this.fillStroke(); - break; - case OPS.eoFillStroke: - this.eoFillStroke(); - break; - case OPS.clip: - this.clip('nonzero'); - break; - case OPS.eoClip: - this.clip('evenodd'); - break; - case OPS.paintSolidColorImageMask: - this.paintSolidColorImageMask(); - break; - case OPS.paintJpegXObject: - this.paintJpegXObject(args[0], args[1], args[2]); - break; - case OPS.paintImageXObject: - this.paintImageXObject(args[0]); - break; - case OPS.paintInlineImageXObject: - this.paintInlineImageXObject(args[0]); - break; - case OPS.paintImageMaskXObject: - this.paintImageMaskXObject(args[0]); - break; - case OPS.paintFormXObjectBegin: - this.paintFormXObjectBegin(args[0], args[1]); - break; - case OPS.paintFormXObjectEnd: - this.paintFormXObjectEnd(); - break; - case OPS.closePath: - this.closePath(); - break; - case OPS.closeStroke: - this.closeStroke(); - break; - case OPS.closeFillStroke: - this.closeFillStroke(); - break; - case OPS.nextLine: - this.nextLine(); - break; - case OPS.transform: - this.transform(args[0], args[1], args[2], args[3], - args[4], args[5]); - break; - case OPS.constructPath: - this.constructPath(args[0], args[1]); - break; - case OPS.endPath: - this.endPath(); - break; - case 92: - this.group(opTree[x].items); - break; - default: - warn('Unimplemented method '+ fn); - break; - } - } - }, - - setWordSpacing: function SVGGraphics_setWordSpacing(wordSpacing) { - this.current.wordSpacing = wordSpacing; - }, - - setCharSpacing: function SVGGraphics_setCharSpacing(charSpacing) { - this.current.charSpacing = charSpacing; - }, - - nextLine: function SVGGraphics_nextLine() { - this.moveText(0, this.current.leading); - }, - - setTextMatrix: function SVGGraphics_setTextMatrix(a, b, c, d, e, f) { - var current = this.current; - this.current.textMatrix = this.current.lineMatrix = [a, b, c, d, e, f]; - - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; - - current.xcoords = []; - current.tspan = document.createElementNS(NS, 'svg:tspan'); - current.tspan.setAttributeNS(null, 'font-family', current.fontFamily); - current.tspan.setAttributeNS(null, 'font-size', - pf(current.fontSize) + 'px'); - current.tspan.setAttributeNS(null, 'y', pf(-current.y)); - - current.txtElement = document.createElementNS(NS, 'svg:text'); - current.txtElement.appendChild(current.tspan); - }, - - beginText: function SVGGraphics_beginText() { - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; - this.current.textMatrix = IDENTITY_MATRIX; - this.current.lineMatrix = IDENTITY_MATRIX; - this.current.tspan = document.createElementNS(NS, 'svg:tspan'); - this.current.txtElement = document.createElementNS(NS, 'svg:text'); - this.current.txtgrp = document.createElementNS(NS, 'svg:g'); - this.current.xcoords = []; - }, - - moveText: function SVGGraphics_moveText(x, y) { - var current = this.current; - this.current.x = this.current.lineX += x; - this.current.y = this.current.lineY += y; - - current.xcoords = []; - current.tspan = document.createElementNS(NS, 'svg:tspan'); - current.tspan.setAttributeNS(null, 'font-family', current.fontFamily); - current.tspan.setAttributeNS(null, 'font-size', - pf(current.fontSize) + 'px'); - current.tspan.setAttributeNS(null, 'y', pf(-current.y)); - }, - - showText: function SVGGraphics_showText(glyphs) { - var current = this.current; - var font = current.font; - var fontSize = current.fontSize; - - if (fontSize === 0) { - return; - } - - var charSpacing = current.charSpacing; - var wordSpacing = current.wordSpacing; - var fontDirection = current.fontDirection; - var textHScale = current.textHScale * fontDirection; - var glyphsLength = glyphs.length; - var vertical = font.vertical; - var widthAdvanceScale = fontSize * current.fontMatrix[0]; - - var x = 0, i; - for (i = 0; i < glyphsLength; ++i) { - var glyph = glyphs[i]; - if (glyph === null) { - // word break - x += fontDirection * wordSpacing; - continue; - } else if (isNum(glyph)) { - x += -glyph * fontSize * 0.001; - continue; - } - current.xcoords.push(current.x + x * textHScale); - - var width = glyph.width; - var character = glyph.fontChar; - var charWidth = width * widthAdvanceScale + charSpacing * fontDirection; - x += charWidth; - - current.tspan.textContent += character; - } - if (vertical) { - current.y -= x * textHScale; - } else { - current.x += x * textHScale; - } - - current.tspan.setAttributeNS(null, 'x', - current.xcoords.map(pf).join(' ')); - current.tspan.setAttributeNS(null, 'y', pf(-current.y)); - current.tspan.setAttributeNS(null, 'font-family', current.fontFamily); - current.tspan.setAttributeNS(null, 'font-size', - pf(current.fontSize) + 'px'); - if (current.fontStyle !== SVG_DEFAULTS.fontStyle) { - current.tspan.setAttributeNS(null, 'font-style', current.fontStyle); - } - if (current.fontWeight !== SVG_DEFAULTS.fontWeight) { - current.tspan.setAttributeNS(null, 'font-weight', current.fontWeight); - } - if (current.fillColor !== SVG_DEFAULTS.fillColor) { - current.tspan.setAttributeNS(null, 'fill', current.fillColor); - } - - current.txtElement.setAttributeNS(null, 'transform', - pm(current.textMatrix) + - ' scale(1, -1)' ); - current.txtElement.setAttributeNS(XML_NS, 'xml:space', 'preserve'); - current.txtElement.appendChild(current.tspan); - current.txtgrp.appendChild(current.txtElement); - - this.tgrp.appendChild(current.txtElement); - - }, - - setLeadingMoveText: function SVGGraphics_setLeadingMoveText(x, y) { - this.setLeading(-y); - this.moveText(x, y); - }, - - addFontStyle: function SVGGraphics_addFontStyle(fontObj) { - if (!this.cssStyle) { - this.cssStyle = document.createElementNS(NS, 'svg:style'); - this.cssStyle.setAttributeNS(null, 'type', 'text/css'); - this.defs.appendChild(this.cssStyle); - } - - var url = PDFJS.createObjectURL(fontObj.data, fontObj.mimetype); - this.cssStyle.textContent += - '@font-face { font-family: "' + fontObj.loadedName + '";' + - ' src: url(' + url + '); }\n'; - }, - - setFont: function SVGGraphics_setFont(details) { - var current = this.current; - var fontObj = this.commonObjs.get(details[0]); - var size = details[1]; - this.current.font = fontObj; - - if (this.embedFonts && fontObj.data && - !this.embeddedFonts[fontObj.loadedName]) { - this.addFontStyle(fontObj); - this.embeddedFonts[fontObj.loadedName] = fontObj; - } - - current.fontMatrix = (fontObj.fontMatrix ? - fontObj.fontMatrix : FONT_IDENTITY_MATRIX); - - var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') : - (fontObj.bold ? 'bold' : 'normal'); - var italic = fontObj.italic ? 'italic' : 'normal'; - - if (size < 0) { - size = -size; - current.fontDirection = -1; - } else { - current.fontDirection = 1; - } - current.fontSize = size; - current.fontFamily = fontObj.loadedName; - current.fontWeight = bold; - current.fontStyle = italic; - - current.tspan = document.createElementNS(NS, 'svg:tspan'); - current.tspan.setAttributeNS(null, 'y', pf(-current.y)); - current.xcoords = []; - }, - - endText: function SVGGraphics_endText() { - if (this.current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - }, - - // Path properties - setLineWidth: function SVGGraphics_setLineWidth(width) { - this.current.lineWidth = width; - }, - setLineCap: function SVGGraphics_setLineCap(style) { - this.current.lineCap = LINE_CAP_STYLES[style]; - }, - setLineJoin: function SVGGraphics_setLineJoin(style) { - this.current.lineJoin = LINE_JOIN_STYLES[style]; - }, - setMiterLimit: function SVGGraphics_setMiterLimit(limit) { - this.current.miterLimit = limit; - }, - setStrokeRGBColor: function SVGGraphics_setStrokeRGBColor(r, g, b) { - var color = Util.makeCssRgb(r, g, b); - this.current.strokeColor = color; - }, - setFillRGBColor: function SVGGraphics_setFillRGBColor(r, g, b) { - var color = Util.makeCssRgb(r, g, b); - this.current.fillColor = color; - this.current.tspan = document.createElementNS(NS, 'svg:tspan'); - this.current.xcoords = []; - }, - setDash: function SVGGraphics_setDash(dashArray, dashPhase) { - this.current.dashArray = dashArray; - this.current.dashPhase = dashPhase; - }, - - constructPath: function SVGGraphics_constructPath(ops, args) { - var current = this.current; - var x = current.x, y = current.y; - current.path = document.createElementNS(NS, 'svg:path'); - var d = []; - var opLength = ops.length; - - for (var i = 0, j = 0; i < opLength; i++) { - switch (ops[i] | 0) { - case OPS.rectangle: - x = args[j++]; - y = args[j++]; - var width = args[j++]; - var height = args[j++]; - var xw = x + width; - var yh = y + height; - d.push('M', pf(x), pf(y), 'L', pf(xw) , pf(y), 'L', pf(xw), pf(yh), - 'L', pf(x), pf(yh), 'Z'); - break; - case OPS.moveTo: - x = args[j++]; - y = args[j++]; - d.push('M', pf(x), pf(y)); - break; - case OPS.lineTo: - x = args[j++]; - y = args[j++]; - d.push('L', pf(x) , pf(y)); - break; - case OPS.curveTo: - x = args[j + 4]; - y = args[j + 5]; - d.push('C', pf(args[j]), pf(args[j + 1]), pf(args[j + 2]), - pf(args[j + 3]), pf(x), pf(y)); - j += 6; - break; - case OPS.curveTo2: - x = args[j + 2]; - y = args[j + 3]; - d.push('C', pf(x), pf(y), pf(args[j]), pf(args[j + 1]), - pf(args[j + 2]), pf(args[j + 3])); - j += 4; - break; - case OPS.curveTo3: - x = args[j + 2]; - y = args[j + 3]; - d.push('C', pf(args[j]), pf(args[j + 1]), pf(x), pf(y), - pf(x), pf(y)); - j += 4; - break; - case OPS.closePath: - d.push('Z'); - break; - } - } - current.path.setAttributeNS(null, 'd', d.join(' ')); - current.path.setAttributeNS(null, 'stroke-miterlimit', - pf(current.miterLimit)); - current.path.setAttributeNS(null, 'stroke-linecap', current.lineCap); - current.path.setAttributeNS(null, 'stroke-linejoin', current.lineJoin); - current.path.setAttributeNS(null, 'stroke-width', - pf(current.lineWidth) + 'px'); - current.path.setAttributeNS(null, 'stroke-dasharray', - current.dashArray.map(pf).join(' ')); - current.path.setAttributeNS(null, 'stroke-dashoffset', - pf(current.dashPhase) + 'px'); - current.path.setAttributeNS(null, 'fill', 'none'); - - this.tgrp.appendChild(current.path); - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - // Saving a reference in current.element so that it can be addressed - // in 'fill' and 'stroke' - current.element = current.path; - current.setCurrentPoint(x, y); - }, - - endPath: function SVGGraphics_endPath() { - var current = this.current; - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - this.tgrp = document.createElementNS(NS, 'svg:g'); - this.tgrp.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - }, - - clip: function SVGGraphics_clip(type) { - var current = this.current; - // Add current path to clipping path - current.clipId = 'clippath' + clipCount; - clipCount++; - this.clippath = document.createElementNS(NS, 'svg:clipPath'); - this.clippath.setAttributeNS(null, 'id', current.clipId); - var clipElement = current.element.cloneNode(); - if (type === 'evenodd') { - clipElement.setAttributeNS(null, 'clip-rule', 'evenodd'); - } else { - clipElement.setAttributeNS(null, 'clip-rule', 'nonzero'); - } - this.clippath.setAttributeNS(null, 'transform', pm(this.transformMatrix)); - this.clippath.appendChild(clipElement); - this.defs.appendChild(this.clippath); - - // Create a new group with that attribute - current.pendingClip = true; - this.cgrp = document.createElementNS(NS, 'svg:g'); - this.cgrp.setAttributeNS(null, 'clip-path', - 'url(#' + current.clipId + ')'); - this.pgrp.appendChild(this.cgrp); - }, - - closePath: function SVGGraphics_closePath() { - var current = this.current; - var d = current.path.getAttributeNS(null, 'd'); - d += 'Z'; - current.path.setAttributeNS(null, 'd', d); - }, - - setLeading: function SVGGraphics_setLeading(leading) { - this.current.leading = -leading; - }, - - setTextRise: function SVGGraphics_setTextRise(textRise) { - this.current.textRise = textRise; - }, - - setHScale: function SVGGraphics_setHScale(scale) { - this.current.textHScale = scale / 100; - }, - - setGState: function SVGGraphics_setGState(states) { - for (var i = 0, ii = states.length; i < ii; i++) { - var state = states[i]; - var key = state[0]; - var value = state[1]; - - switch (key) { - case 'LW': - this.setLineWidth(value); - break; - case 'LC': - this.setLineCap(value); - break; - case 'LJ': - this.setLineJoin(value); - break; - case 'ML': - this.setMiterLimit(value); - break; - case 'D': - this.setDash(value[0], value[1]); - break; - case 'RI': - break; - case 'FL': - break; - case 'Font': - this.setFont(value); - break; - case 'CA': - break; - case 'ca': - break; - case 'BM': - break; - case 'SMask': - break; - } - } - }, - - fill: function SVGGraphics_fill() { - var current = this.current; - current.element.setAttributeNS(null, 'fill', current.fillColor); - }, - - stroke: function SVGGraphics_stroke() { - var current = this.current; - current.element.setAttributeNS(null, 'stroke', current.strokeColor); - current.element.setAttributeNS(null, 'fill', 'none'); - }, - - eoFill: function SVGGraphics_eoFill() { - var current = this.current; - current.element.setAttributeNS(null, 'fill', current.fillColor); - current.element.setAttributeNS(null, 'fill-rule', 'evenodd'); - }, - - fillStroke: function SVGGraphics_fillStroke() { - // Order is important since stroke wants fill to be none. - // First stroke, then if fill needed, it will be overwritten. - this.stroke(); - this.fill(); - }, - - eoFillStroke: function SVGGraphics_eoFillStroke() { - this.current.element.setAttributeNS(null, 'fill-rule', 'evenodd'); - this.fillStroke(); - }, - - closeStroke: function SVGGraphics_closeStroke() { - this.closePath(); - this.stroke(); - }, - - closeFillStroke: function SVGGraphics_closeFillStroke() { - this.closePath(); - this.fillStroke(); - }, - - paintSolidColorImageMask: - function SVGGraphics_paintSolidColorImageMask() { - var current = this.current; - var rect = document.createElementNS(NS, 'svg:rect'); - rect.setAttributeNS(null, 'x', '0'); - rect.setAttributeNS(null, 'y', '0'); - rect.setAttributeNS(null, 'width', '1px'); - rect.setAttributeNS(null, 'height', '1px'); - rect.setAttributeNS(null, 'fill', current.fillColor); - this.tgrp.appendChild(rect); - }, - - paintJpegXObject: function SVGGraphics_paintJpegXObject(objId, w, h) { - var current = this.current; - var imgObj = this.objs.get(objId); - var imgEl = document.createElementNS(NS, 'svg:image'); - imgEl.setAttributeNS(XLINK_NS, 'xlink:href', imgObj.src); - imgEl.setAttributeNS(null, 'width', imgObj.width + 'px'); - imgEl.setAttributeNS(null, 'height', imgObj.height + 'px'); - imgEl.setAttributeNS(null, 'x', '0'); - imgEl.setAttributeNS(null, 'y', pf(-h)); - imgEl.setAttributeNS(null, 'transform', - 'scale(' + pf(1 / w) + ' ' + pf(-1 / h) + ')'); - - this.tgrp.appendChild(imgEl); - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - }, - - paintImageXObject: function SVGGraphics_paintImageXObject(objId) { - var imgData = this.objs.get(objId); - if (!imgData) { - warn('Dependent image isn\'t ready yet'); - return; - } - this.paintInlineImageXObject(imgData); - }, - - paintInlineImageXObject: - function SVGGraphics_paintInlineImageXObject(imgData, mask) { - var current = this.current; - var width = imgData.width; - var height = imgData.height; - - var imgSrc = convertImgDataToPng(imgData); - var cliprect = document.createElementNS(NS, 'svg:rect'); - cliprect.setAttributeNS(null, 'x', '0'); - cliprect.setAttributeNS(null, 'y', '0'); - cliprect.setAttributeNS(null, 'width', pf(width)); - cliprect.setAttributeNS(null, 'height', pf(height)); - current.element = cliprect; - this.clip('nonzero'); - var imgEl = document.createElementNS(NS, 'svg:image'); - imgEl.setAttributeNS(XLINK_NS, 'xlink:href', imgSrc); - imgEl.setAttributeNS(null, 'x', '0'); - imgEl.setAttributeNS(null, 'y', pf(-height)); - imgEl.setAttributeNS(null, 'width', pf(width) + 'px'); - imgEl.setAttributeNS(null, 'height', pf(height) + 'px'); - imgEl.setAttributeNS(null, 'transform', - 'scale(' + pf(1 / width) + ' ' + - pf(-1 / height) + ')'); - if (mask) { - mask.appendChild(imgEl); - } else { - this.tgrp.appendChild(imgEl); - } - if (current.pendingClip) { - this.cgrp.appendChild(this.tgrp); - this.pgrp.appendChild(this.cgrp); - } else { - this.pgrp.appendChild(this.tgrp); - } - }, - - paintImageMaskXObject: - function SVGGraphics_paintImageMaskXObject(imgData) { - var current = this.current; - var width = imgData.width; - var height = imgData.height; - var fillColor = current.fillColor; - - current.maskId = 'mask' + maskCount++; - var mask = document.createElementNS(NS, 'svg:mask'); - mask.setAttributeNS(null, 'id', current.maskId); - - var rect = document.createElementNS(NS, 'svg:rect'); - rect.setAttributeNS(null, 'x', '0'); - rect.setAttributeNS(null, 'y', '0'); - rect.setAttributeNS(null, 'width', pf(width)); - rect.setAttributeNS(null, 'height', pf(height)); - rect.setAttributeNS(null, 'fill', fillColor); - rect.setAttributeNS(null, 'mask', 'url(#' + current.maskId +')'); - this.defs.appendChild(mask); - this.tgrp.appendChild(rect); - - this.paintInlineImageXObject(imgData, mask); - }, - - paintFormXObjectBegin: - function SVGGraphics_paintFormXObjectBegin(matrix, bbox) { - this.save(); - - if (isArray(matrix) && matrix.length === 6) { - this.transform(matrix[0], matrix[1], matrix[2], - matrix[3], matrix[4], matrix[5]); - } - - if (isArray(bbox) && bbox.length === 4) { - var width = bbox[2] - bbox[0]; - var height = bbox[3] - bbox[1]; - - var cliprect = document.createElementNS(NS, 'svg:rect'); - cliprect.setAttributeNS(null, 'x', bbox[0]); - cliprect.setAttributeNS(null, 'y', bbox[1]); - cliprect.setAttributeNS(null, 'width', pf(width)); - cliprect.setAttributeNS(null, 'height', pf(height)); - this.current.element = cliprect; - this.clip('nonzero'); - this.endPath(); - } - }, - - paintFormXObjectEnd: - function SVGGraphics_paintFormXObjectEnd() { - this.restore(); - } - }; - return SVGGraphics; -})(); - -PDFJS.SVGGraphics = SVGGraphics; -//#endif - - -}).call((typeof window === 'undefined') ? this : window); - -if (!PDFJS.workerSrc && typeof document !== 'undefined') { - // workerSrc is not set -- using last script url to define default location - PDFJS.workerSrc = (function () { - 'use strict'; - var scriptTagContainer = document.body || - document.getElementsByTagName('head')[0]; - var pdfjsSrc = scriptTagContainer.lastChild.src; - return pdfjsSrc && pdfjsSrc.replace(/\.js$/i, '.worker.js'); - })(); -} - diff --git a/plugins/pdf_viewer/v/pdf.worker.js b/plugins/pdf_viewer/v/pdf.worker.js deleted file mode 100755 index c17192e..0000000 --- a/plugins/pdf_viewer/v/pdf.worker.js +++ /dev/null @@ -1,39353 +0,0 @@ -/* -*- 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()); - } -}); - -//#if !(FIREFOX || MOZCENTRAL || B2G || CHROME) -//// 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; -})(); -//#else -//PDFJS.hasCanvasTypedArrays = true; -//#endif - -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; - } -//#if !MOZCENTRAL - 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; -//#else -//throw new Error('DOM Promise is not present'); -//#endif -})(); - -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; -} - - - -//#if (FIREFOX || MOZCENTRAL) -// -//Components.utils.import('resource://gre/modules/Services.jsm'); -// -//var EXPORTED_SYMBOLS = ['NetworkManager']; -// -//var console = { -// log: function console_log(aMsg) { -// var msg = 'network.js: ' + (aMsg.join ? aMsg.join('') : aMsg); -// Services.console.logStringMessage(msg); -// // TODO(mack): dump() doesn't seem to work here... -// dump(msg + '\n'); -// } -//} -//#endif - -var NetworkManager = (function NetworkManagerClosure() { - - var OK_RESPONSE = 200; - var PARTIAL_CONTENT_RESPONSE = 206; - - function NetworkManager(url, args) { - this.url = url; - args = args || {}; - this.isHttp = /^https?:/i.test(url); - this.httpHeaders = (this.isHttp && args.httpHeaders) || {}; - this.withCredentials = args.withCredentials || false; - this.getXhr = args.getXhr || - function NetworkManager_getXhr() { -//#if B2G -// return new XMLHttpRequest({ mozSystem: true }); -//#else - return new XMLHttpRequest(); -//#endif - }; - - this.currXhrId = 0; - this.pendingRequests = {}; - this.loadedRequests = {}; - } - - function getArrayBuffer(xhr) { - var data = xhr.response; - if (typeof data !== 'string') { - return data; - } - var length = data.length; - var array = new Uint8Array(length); - for (var i = 0; i < length; i++) { - array[i] = data.charCodeAt(i) & 0xFF; - } - return array.buffer; - } - - NetworkManager.prototype = { - requestRange: function NetworkManager_requestRange(begin, end, listeners) { - var args = { - begin: begin, - end: end - }; - for (var prop in listeners) { - args[prop] = listeners[prop]; - } - return this.request(args); - }, - - requestFull: function NetworkManager_requestFull(listeners) { - return this.request(listeners); - }, - - request: function NetworkManager_request(args) { - var xhr = this.getXhr(); - var xhrId = this.currXhrId++; - var pendingRequest = this.pendingRequests[xhrId] = { - xhr: xhr - }; - - xhr.open('GET', this.url); - xhr.withCredentials = this.withCredentials; - for (var property in this.httpHeaders) { - var value = this.httpHeaders[property]; - if (typeof value === 'undefined') { - continue; - } - xhr.setRequestHeader(property, value); - } - if (this.isHttp && 'begin' in args && 'end' in args) { - var rangeStr = args.begin + '-' + (args.end - 1); - xhr.setRequestHeader('Range', 'bytes=' + rangeStr); - pendingRequest.expectedStatus = 206; - } else { - pendingRequest.expectedStatus = 200; - } - - if (args.onProgressiveData) { - // Some legacy browsers might throw an exception. - try { - xhr.responseType = 'moz-chunked-arraybuffer'; - } catch(e) {} - if (xhr.responseType === 'moz-chunked-arraybuffer') { - pendingRequest.onProgressiveData = args.onProgressiveData; - pendingRequest.mozChunked = true; - } else { - xhr.responseType = 'arraybuffer'; - } - } else { - xhr.responseType = 'arraybuffer'; - } - - if (args.onError) { - xhr.onerror = function(evt) { - args.onError(xhr.status); - }; - } - xhr.onreadystatechange = this.onStateChange.bind(this, xhrId); - xhr.onprogress = this.onProgress.bind(this, xhrId); - - pendingRequest.onHeadersReceived = args.onHeadersReceived; - pendingRequest.onDone = args.onDone; - pendingRequest.onError = args.onError; - pendingRequest.onProgress = args.onProgress; - - xhr.send(null); - - return xhrId; - }, - - onProgress: function NetworkManager_onProgress(xhrId, evt) { - var pendingRequest = this.pendingRequests[xhrId]; - if (!pendingRequest) { - // Maybe abortRequest was called... - return; - } - - if (pendingRequest.mozChunked) { - var chunk = getArrayBuffer(pendingRequest.xhr); - pendingRequest.onProgressiveData(chunk); - } - - var onProgress = pendingRequest.onProgress; - if (onProgress) { - onProgress(evt); - } - }, - - onStateChange: function NetworkManager_onStateChange(xhrId, evt) { - var pendingRequest = this.pendingRequests[xhrId]; - if (!pendingRequest) { - // Maybe abortRequest was called... - return; - } - - var xhr = pendingRequest.xhr; - if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { - pendingRequest.onHeadersReceived(); - delete pendingRequest.onHeadersReceived; - } - - if (xhr.readyState !== 4) { - return; - } - - if (!(xhrId in this.pendingRequests)) { - // The XHR request might have been aborted in onHeadersReceived() - // callback, in which case we should abort request - return; - } - - delete this.pendingRequests[xhrId]; - - // success status == 0 can be on ftp, file and other protocols - if (xhr.status === 0 && this.isHttp) { - if (pendingRequest.onError) { - pendingRequest.onError(xhr.status); - } - return; - } - var xhrStatus = xhr.status || OK_RESPONSE; - - // From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2: - // "A server MAY ignore the Range header". This means it's possible to - // get a 200 rather than a 206 response from a range request. - var ok_response_on_range_request = - xhrStatus === OK_RESPONSE && - pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; - - if (!ok_response_on_range_request && - xhrStatus !== pendingRequest.expectedStatus) { - if (pendingRequest.onError) { - pendingRequest.onError(xhr.status); - } - return; - } - - this.loadedRequests[xhrId] = true; - - var chunk = getArrayBuffer(xhr); - if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { - var rangeHeader = xhr.getResponseHeader('Content-Range'); - var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); - var begin = parseInt(matches[1], 10); - pendingRequest.onDone({ - begin: begin, - chunk: chunk - }); - } else if (pendingRequest.onProgressiveData) { - pendingRequest.onDone(null); - } else { - pendingRequest.onDone({ - begin: 0, - chunk: chunk - }); - } - }, - - hasPendingRequests: function NetworkManager_hasPendingRequests() { - for (var xhrId in this.pendingRequests) { - return true; - } - return false; - }, - - getRequestXhr: function NetworkManager_getXhr(xhrId) { - return this.pendingRequests[xhrId].xhr; - }, - - isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) { - return !!(this.pendingRequests[xhrId].onProgressiveData); - }, - - isPendingRequest: function NetworkManager_isPendingRequest(xhrId) { - return xhrId in this.pendingRequests; - }, - - isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) { - return xhrId in this.loadedRequests; - }, - - abortAllRequests: function NetworkManager_abortAllRequests() { - for (var xhrId in this.pendingRequests) { - this.abortRequest(xhrId | 0); - } - }, - - abortRequest: function NetworkManager_abortRequest(xhrId) { - var xhr = this.pendingRequests[xhrId].xhr; - delete this.pendingRequests[xhrId]; - xhr.abort(); - } - }; - - return NetworkManager; -})(); - - -var ChunkedStream = (function ChunkedStreamClosure() { - function ChunkedStream(length, chunkSize, manager) { - this.bytes = new Uint8Array(length); - this.start = 0; - this.pos = 0; - this.end = length; - this.chunkSize = chunkSize; - this.loadedChunks = []; - this.numChunksLoaded = 0; - this.numChunks = Math.ceil(length / chunkSize); - this.manager = manager; - this.progressiveDataLength = 0; - this.lastSuccessfulEnsureByteChunk = -1; // a single-entry cache - } - - // required methods for a stream. if a particular stream does not - // implement these, an error should be thrown - ChunkedStream.prototype = { - - getMissingChunks: function ChunkedStream_getMissingChunks() { - var chunks = []; - for (var chunk = 0, n = this.numChunks; chunk < n; ++chunk) { - if (!this.loadedChunks[chunk]) { - chunks.push(chunk); - } - } - return chunks; - }, - - getBaseStreams: function ChunkedStream_getBaseStreams() { - return [this]; - }, - - allChunksLoaded: function ChunkedStream_allChunksLoaded() { - return this.numChunksLoaded === this.numChunks; - }, - - onReceiveData: function ChunkedStream_onReceiveData(begin, chunk) { - var end = begin + chunk.byteLength; - - assert(begin % this.chunkSize === 0, 'Bad begin offset: ' + begin); - // Using this.length is inaccurate here since this.start can be moved - // See ChunkedStream.moveStart() - var length = this.bytes.length; - assert(end % this.chunkSize === 0 || end === length, - 'Bad end offset: ' + end); - - this.bytes.set(new Uint8Array(chunk), begin); - var chunkSize = this.chunkSize; - var beginChunk = Math.floor(begin / chunkSize); - var endChunk = Math.floor((end - 1) / chunkSize) + 1; - var curChunk; - - for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) { - if (!this.loadedChunks[curChunk]) { - this.loadedChunks[curChunk] = true; - ++this.numChunksLoaded; - } - } - }, - - onReceiveProgressiveData: - function ChunkedStream_onReceiveProgressiveData(data) { - var position = this.progressiveDataLength; - var beginChunk = Math.floor(position / this.chunkSize); - - this.bytes.set(new Uint8Array(data), position); - position += data.byteLength; - this.progressiveDataLength = position; - var endChunk = position >= this.end ? this.numChunks : - Math.floor(position / this.chunkSize); - var curChunk; - for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) { - if (!this.loadedChunks[curChunk]) { - this.loadedChunks[curChunk] = true; - ++this.numChunksLoaded; - } - } - }, - - ensureByte: function ChunkedStream_ensureByte(pos) { - var chunk = Math.floor(pos / this.chunkSize); - if (chunk === this.lastSuccessfulEnsureByteChunk) { - return; - } - - if (!this.loadedChunks[chunk]) { - throw new MissingDataException(pos, pos + 1); - } - this.lastSuccessfulEnsureByteChunk = chunk; - }, - - ensureRange: function ChunkedStream_ensureRange(begin, end) { - if (begin >= end) { - return; - } - - if (end <= this.progressiveDataLength) { - return; - } - - var chunkSize = this.chunkSize; - var beginChunk = Math.floor(begin / chunkSize); - var endChunk = Math.floor((end - 1) / chunkSize) + 1; - for (var chunk = beginChunk; chunk < endChunk; ++chunk) { - if (!this.loadedChunks[chunk]) { - throw new MissingDataException(begin, end); - } - } - }, - - nextEmptyChunk: function ChunkedStream_nextEmptyChunk(beginChunk) { - var chunk, n; - for (chunk = beginChunk, n = this.numChunks; chunk < n; ++chunk) { - if (!this.loadedChunks[chunk]) { - return chunk; - } - } - // Wrap around to beginning - for (chunk = 0; chunk < beginChunk; ++chunk) { - if (!this.loadedChunks[chunk]) { - return chunk; - } - } - return null; - }, - - hasChunk: function ChunkedStream_hasChunk(chunk) { - return !!this.loadedChunks[chunk]; - }, - - get length() { - return this.end - this.start; - }, - - get isEmpty() { - return this.length === 0; - }, - - getByte: function ChunkedStream_getByte() { - var pos = this.pos; - if (pos >= this.end) { - return -1; - } - this.ensureByte(pos); - return this.bytes[this.pos++]; - }, - - getUint16: function ChunkedStream_getUint16() { - var b0 = this.getByte(); - var b1 = this.getByte(); - if (b0 === -1 || b1 === -1) { - return -1; - } - return (b0 << 8) + b1; - }, - - getInt32: function ChunkedStream_getInt32() { - var b0 = this.getByte(); - var b1 = this.getByte(); - var b2 = this.getByte(); - var b3 = this.getByte(); - return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; - }, - - // returns subarray of original buffer - // should only be read - getBytes: function ChunkedStream_getBytes(length) { - var bytes = this.bytes; - var pos = this.pos; - var strEnd = this.end; - - if (!length) { - this.ensureRange(pos, strEnd); - return bytes.subarray(pos, strEnd); - } - - var end = pos + length; - if (end > strEnd) { - end = strEnd; - } - this.ensureRange(pos, end); - - this.pos = end; - return bytes.subarray(pos, end); - }, - - peekByte: function ChunkedStream_peekByte() { - var peekedByte = this.getByte(); - this.pos--; - return peekedByte; - }, - - peekBytes: function ChunkedStream_peekBytes(length) { - var bytes = this.getBytes(length); - this.pos -= bytes.length; - return bytes; - }, - - getByteRange: function ChunkedStream_getBytes(begin, end) { - this.ensureRange(begin, end); - return this.bytes.subarray(begin, end); - }, - - skip: function ChunkedStream_skip(n) { - if (!n) { - n = 1; - } - this.pos += n; - }, - - reset: function ChunkedStream_reset() { - this.pos = this.start; - }, - - moveStart: function ChunkedStream_moveStart() { - this.start = this.pos; - }, - - makeSubStream: function ChunkedStream_makeSubStream(start, length, dict) { - this.ensureRange(start, start + length); - - function ChunkedStreamSubstream() {} - ChunkedStreamSubstream.prototype = Object.create(this); - ChunkedStreamSubstream.prototype.getMissingChunks = function() { - var chunkSize = this.chunkSize; - var beginChunk = Math.floor(this.start / chunkSize); - var endChunk = Math.floor((this.end - 1) / chunkSize) + 1; - var missingChunks = []; - for (var chunk = beginChunk; chunk < endChunk; ++chunk) { - if (!this.loadedChunks[chunk]) { - missingChunks.push(chunk); - } - } - return missingChunks; - }; - var subStream = new ChunkedStreamSubstream(); - subStream.pos = subStream.start = start; - subStream.end = start + length || this.end; - subStream.dict = dict; - return subStream; - }, - - isStream: true - }; - - return ChunkedStream; -})(); - -var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { - - function ChunkedStreamManager(length, chunkSize, url, args) { - this.stream = new ChunkedStream(length, chunkSize, this); - this.length = length; - this.chunkSize = chunkSize; - this.url = url; - this.disableAutoFetch = args.disableAutoFetch; - var msgHandler = this.msgHandler = args.msgHandler; - - if (args.chunkedViewerLoading) { - msgHandler.on('OnDataRange', this.onReceiveData.bind(this)); - msgHandler.on('OnDataProgress', this.onProgress.bind(this)); - this.sendRequest = function ChunkedStreamManager_sendRequest(begin, end) { - msgHandler.send('RequestDataRange', { begin: begin, end: end }); - }; - } else { - - var getXhr = function getXhr() { -//#if B2G -// return new XMLHttpRequest({ mozSystem: true }); -//#else - return new XMLHttpRequest(); -//#endif - }; - this.networkManager = new NetworkManager(this.url, { - getXhr: getXhr, - httpHeaders: args.httpHeaders, - withCredentials: args.withCredentials - }); - this.sendRequest = function ChunkedStreamManager_sendRequest(begin, end) { - this.networkManager.requestRange(begin, end, { - onDone: this.onReceiveData.bind(this), - onProgress: this.onProgress.bind(this) - }); - }; - } - - this.currRequestId = 0; - - this.chunksNeededByRequest = {}; - this.requestsByChunk = {}; - this.callbacksByRequest = {}; - this.progressiveDataLength = 0; - - this._loadedStreamCapability = createPromiseCapability(); - - if (args.initialData) { - this.onReceiveData({chunk: args.initialData}); - } - } - - ChunkedStreamManager.prototype = { - onLoadedStream: function ChunkedStreamManager_getLoadedStream() { - return this._loadedStreamCapability.promise; - }, - - // Get all the chunks that are not yet loaded and groups them into - // contiguous ranges to load in as few requests as possible - requestAllChunks: function ChunkedStreamManager_requestAllChunks() { - var missingChunks = this.stream.getMissingChunks(); - this.requestChunks(missingChunks); - return this._loadedStreamCapability.promise; - }, - - requestChunks: function ChunkedStreamManager_requestChunks(chunks, - callback) { - var requestId = this.currRequestId++; - - var chunksNeeded; - var i, ii; - this.chunksNeededByRequest[requestId] = chunksNeeded = {}; - for (i = 0, ii = chunks.length; i < ii; i++) { - if (!this.stream.hasChunk(chunks[i])) { - chunksNeeded[chunks[i]] = true; - } - } - - if (isEmptyObj(chunksNeeded)) { - if (callback) { - callback(); - } - return; - } - - this.callbacksByRequest[requestId] = callback; - - var chunksToRequest = []; - for (var chunk in chunksNeeded) { - chunk = chunk | 0; - if (!(chunk in this.requestsByChunk)) { - this.requestsByChunk[chunk] = []; - chunksToRequest.push(chunk); - } - this.requestsByChunk[chunk].push(requestId); - } - - if (!chunksToRequest.length) { - return; - } - - var groupedChunksToRequest = this.groupChunks(chunksToRequest); - - for (i = 0; i < groupedChunksToRequest.length; ++i) { - var groupedChunk = groupedChunksToRequest[i]; - var begin = groupedChunk.beginChunk * this.chunkSize; - var end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length); - this.sendRequest(begin, end); - } - }, - - getStream: function ChunkedStreamManager_getStream() { - return this.stream; - }, - - // Loads any chunks in the requested range that are not yet loaded - requestRange: function ChunkedStreamManager_requestRange( - begin, end, callback) { - - end = Math.min(end, this.length); - - var beginChunk = this.getBeginChunk(begin); - var endChunk = this.getEndChunk(end); - - var chunks = []; - for (var chunk = beginChunk; chunk < endChunk; ++chunk) { - chunks.push(chunk); - } - - this.requestChunks(chunks, callback); - }, - - requestRanges: function ChunkedStreamManager_requestRanges(ranges, - callback) { - ranges = ranges || []; - var chunksToRequest = []; - - for (var i = 0; i < ranges.length; i++) { - var beginChunk = this.getBeginChunk(ranges[i].begin); - var endChunk = this.getEndChunk(ranges[i].end); - for (var chunk = beginChunk; chunk < endChunk; ++chunk) { - if (chunksToRequest.indexOf(chunk) < 0) { - chunksToRequest.push(chunk); - } - } - } - - chunksToRequest.sort(function(a, b) { return a - b; }); - this.requestChunks(chunksToRequest, callback); - }, - - // Groups a sorted array of chunks into as few continguous larger - // chunks as possible - groupChunks: function ChunkedStreamManager_groupChunks(chunks) { - var groupedChunks = []; - var beginChunk = -1; - var prevChunk = -1; - for (var i = 0; i < chunks.length; ++i) { - var chunk = chunks[i]; - - if (beginChunk < 0) { - beginChunk = chunk; - } - - if (prevChunk >= 0 && prevChunk + 1 !== chunk) { - groupedChunks.push({ beginChunk: beginChunk, - endChunk: prevChunk + 1 }); - beginChunk = chunk; - } - if (i + 1 === chunks.length) { - groupedChunks.push({ beginChunk: beginChunk, - endChunk: chunk + 1 }); - } - - prevChunk = chunk; - } - return groupedChunks; - }, - - onProgress: function ChunkedStreamManager_onProgress(args) { - var bytesLoaded = (this.stream.numChunksLoaded * this.chunkSize + - args.loaded); - this.msgHandler.send('DocProgress', { - loaded: bytesLoaded, - total: this.length - }); - }, - - onReceiveData: function ChunkedStreamManager_onReceiveData(args) { - var chunk = args.chunk; - var isProgressive = args.begin === undefined; - var begin = isProgressive ? this.progressiveDataLength : args.begin; - var end = begin + chunk.byteLength; - - var beginChunk = Math.floor(begin / this.chunkSize); - var endChunk = end < this.length ? Math.floor(end / this.chunkSize) : - Math.ceil(end / this.chunkSize); - - if (isProgressive) { - this.stream.onReceiveProgressiveData(chunk); - this.progressiveDataLength = end; - } else { - this.stream.onReceiveData(begin, chunk); - } - - if (this.stream.allChunksLoaded()) { - this._loadedStreamCapability.resolve(this.stream); - } - - var loadedRequests = []; - var i, requestId; - for (chunk = beginChunk; chunk < endChunk; ++chunk) { - // The server might return more chunks than requested - var requestIds = this.requestsByChunk[chunk] || []; - delete this.requestsByChunk[chunk]; - - for (i = 0; i < requestIds.length; ++i) { - requestId = requestIds[i]; - var chunksNeeded = this.chunksNeededByRequest[requestId]; - if (chunk in chunksNeeded) { - delete chunksNeeded[chunk]; - } - - if (!isEmptyObj(chunksNeeded)) { - continue; - } - - loadedRequests.push(requestId); - } - } - - // If there are no pending requests, automatically fetch the next - // unfetched chunk of the PDF - if (!this.disableAutoFetch && isEmptyObj(this.requestsByChunk)) { - var nextEmptyChunk; - if (this.stream.numChunksLoaded === 1) { - // This is a special optimization so that after fetching the first - // chunk, rather than fetching the second chunk, we fetch the last - // chunk. - var lastChunk = this.stream.numChunks - 1; - if (!this.stream.hasChunk(lastChunk)) { - nextEmptyChunk = lastChunk; - } - } else { - nextEmptyChunk = this.stream.nextEmptyChunk(endChunk); - } - if (isInt(nextEmptyChunk)) { - this.requestChunks([nextEmptyChunk]); - } - } - - for (i = 0; i < loadedRequests.length; ++i) { - requestId = loadedRequests[i]; - var callback = this.callbacksByRequest[requestId]; - delete this.callbacksByRequest[requestId]; - if (callback) { - callback(); - } - } - - this.msgHandler.send('DocProgress', { - loaded: this.stream.numChunksLoaded * this.chunkSize, - total: this.length - }); - }, - - onError: function ChunkedStreamManager_onError(err) { - this._loadedStreamCapability.reject(err); - }, - - getBeginChunk: function ChunkedStreamManager_getBeginChunk(begin) { - var chunk = Math.floor(begin / this.chunkSize); - return chunk; - }, - - getEndChunk: function ChunkedStreamManager_getEndChunk(end) { - if (end % this.chunkSize === 0) { - return end / this.chunkSize; - } - - // 0 -> 0 - // 1 -> 1 - // 99 -> 1 - // 100 -> 1 - // 101 -> 2 - var chunk = Math.floor((end - 1) / this.chunkSize) + 1; - return chunk; - } - }; - - return ChunkedStreamManager; -})(); - - -// The maximum number of bytes fetched per range request -var RANGE_CHUNK_SIZE = 65536; - -// TODO(mack): Make use of PDFJS.Util.inherit() when it becomes available -var BasePdfManager = (function BasePdfManagerClosure() { - function BasePdfManager() { - throw new Error('Cannot initialize BaseManagerManager'); - } - - BasePdfManager.prototype = { - onLoadedStream: function BasePdfManager_onLoadedStream() { - throw new NotImplementedException(); - }, - - ensureDoc: function BasePdfManager_ensureDoc(prop, args) { - return this.ensure(this.pdfDocument, prop, args); - }, - - ensureXRef: function BasePdfManager_ensureXRef(prop, args) { - return this.ensure(this.pdfDocument.xref, prop, args); - }, - - ensureCatalog: function BasePdfManager_ensureCatalog(prop, args) { - return this.ensure(this.pdfDocument.catalog, prop, args); - }, - - getPage: function BasePdfManager_pagePage(pageIndex) { - return this.pdfDocument.getPage(pageIndex); - }, - - cleanup: function BasePdfManager_cleanup() { - return this.pdfDocument.cleanup(); - }, - - ensure: function BasePdfManager_ensure(obj, prop, args) { - return new NotImplementedException(); - }, - - requestRange: function BasePdfManager_ensure(begin, end) { - return new NotImplementedException(); - }, - - requestLoadedStream: function BasePdfManager_requestLoadedStream() { - return new NotImplementedException(); - }, - - sendProgressiveData: function BasePdfManager_sendProgressiveData(chunk) { - return new NotImplementedException(); - }, - - updatePassword: function BasePdfManager_updatePassword(password) { - this.pdfDocument.xref.password = this.password = password; - if (this._passwordChangedCapability) { - this._passwordChangedCapability.resolve(); - } - }, - - passwordChanged: function BasePdfManager_passwordChanged() { - this._passwordChangedCapability = createPromiseCapability(); - return this._passwordChangedCapability.promise; - }, - - terminate: function BasePdfManager_terminate() { - return new NotImplementedException(); - } - }; - - return BasePdfManager; -})(); - -var LocalPdfManager = (function LocalPdfManagerClosure() { - function LocalPdfManager(data, password) { - var stream = new Stream(data); - this.pdfDocument = new PDFDocument(this, stream, password); - this._loadedStreamCapability = createPromiseCapability(); - this._loadedStreamCapability.resolve(stream); - } - - LocalPdfManager.prototype = Object.create(BasePdfManager.prototype); - LocalPdfManager.prototype.constructor = LocalPdfManager; - - LocalPdfManager.prototype.ensure = - function LocalPdfManager_ensure(obj, prop, args) { - return new Promise(function (resolve, reject) { - try { - var value = obj[prop]; - var result; - if (typeof value === 'function') { - result = value.apply(obj, args); - } else { - result = value; - } - resolve(result); - } catch (e) { - reject(e); - } - }); - }; - - LocalPdfManager.prototype.requestRange = - function LocalPdfManager_requestRange(begin, end) { - return Promise.resolve(); - }; - - LocalPdfManager.prototype.requestLoadedStream = - function LocalPdfManager_requestLoadedStream() { - }; - - LocalPdfManager.prototype.onLoadedStream = - function LocalPdfManager_getLoadedStream() { - return this._loadedStreamCapability.promise; - }; - - LocalPdfManager.prototype.terminate = - function LocalPdfManager_terminate() { - return; - }; - - return LocalPdfManager; -})(); - -var NetworkPdfManager = (function NetworkPdfManagerClosure() { - function NetworkPdfManager(args, msgHandler) { - - this.msgHandler = msgHandler; - - var params = { - msgHandler: msgHandler, - httpHeaders: args.httpHeaders, - withCredentials: args.withCredentials, - chunkedViewerLoading: args.chunkedViewerLoading, - disableAutoFetch: args.disableAutoFetch, - initialData: args.initialData - }; - this.streamManager = new ChunkedStreamManager(args.length, RANGE_CHUNK_SIZE, - args.url, params); - - this.pdfDocument = new PDFDocument(this, this.streamManager.getStream(), - args.password); - } - - NetworkPdfManager.prototype = Object.create(BasePdfManager.prototype); - NetworkPdfManager.prototype.constructor = NetworkPdfManager; - - NetworkPdfManager.prototype.ensure = - function NetworkPdfManager_ensure(obj, prop, args) { - var pdfManager = this; - - return new Promise(function (resolve, reject) { - function ensureHelper() { - try { - var result; - var value = obj[prop]; - if (typeof value === 'function') { - result = value.apply(obj, args); - } else { - result = value; - } - resolve(result); - } catch(e) { - if (!(e instanceof MissingDataException)) { - reject(e); - return; - } - pdfManager.streamManager.requestRange(e.begin, e.end, ensureHelper); - } - } - - ensureHelper(); - }); - }; - - NetworkPdfManager.prototype.requestRange = - function NetworkPdfManager_requestRange(begin, end) { - return new Promise(function (resolve) { - this.streamManager.requestRange(begin, end, function() { - resolve(); - }); - }.bind(this)); - }; - - NetworkPdfManager.prototype.requestLoadedStream = - function NetworkPdfManager_requestLoadedStream() { - this.streamManager.requestAllChunks(); - }; - - NetworkPdfManager.prototype.sendProgressiveData = - function NetworkPdfManager_sendProgressiveData(chunk) { - this.streamManager.onReceiveData({ chunk: chunk }); - }; - - NetworkPdfManager.prototype.onLoadedStream = - function NetworkPdfManager_getLoadedStream() { - return this.streamManager.onLoadedStream(); - }; - - NetworkPdfManager.prototype.terminate = - function NetworkPdfManager_terminate() { - this.streamManager.networkManager.abortAllRequests(); - }; - - return NetworkPdfManager; -})(); - - -var Page = (function PageClosure() { - - var LETTER_SIZE_MEDIABOX = [0, 0, 612, 792]; - - function Page(pdfManager, xref, pageIndex, pageDict, ref, fontCache) { - this.pdfManager = pdfManager; - this.pageIndex = pageIndex; - this.pageDict = pageDict; - this.xref = xref; - this.ref = ref; - this.fontCache = fontCache; - this.idCounters = { - obj: 0 - }; - this.resourcesPromise = null; - } - - Page.prototype = { - getPageProp: function Page_getPageProp(key) { - return this.pageDict.get(key); - }, - - getInheritedPageProp: function Page_inheritPageProp(key) { - var dict = this.pageDict; - var value = dict.get(key); - while (value === undefined) { - dict = dict.get('Parent'); - if (!dict) { - break; - } - value = dict.get(key); - } - return value; - }, - - get content() { - return this.getPageProp('Contents'); - }, - - get resources() { - var value = this.getInheritedPageProp('Resources'); - // For robustness: The spec states that a \Resources entry has to be - // present, but can be empty. Some document omit it still. In this case - // return an empty dictionary: - if (value === undefined) { - value = Dict.empty; - } - return shadow(this, 'resources', value); - }, - - get mediaBox() { - var obj = this.getInheritedPageProp('MediaBox'); - // Reset invalid media box to letter size. - if (!isArray(obj) || obj.length !== 4) { - obj = LETTER_SIZE_MEDIABOX; - } - return shadow(this, 'mediaBox', obj); - }, - - get view() { - var mediaBox = this.mediaBox; - var cropBox = this.getInheritedPageProp('CropBox'); - if (!isArray(cropBox) || cropBox.length !== 4) { - return shadow(this, 'view', mediaBox); - } - - // From the spec, 6th ed., p.963: - // "The crop, bleed, trim, and art boxes should not ordinarily - // extend beyond the boundaries of the media box. If they do, they are - // effectively reduced to their intersection with the media box." - cropBox = Util.intersect(cropBox, mediaBox); - if (!cropBox) { - return shadow(this, 'view', mediaBox); - } - return shadow(this, 'view', cropBox); - }, - - get annotationRefs() { - return shadow(this, 'annotationRefs', - this.getInheritedPageProp('Annots')); - }, - - get rotate() { - var rotate = this.getInheritedPageProp('Rotate') || 0; - // Normalize rotation so it's a multiple of 90 and between 0 and 270 - if (rotate % 90 !== 0) { - rotate = 0; - } else if (rotate >= 360) { - rotate = rotate % 360; - } else if (rotate < 0) { - // The spec doesn't cover negatives, assume its counterclockwise - // rotation. The following is the other implementation of modulo. - rotate = ((rotate % 360) + 360) % 360; - } - return shadow(this, 'rotate', rotate); - }, - - getContentStream: function Page_getContentStream() { - var content = this.content; - var stream; - if (isArray(content)) { - // fetching items - var xref = this.xref; - var i, n = content.length; - var streams = []; - for (i = 0; i < n; ++i) { - streams.push(xref.fetchIfRef(content[i])); - } - stream = new StreamsSequenceStream(streams); - } else if (isStream(content)) { - stream = content; - } else { - // replacing non-existent page content with empty one - stream = new NullStream(); - } - return stream; - }, - - loadResources: function Page_loadResources(keys) { - if (!this.resourcesPromise) { - // TODO: add async getInheritedPageProp and remove this. - this.resourcesPromise = this.pdfManager.ensure(this, 'resources'); - } - return this.resourcesPromise.then(function resourceSuccess() { - var objectLoader = new ObjectLoader(this.resources.map, - keys, - this.xref); - return objectLoader.load(); - }.bind(this)); - }, - - getOperatorList: function Page_getOperatorList(handler, intent) { - var self = this; - - var pdfManager = this.pdfManager; - var contentStreamPromise = pdfManager.ensure(this, 'getContentStream', - []); - var resourcesPromise = this.loadResources([ - 'ExtGState', - 'ColorSpace', - 'Pattern', - 'Shading', - 'XObject', - 'Font' - // ProcSet - // Properties - ]); - - var partialEvaluator = new PartialEvaluator(pdfManager, this.xref, - handler, this.pageIndex, - 'p' + this.pageIndex + '_', - this.idCounters, - this.fontCache); - - var dataPromises = Promise.all([contentStreamPromise, resourcesPromise]); - var pageListPromise = dataPromises.then(function(data) { - var contentStream = data[0]; - var opList = new OperatorList(intent, handler, self.pageIndex); - - handler.send('StartRenderPage', { - transparency: partialEvaluator.hasBlendModes(self.resources), - pageIndex: self.pageIndex, - intent: intent - }); - return partialEvaluator.getOperatorList(contentStream, self.resources, - opList).then(function () { - return opList; - }); - }); - - var annotationsPromise = pdfManager.ensure(this, 'annotations'); - return Promise.all([pageListPromise, annotationsPromise]).then( - function(datas) { - var pageOpList = datas[0]; - var annotations = datas[1]; - - if (annotations.length === 0) { - pageOpList.flush(true); - return pageOpList; - } - - var annotationsReadyPromise = Annotation.appendToOperatorList( - annotations, pageOpList, pdfManager, partialEvaluator, intent); - return annotationsReadyPromise.then(function () { - pageOpList.flush(true); - return pageOpList; - }); - }); - }, - - extractTextContent: function Page_extractTextContent() { - var handler = { - on: function nullHandlerOn() {}, - send: function nullHandlerSend() {} - }; - - var self = this; - - var pdfManager = this.pdfManager; - var contentStreamPromise = pdfManager.ensure(this, 'getContentStream', - []); - - var resourcesPromise = this.loadResources([ - 'ExtGState', - 'XObject', - 'Font' - ]); - - var dataPromises = Promise.all([contentStreamPromise, - resourcesPromise]); - return dataPromises.then(function(data) { - var contentStream = data[0]; - var partialEvaluator = new PartialEvaluator(pdfManager, self.xref, - handler, self.pageIndex, - 'p' + self.pageIndex + '_', - self.idCounters, - self.fontCache); - - return partialEvaluator.getTextContent(contentStream, - self.resources); - }); - }, - - getAnnotationsData: function Page_getAnnotationsData() { - var annotations = this.annotations; - var annotationsData = []; - for (var i = 0, n = annotations.length; i < n; ++i) { - annotationsData.push(annotations[i].getData()); - } - return annotationsData; - }, - - get annotations() { - var annotations = []; - var annotationRefs = (this.annotationRefs || []); - for (var i = 0, n = annotationRefs.length; i < n; ++i) { - var annotationRef = annotationRefs[i]; - var annotation = Annotation.fromRef(this.xref, annotationRef); - if (annotation) { - annotations.push(annotation); - } - } - return shadow(this, 'annotations', annotations); - } - }; - - return Page; -})(); - -/** - * The `PDFDocument` holds all the data of the PDF file. Compared to the - * `PDFDoc`, this one doesn't have any job management code. - * Right now there exists one PDFDocument on the main thread + one object - * for each worker. If there is no worker support enabled, there are two - * `PDFDocument` objects on the main thread created. - */ -var PDFDocument = (function PDFDocumentClosure() { - var FINGERPRINT_FIRST_BYTES = 1024; - var EMPTY_FINGERPRINT = '\x00\x00\x00\x00\x00\x00\x00' + - '\x00\x00\x00\x00\x00\x00\x00\x00\x00'; - - function PDFDocument(pdfManager, arg, password) { - if (isStream(arg)) { - init.call(this, pdfManager, arg, password); - } else if (isArrayBuffer(arg)) { - init.call(this, pdfManager, new Stream(arg), password); - } else { - error('PDFDocument: Unknown argument type'); - } - } - - function init(pdfManager, stream, password) { - assert(stream.length > 0, 'stream must have data'); - this.pdfManager = pdfManager; - this.stream = stream; - var xref = new XRef(this.stream, password, pdfManager); - this.xref = xref; - } - - function find(stream, needle, limit, backwards) { - var pos = stream.pos; - var end = stream.end; - var strBuf = []; - if (pos + limit > end) { - limit = end - pos; - } - for (var n = 0; n < limit; ++n) { - strBuf.push(String.fromCharCode(stream.getByte())); - } - var str = strBuf.join(''); - stream.pos = pos; - var index = backwards ? str.lastIndexOf(needle) : str.indexOf(needle); - if (index === -1) { - return false; /* not found */ - } - stream.pos += index; - return true; /* found */ - } - - var DocumentInfoValidators = { - get entries() { - // Lazily build this since all the validation functions below are not - // defined until after this file loads. - return shadow(this, 'entries', { - Title: isString, - Author: isString, - Subject: isString, - Keywords: isString, - Creator: isString, - Producer: isString, - CreationDate: isString, - ModDate: isString, - Trapped: isName - }); - } - }; - - PDFDocument.prototype = { - parse: function PDFDocument_parse(recoveryMode) { - this.setup(recoveryMode); - try { - // checking if AcroForm is present - this.acroForm = this.catalog.catDict.get('AcroForm'); - if (this.acroForm) { - this.xfa = this.acroForm.get('XFA'); - var fields = this.acroForm.get('Fields'); - if ((!fields || !isArray(fields) || fields.length === 0) && - !this.xfa) { - // no fields and no XFA -- not a form (?) - this.acroForm = null; - } - } - } catch (ex) { - info('Something wrong with AcroForm entry'); - this.acroForm = null; - } - }, - - get linearization() { - var linearization = null; - if (this.stream.length) { - try { - linearization = Linearization.create(this.stream); - } catch (err) { - if (err instanceof MissingDataException) { - throw err; - } - info(err); - } - } - // shadow the prototype getter with a data property - return shadow(this, 'linearization', linearization); - }, - get startXRef() { - var stream = this.stream; - var startXRef = 0; - var linearization = this.linearization; - if (linearization) { - // Find end of first obj. - stream.reset(); - if (find(stream, 'endobj', 1024)) { - startXRef = stream.pos + 6; - } - } else { - // Find startxref by jumping backward from the end of the file. - var step = 1024; - var found = false, pos = stream.end; - while (!found && pos > 0) { - pos -= step - 'startxref'.length; - if (pos < 0) { - pos = 0; - } - stream.pos = pos; - found = find(stream, 'startxref', step, true); - } - if (found) { - stream.skip(9); - var ch; - do { - ch = stream.getByte(); - } while (Lexer.isSpace(ch)); - var str = ''; - while (ch >= 0x20 && ch <= 0x39) { // < '9' - str += String.fromCharCode(ch); - ch = stream.getByte(); - } - startXRef = parseInt(str, 10); - if (isNaN(startXRef)) { - startXRef = 0; - } - } - } - // shadow the prototype getter with a data property - return shadow(this, 'startXRef', startXRef); - }, - get mainXRefEntriesOffset() { - var mainXRefEntriesOffset = 0; - var linearization = this.linearization; - if (linearization) { - mainXRefEntriesOffset = linearization.mainXRefEntriesOffset; - } - // shadow the prototype getter with a data property - return shadow(this, 'mainXRefEntriesOffset', mainXRefEntriesOffset); - }, - // Find the header, remove leading garbage and setup the stream - // starting from the header. - checkHeader: function PDFDocument_checkHeader() { - var stream = this.stream; - stream.reset(); - if (find(stream, '%PDF-', 1024)) { - // Found the header, trim off any garbage before it. - stream.moveStart(); - // Reading file format version - var MAX_VERSION_LENGTH = 12; - var version = '', ch; - while ((ch = stream.getByte()) > 0x20) { // SPACE - if (version.length >= MAX_VERSION_LENGTH) { - break; - } - version += String.fromCharCode(ch); - } - // removing "%PDF-"-prefix - this.pdfFormatVersion = version.substring(5); - return; - } - // May not be a PDF file, continue anyway. - }, - parseStartXRef: function PDFDocument_parseStartXRef() { - var startXRef = this.startXRef; - this.xref.setStartXRef(startXRef); - }, - setup: function PDFDocument_setup(recoveryMode) { - this.xref.parse(recoveryMode); - this.catalog = new Catalog(this.pdfManager, this.xref); - }, - get numPages() { - var linearization = this.linearization; - var num = linearization ? linearization.numPages : this.catalog.numPages; - // shadow the prototype getter - return shadow(this, 'numPages', num); - }, - get documentInfo() { - var docInfo = { - PDFFormatVersion: this.pdfFormatVersion, - IsAcroFormPresent: !!this.acroForm, - IsXFAPresent: !!this.xfa - }; - var infoDict; - try { - infoDict = this.xref.trailer.get('Info'); - } catch (err) { - info('The document information dictionary is invalid.'); - } - if (infoDict) { - var validEntries = DocumentInfoValidators.entries; - // Only fill the document info with valid entries from the spec. - for (var key in validEntries) { - if (infoDict.has(key)) { - var value = infoDict.get(key); - // Make sure the value conforms to the spec. - if (validEntries[key](value)) { - docInfo[key] = (typeof value !== 'string' ? - value : stringToPDFString(value)); - } else { - info('Bad value in document info for "' + key + '"'); - } - } - } - } - return shadow(this, 'documentInfo', docInfo); - }, - get fingerprint() { - var xref = this.xref, idArray, hash, fileID = ''; - - if (xref.trailer.has('ID')) { - idArray = xref.trailer.get('ID'); - } - if (idArray && isArray(idArray) && idArray[0] !== EMPTY_FINGERPRINT) { - hash = stringToBytes(idArray[0]); - } else { - if (this.stream.ensureRange) { - this.stream.ensureRange(0, - Math.min(FINGERPRINT_FIRST_BYTES, this.stream.end)); - } - hash = calculateMD5(this.stream.bytes.subarray(0, - FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES); - } - - for (var i = 0, n = hash.length; i < n; i++) { - var hex = hash[i].toString(16); - fileID += hex.length === 1 ? '0' + hex : hex; - } - - return shadow(this, 'fingerprint', fileID); - }, - - getPage: function PDFDocument_getPage(pageIndex) { - return this.catalog.getPage(pageIndex); - }, - - cleanup: function PDFDocument_cleanup() { - return this.catalog.cleanup(); - } - }; - - return PDFDocument; -})(); - - -var Name = (function NameClosure() { - function Name(name) { - this.name = name; - } - - Name.prototype = {}; - - var nameCache = {}; - - Name.get = function Name_get(name) { - var nameValue = nameCache[name]; - return (nameValue ? nameValue : (nameCache[name] = new Name(name))); - }; - - return Name; -})(); - -var Cmd = (function CmdClosure() { - function Cmd(cmd) { - this.cmd = cmd; - } - - Cmd.prototype = {}; - - var cmdCache = {}; - - Cmd.get = function Cmd_get(cmd) { - var cmdValue = cmdCache[cmd]; - return (cmdValue ? cmdValue : (cmdCache[cmd] = new Cmd(cmd))); - }; - - return Cmd; -})(); - -var Dict = (function DictClosure() { - var nonSerializable = function nonSerializableClosure() { - return nonSerializable; // creating closure on some variable - }; - - var GETALL_DICTIONARY_TYPES_WHITELIST = { - 'Background': true, - 'ExtGState': true, - 'Halftone': true, - 'Layout': true, - 'Mask': true, - 'Pagination': true, - 'Printing': true - }; - - function isRecursionAllowedFor(dict) { - if (!isName(dict.Type)) { - return true; - } - var dictType = dict.Type.name; - return GETALL_DICTIONARY_TYPES_WHITELIST[dictType] === true; - } - - // xref is optional - function Dict(xref) { - // Map should only be used internally, use functions below to access. - this.map = Object.create(null); - this.xref = xref; - this.objId = null; - this.__nonSerializable__ = nonSerializable; // disable cloning of the Dict - } - - Dict.prototype = { - assignXref: function Dict_assignXref(newXref) { - this.xref = newXref; - }, - - // automatically dereferences Ref objects - get: function Dict_get(key1, key2, key3) { - var value; - var xref = this.xref; - if (typeof (value = this.map[key1]) !== 'undefined' || key1 in this.map || - typeof key2 === 'undefined') { - return xref ? xref.fetchIfRef(value) : value; - } - if (typeof (value = this.map[key2]) !== 'undefined' || key2 in this.map || - typeof key3 === 'undefined') { - return xref ? xref.fetchIfRef(value) : value; - } - value = this.map[key3] || null; - return xref ? xref.fetchIfRef(value) : value; - }, - - // Same as get(), but returns a promise and uses fetchIfRefAsync(). - getAsync: function Dict_getAsync(key1, key2, key3) { - var value; - var xref = this.xref; - if (typeof (value = this.map[key1]) !== 'undefined' || key1 in this.map || - typeof key2 === 'undefined') { - if (xref) { - return xref.fetchIfRefAsync(value); - } - return Promise.resolve(value); - } - if (typeof (value = this.map[key2]) !== 'undefined' || key2 in this.map || - typeof key3 === 'undefined') { - if (xref) { - return xref.fetchIfRefAsync(value); - } - return Promise.resolve(value); - } - value = this.map[key3] || null; - if (xref) { - return xref.fetchIfRefAsync(value); - } - return Promise.resolve(value); - }, - - // no dereferencing - getRaw: function Dict_getRaw(key) { - return this.map[key]; - }, - - // creates new map and dereferences all Refs - getAll: function Dict_getAll() { - var all = Object.create(null); - var queue = null; - var key, obj; - for (key in this.map) { - obj = this.get(key); - if (obj instanceof Dict) { - if (isRecursionAllowedFor(obj)) { - (queue || (queue = [])).push({target: all, key: key, obj: obj}); - } else { - all[key] = this.getRaw(key); - } - } else { - all[key] = obj; - } - } - if (!queue) { - return all; - } - - // trying to take cyclic references into the account - var processed = Object.create(null); - while (queue.length > 0) { - var item = queue.shift(); - var itemObj = item.obj; - var objId = itemObj.objId; - if (objId && objId in processed) { - item.target[item.key] = processed[objId]; - continue; - } - var dereferenced = Object.create(null); - for (key in itemObj.map) { - obj = itemObj.get(key); - if (obj instanceof Dict) { - if (isRecursionAllowedFor(obj)) { - queue.push({target: dereferenced, key: key, obj: obj}); - } else { - dereferenced[key] = itemObj.getRaw(key); - } - } else { - dereferenced[key] = obj; - } - } - if (objId) { - processed[objId] = dereferenced; - } - item.target[item.key] = dereferenced; - } - return all; - }, - - getKeys: function Dict_getKeys() { - return Object.keys(this.map); - }, - - set: function Dict_set(key, value) { - this.map[key] = value; - }, - - has: function Dict_has(key) { - return key in this.map; - }, - - forEach: function Dict_forEach(callback) { - for (var key in this.map) { - callback(key, this.get(key)); - } - } - }; - - Dict.empty = new Dict(null); - - return Dict; -})(); - -var Ref = (function RefClosure() { - function Ref(num, gen) { - this.num = num; - this.gen = gen; - } - - Ref.prototype = { - toString: function Ref_toString() { - // This function is hot, so we make the string as compact as possible. - // |this.gen| is almost always zero, so we treat that case specially. - var str = this.num + 'R'; - if (this.gen !== 0) { - str += this.gen; - } - return str; - } - }; - - return Ref; -})(); - -// The reference is identified by number and generation. -// This structure stores only one instance of the reference. -var RefSet = (function RefSetClosure() { - function RefSet() { - this.dict = {}; - } - - RefSet.prototype = { - has: function RefSet_has(ref) { - return ref.toString() in this.dict; - }, - - put: function RefSet_put(ref) { - this.dict[ref.toString()] = true; - }, - - remove: function RefSet_remove(ref) { - delete this.dict[ref.toString()]; - } - }; - - return RefSet; -})(); - -var RefSetCache = (function RefSetCacheClosure() { - function RefSetCache() { - this.dict = Object.create(null); - } - - RefSetCache.prototype = { - get: function RefSetCache_get(ref) { - return this.dict[ref.toString()]; - }, - - has: function RefSetCache_has(ref) { - return ref.toString() in this.dict; - }, - - put: function RefSetCache_put(ref, obj) { - this.dict[ref.toString()] = obj; - }, - - putAlias: function RefSetCache_putAlias(ref, aliasRef) { - this.dict[ref.toString()] = this.get(aliasRef); - }, - - forEach: function RefSetCache_forEach(fn, thisArg) { - for (var i in this.dict) { - fn.call(thisArg, this.dict[i]); - } - }, - - clear: function RefSetCache_clear() { - this.dict = Object.create(null); - } - }; - - return RefSetCache; -})(); - -var Catalog = (function CatalogClosure() { - function Catalog(pdfManager, xref) { - this.pdfManager = pdfManager; - this.xref = xref; - this.catDict = xref.getCatalogObj(); - this.fontCache = new RefSetCache(); - assert(isDict(this.catDict), - 'catalog object is not a dictionary'); - - this.pagePromises = []; - } - - Catalog.prototype = { - get metadata() { - var streamRef = this.catDict.getRaw('Metadata'); - if (!isRef(streamRef)) { - return shadow(this, 'metadata', null); - } - - var encryptMetadata = (!this.xref.encrypt ? false : - this.xref.encrypt.encryptMetadata); - - var stream = this.xref.fetch(streamRef, !encryptMetadata); - var metadata; - if (stream && isDict(stream.dict)) { - var type = stream.dict.get('Type'); - var subtype = stream.dict.get('Subtype'); - - if (isName(type) && isName(subtype) && - type.name === 'Metadata' && subtype.name === 'XML') { - // XXX: This should examine the charset the XML document defines, - // however since there are currently no real means to decode - // arbitrary charsets, let's just hope that the author of the PDF - // was reasonable enough to stick with the XML default charset, - // which is UTF-8. - try { - metadata = stringToUTF8String(bytesToString(stream.getBytes())); - } catch (e) { - info('Skipping invalid metadata.'); - } - } - } - - return shadow(this, 'metadata', metadata); - }, - get toplevelPagesDict() { - var pagesObj = this.catDict.get('Pages'); - assert(isDict(pagesObj), 'invalid top-level pages dictionary'); - // shadow the prototype getter - return shadow(this, 'toplevelPagesDict', pagesObj); - }, - get documentOutline() { - var obj = null; - try { - obj = this.readDocumentOutline(); - } catch (ex) { - if (ex instanceof MissingDataException) { - throw ex; - } - warn('Unable to read document outline'); - } - return shadow(this, 'documentOutline', obj); - }, - readDocumentOutline: function Catalog_readDocumentOutline() { - var xref = this.xref; - var obj = this.catDict.get('Outlines'); - var root = { items: [] }; - if (isDict(obj)) { - obj = obj.getRaw('First'); - var processed = new RefSet(); - if (isRef(obj)) { - var queue = [{obj: obj, parent: root}]; - // to avoid recursion keeping track of the items - // in the processed dictionary - processed.put(obj); - while (queue.length > 0) { - var i = queue.shift(); - var outlineDict = xref.fetchIfRef(i.obj); - if (outlineDict === null) { - continue; - } - if (!outlineDict.has('Title')) { - error('Invalid outline item'); - } - var dest = outlineDict.get('A'); - if (dest) { - dest = dest.get('D'); - } else if (outlineDict.has('Dest')) { - dest = outlineDict.getRaw('Dest'); - if (isName(dest)) { - dest = dest.name; - } - } - var title = outlineDict.get('Title'); - var outlineItem = { - dest: dest, - title: stringToPDFString(title), - color: outlineDict.get('C') || [0, 0, 0], - count: outlineDict.get('Count'), - bold: !!(outlineDict.get('F') & 2), - italic: !!(outlineDict.get('F') & 1), - items: [] - }; - i.parent.items.push(outlineItem); - obj = outlineDict.getRaw('First'); - if (isRef(obj) && !processed.has(obj)) { - queue.push({obj: obj, parent: outlineItem}); - processed.put(obj); - } - obj = outlineDict.getRaw('Next'); - if (isRef(obj) && !processed.has(obj)) { - queue.push({obj: obj, parent: i.parent}); - processed.put(obj); - } - } - } - } - return (root.items.length > 0 ? root.items : null); - }, - get numPages() { - var obj = this.toplevelPagesDict.get('Count'); - assert( - isInt(obj), - 'page count in top level pages object is not an integer' - ); - // shadow the prototype getter - return shadow(this, 'num', obj); - }, - get destinations() { - function fetchDestination(dest) { - return isDict(dest) ? dest.get('D') : dest; - } - - var xref = this.xref; - var dests = {}, nameTreeRef, nameDictionaryRef; - var obj = this.catDict.get('Names'); - if (obj && obj.has('Dests')) { - nameTreeRef = obj.getRaw('Dests'); - } else if (this.catDict.has('Dests')) { - nameDictionaryRef = this.catDict.get('Dests'); - } - - if (nameDictionaryRef) { - // reading simple destination dictionary - obj = nameDictionaryRef; - obj.forEach(function catalogForEach(key, value) { - if (!value) { - return; - } - dests[key] = fetchDestination(value); - }); - } - if (nameTreeRef) { - var nameTree = new NameTree(nameTreeRef, xref); - var names = nameTree.getAll(); - for (var name in names) { - if (!names.hasOwnProperty(name)) { - continue; - } - dests[name] = fetchDestination(names[name]); - } - } - return shadow(this, 'destinations', dests); - }, - getDestination: function Catalog_getDestination(destinationId) { - function fetchDestination(dest) { - return isDict(dest) ? dest.get('D') : dest; - } - - var xref = this.xref; - var dest, nameTreeRef, nameDictionaryRef; - var obj = this.catDict.get('Names'); - if (obj && obj.has('Dests')) { - nameTreeRef = obj.getRaw('Dests'); - } else if (this.catDict.has('Dests')) { - nameDictionaryRef = this.catDict.get('Dests'); - } - - if (nameDictionaryRef) { - // reading simple destination dictionary - obj = nameDictionaryRef; - obj.forEach(function catalogForEach(key, value) { - if (!value) { - return; - } - if (key === destinationId) { - dest = fetchDestination(value); - } - }); - } - if (nameTreeRef) { - var nameTree = new NameTree(nameTreeRef, xref); - dest = fetchDestination(nameTree.get(destinationId)); - } - return dest; - }, - get attachments() { - var xref = this.xref; - var attachments = null, nameTreeRef; - var obj = this.catDict.get('Names'); - if (obj) { - nameTreeRef = obj.getRaw('EmbeddedFiles'); - } - - if (nameTreeRef) { - var nameTree = new NameTree(nameTreeRef, xref); - var names = nameTree.getAll(); - for (var name in names) { - if (!names.hasOwnProperty(name)) { - continue; - } - var fs = new FileSpec(names[name], xref); - if (!attachments) { - attachments = {}; - } - attachments[stringToPDFString(name)] = fs.serializable; - } - } - return shadow(this, 'attachments', attachments); - }, - get javaScript() { - var xref = this.xref; - var obj = this.catDict.get('Names'); - - var javaScript = []; - if (obj && obj.has('JavaScript')) { - var nameTree = new NameTree(obj.getRaw('JavaScript'), xref); - var names = nameTree.getAll(); - for (var name in names) { - if (!names.hasOwnProperty(name)) { - continue; - } - // We don't really use the JavaScript right now. This code is - // defensive so we don't cause errors on document load. - var jsDict = names[name]; - if (!isDict(jsDict)) { - continue; - } - var type = jsDict.get('S'); - if (!isName(type) || type.name !== 'JavaScript') { - continue; - } - var js = jsDict.get('JS'); - if (!isString(js) && !isStream(js)) { - continue; - } - if (isStream(js)) { - js = bytesToString(js.getBytes()); - } - javaScript.push(stringToPDFString(js)); - } - } - - // Append OpenAction actions to javaScript array - var openactionDict = this.catDict.get('OpenAction'); - if (isDict(openactionDict)) { - var objType = openactionDict.get('Type'); - var actionType = openactionDict.get('S'); - var action = openactionDict.get('N'); - var isPrintAction = (isName(objType) && objType.name === 'Action' && - isName(actionType) && actionType.name === 'Named' && - isName(action) && action.name === 'Print'); - - if (isPrintAction) { - javaScript.push('print(true);'); - } - } - - return shadow(this, 'javaScript', javaScript); - }, - - cleanup: function Catalog_cleanup() { - var promises = []; - this.fontCache.forEach(function (promise) { - promises.push(promise); - }); - return Promise.all(promises).then(function (translatedFonts) { - for (var i = 0, ii = translatedFonts.length; i < ii; i++) { - var font = translatedFonts[i].dict; - delete font.translated; - } - this.fontCache.clear(); - }.bind(this)); - }, - - getPage: function Catalog_getPage(pageIndex) { - if (!(pageIndex in this.pagePromises)) { - this.pagePromises[pageIndex] = this.getPageDict(pageIndex).then( - function (a) { - var dict = a[0]; - var ref = a[1]; - return new Page(this.pdfManager, this.xref, pageIndex, dict, ref, - this.fontCache); - }.bind(this) - ); - } - return this.pagePromises[pageIndex]; - }, - - getPageDict: function Catalog_getPageDict(pageIndex) { - var capability = createPromiseCapability(); - var nodesToVisit = [this.catDict.getRaw('Pages')]; - var currentPageIndex = 0; - var xref = this.xref; - var checkAllKids = false; - - function next() { - while (nodesToVisit.length) { - var currentNode = nodesToVisit.pop(); - - if (isRef(currentNode)) { - xref.fetchAsync(currentNode).then(function (obj) { - if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) { - if (pageIndex === currentPageIndex) { - capability.resolve([obj, currentNode]); - } else { - currentPageIndex++; - next(); - } - return; - } - nodesToVisit.push(obj); - next(); - }, capability.reject); - return; - } - - // Must be a child page dictionary. - assert( - isDict(currentNode), - 'page dictionary kid reference points to wrong type of object' - ); - var count = currentNode.get('Count'); - // If the current node doesn't have any children, avoid getting stuck - // in an empty node further down in the tree (see issue5644.pdf). - if (count === 0) { - checkAllKids = true; - } - // Skip nodes where the page can't be. - if (currentPageIndex + count <= pageIndex) { - currentPageIndex += count; - continue; - } - - var kids = currentNode.get('Kids'); - assert(isArray(kids), 'page dictionary kids object is not an array'); - if (!checkAllKids && count === kids.length) { - // Nodes that don't have the page have been skipped and this is the - // bottom of the tree which means the page requested must be a - // descendant of this pages node. Ideally we would just resolve the - // promise with the page ref here, but there is the case where more - // pages nodes could link to single a page (see issue 3666 pdf). To - // handle this push it back on the queue so if it is a pages node it - // will be descended into. - nodesToVisit = [kids[pageIndex - currentPageIndex]]; - currentPageIndex = pageIndex; - continue; - } else { - for (var last = kids.length - 1; last >= 0; last--) { - nodesToVisit.push(kids[last]); - } - } - } - capability.reject('Page index ' + pageIndex + ' not found.'); - } - next(); - return capability.promise; - }, - - getPageIndex: function Catalog_getPageIndex(ref) { - // The page tree nodes have the count of all the leaves below them. To get - // how many pages are before we just have to walk up the tree and keep - // adding the count of siblings to the left of the node. - var xref = this.xref; - function pagesBeforeRef(kidRef) { - var total = 0; - var parentRef; - return xref.fetchAsync(kidRef).then(function (node) { - if (!node) { - return null; - } - parentRef = node.getRaw('Parent'); - return node.getAsync('Parent'); - }).then(function (parent) { - if (!parent) { - return null; - } - return parent.getAsync('Kids'); - }).then(function (kids) { - if (!kids) { - return null; - } - var kidPromises = []; - var found = false; - for (var i = 0; i < kids.length; i++) { - var kid = kids[i]; - assert(isRef(kid), 'kids must be a ref'); - if (kid.num === kidRef.num) { - found = true; - break; - } - kidPromises.push(xref.fetchAsync(kid).then(function (kid) { - if (kid.has('Count')) { - var count = kid.get('Count'); - total += count; - } else { // page leaf node - total++; - } - })); - } - if (!found) { - error('kid ref not found in parents kids'); - } - return Promise.all(kidPromises).then(function () { - return [total, parentRef]; - }); - }); - } - - var total = 0; - function next(ref) { - return pagesBeforeRef(ref).then(function (args) { - if (!args) { - return total; - } - var count = args[0]; - var parentRef = args[1]; - total += count; - return next(parentRef); - }); - } - - return next(ref); - } - }; - - return Catalog; -})(); - -var XRef = (function XRefClosure() { - function XRef(stream, password) { - this.stream = stream; - this.entries = []; - this.xrefstms = {}; - // prepare the XRef cache - this.cache = []; - this.password = password; - this.stats = { - streamTypes: [], - fontTypes: [] - }; - } - - XRef.prototype = { - setStartXRef: function XRef_setStartXRef(startXRef) { - // Store the starting positions of xref tables as we process them - // so we can recover from missing data errors - this.startXRefQueue = [startXRef]; - }, - - parse: function XRef_parse(recoveryMode) { - var trailerDict; - if (!recoveryMode) { - trailerDict = this.readXRef(); - } else { - warn('Indexing all PDF objects'); - trailerDict = this.indexObjects(); - } - trailerDict.assignXref(this); - this.trailer = trailerDict; - var encrypt = trailerDict.get('Encrypt'); - if (encrypt) { - var ids = trailerDict.get('ID'); - var fileId = (ids && ids.length) ? ids[0] : ''; - this.encrypt = new CipherTransformFactory(encrypt, fileId, - this.password); - } - - // get the root dictionary (catalog) object - if (!(this.root = trailerDict.get('Root'))) { - error('Invalid root reference'); - } - }, - - processXRefTable: function XRef_processXRefTable(parser) { - if (!('tableState' in this)) { - // Stores state of the table as we process it so we can resume - // from middle of table in case of missing data error - this.tableState = { - entryNum: 0, - streamPos: parser.lexer.stream.pos, - parserBuf1: parser.buf1, - parserBuf2: parser.buf2 - }; - } - - var obj = this.readXRefTable(parser); - - // Sanity check - if (!isCmd(obj, 'trailer')) { - error('Invalid XRef table: could not find trailer dictionary'); - } - // Read trailer dictionary, e.g. - // trailer - // << /Size 22 - // /Root 20R - // /Info 10R - // /ID [ <81b14aafa313db63dbd6f981e49f94f4> ] - // >> - // The parser goes through the entire stream << ... >> and provides - // a getter interface for the key-value table - var dict = parser.getObj(); - - // The pdflib PDF generator can generate a nested trailer dictionary - if (!isDict(dict) && dict.dict) { - dict = dict.dict; - } - if (!isDict(dict)) { - error('Invalid XRef table: could not parse trailer dictionary'); - } - delete this.tableState; - - return dict; - }, - - readXRefTable: function XRef_readXRefTable(parser) { - // Example of cross-reference table: - // xref - // 0 1 <-- subsection header (first obj #, obj count) - // 0000000000 65535 f <-- actual object (offset, generation #, f/n) - // 23 2 <-- subsection header ... and so on ... - // 0000025518 00002 n - // 0000025635 00000 n - // trailer - // ... - - var stream = parser.lexer.stream; - var tableState = this.tableState; - stream.pos = tableState.streamPos; - parser.buf1 = tableState.parserBuf1; - parser.buf2 = tableState.parserBuf2; - - // Outer loop is over subsection headers - var obj; - - while (true) { - if (!('firstEntryNum' in tableState) || !('entryCount' in tableState)) { - if (isCmd(obj = parser.getObj(), 'trailer')) { - break; - } - tableState.firstEntryNum = obj; - tableState.entryCount = parser.getObj(); - } - - var first = tableState.firstEntryNum; - var count = tableState.entryCount; - if (!isInt(first) || !isInt(count)) { - error('Invalid XRef table: wrong types in subsection header'); - } - // Inner loop is over objects themselves - for (var i = tableState.entryNum; i < count; i++) { - tableState.streamPos = stream.pos; - tableState.entryNum = i; - tableState.parserBuf1 = parser.buf1; - tableState.parserBuf2 = parser.buf2; - - var entry = {}; - entry.offset = parser.getObj(); - entry.gen = parser.getObj(); - var type = parser.getObj(); - - if (isCmd(type, 'f')) { - entry.free = true; - } else if (isCmd(type, 'n')) { - entry.uncompressed = true; - } - - // Validate entry obj - if (!isInt(entry.offset) || !isInt(entry.gen) || - !(entry.free || entry.uncompressed)) { - error('Invalid entry in XRef subsection: ' + first + ', ' + count); - } - - if (!this.entries[i + first]) { - this.entries[i + first] = entry; - } - } - - tableState.entryNum = 0; - tableState.streamPos = stream.pos; - tableState.parserBuf1 = parser.buf1; - tableState.parserBuf2 = parser.buf2; - delete tableState.firstEntryNum; - delete tableState.entryCount; - } - - // Per issue 3248: hp scanners generate bad XRef - if (first === 1 && this.entries[1] && this.entries[1].free) { - // shifting the entries - this.entries.shift(); - } - - // Sanity check: as per spec, first object must be free - if (this.entries[0] && !this.entries[0].free) { - error('Invalid XRef table: unexpected first object'); - } - return obj; - }, - - processXRefStream: function XRef_processXRefStream(stream) { - if (!('streamState' in this)) { - // Stores state of the stream as we process it so we can resume - // from middle of stream in case of missing data error - var streamParameters = stream.dict; - var byteWidths = streamParameters.get('W'); - var range = streamParameters.get('Index'); - if (!range) { - range = [0, streamParameters.get('Size')]; - } - - this.streamState = { - entryRanges: range, - byteWidths: byteWidths, - entryNum: 0, - streamPos: stream.pos - }; - } - this.readXRefStream(stream); - delete this.streamState; - - return stream.dict; - }, - - readXRefStream: function XRef_readXRefStream(stream) { - var i, j; - var streamState = this.streamState; - stream.pos = streamState.streamPos; - - var byteWidths = streamState.byteWidths; - var typeFieldWidth = byteWidths[0]; - var offsetFieldWidth = byteWidths[1]; - var generationFieldWidth = byteWidths[2]; - - var entryRanges = streamState.entryRanges; - while (entryRanges.length > 0) { - var first = entryRanges[0]; - var n = entryRanges[1]; - - if (!isInt(first) || !isInt(n)) { - error('Invalid XRef range fields: ' + first + ', ' + n); - } - if (!isInt(typeFieldWidth) || !isInt(offsetFieldWidth) || - !isInt(generationFieldWidth)) { - error('Invalid XRef entry fields length: ' + first + ', ' + n); - } - for (i = streamState.entryNum; i < n; ++i) { - streamState.entryNum = i; - streamState.streamPos = stream.pos; - - var type = 0, offset = 0, generation = 0; - for (j = 0; j < typeFieldWidth; ++j) { - type = (type << 8) | stream.getByte(); - } - // if type field is absent, its default value is 1 - if (typeFieldWidth === 0) { - type = 1; - } - for (j = 0; j < offsetFieldWidth; ++j) { - offset = (offset << 8) | stream.getByte(); - } - for (j = 0; j < generationFieldWidth; ++j) { - generation = (generation << 8) | stream.getByte(); - } - var entry = {}; - entry.offset = offset; - entry.gen = generation; - switch (type) { - case 0: - entry.free = true; - break; - case 1: - entry.uncompressed = true; - break; - case 2: - break; - default: - error('Invalid XRef entry type: ' + type); - } - if (!this.entries[first + i]) { - this.entries[first + i] = entry; - } - } - - streamState.entryNum = 0; - streamState.streamPos = stream.pos; - entryRanges.splice(0, 2); - } - }, - - indexObjects: function XRef_indexObjects() { - // Simple scan through the PDF content to find objects, - // trailers and XRef streams. - function readToken(data, offset) { - var token = '', ch = data[offset]; - while (ch !== 13 && ch !== 10) { - if (++offset >= data.length) { - break; - } - token += String.fromCharCode(ch); - ch = data[offset]; - } - return token; - } - function skipUntil(data, offset, what) { - var length = what.length, dataLength = data.length; - var skipped = 0; - // finding byte sequence - while (offset < dataLength) { - var i = 0; - while (i < length && data[offset + i] === what[i]) { - ++i; - } - if (i >= length) { - break; // sequence found - } - offset++; - skipped++; - } - return skipped; - } - var trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]); - var startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, - 101, 102]); - var endobjBytes = new Uint8Array([101, 110, 100, 111, 98, 106]); - var xrefBytes = new Uint8Array([47, 88, 82, 101, 102]); - - var stream = this.stream; - stream.pos = 0; - var buffer = stream.getBytes(); - var position = stream.start, length = buffer.length; - var trailers = [], xrefStms = []; - while (position < length) { - var ch = buffer[position]; - if (ch === 32 || ch === 9 || ch === 13 || ch === 10) { - ++position; - continue; - } - if (ch === 37) { // %-comment - do { - ++position; - if (position >= length) { - break; - } - ch = buffer[position]; - } while (ch !== 13 && ch !== 10); - continue; - } - var token = readToken(buffer, position); - var m; - if (token === 'xref') { - position += skipUntil(buffer, position, trailerBytes); - trailers.push(position); - position += skipUntil(buffer, position, startxrefBytes); - } else if ((m = /^(\d+)\s+(\d+)\s+obj\b/.exec(token))) { - this.entries[m[1]] = { - offset: position, - gen: m[2] | 0, - uncompressed: true - }; - - var contentLength = skipUntil(buffer, position, endobjBytes) + 7; - var content = buffer.subarray(position, position + contentLength); - - // checking XRef stream suspect - // (it shall have '/XRef' and next char is not a letter) - var xrefTagOffset = skipUntil(content, 0, xrefBytes); - if (xrefTagOffset < contentLength && - content[xrefTagOffset + 5] < 64) { - xrefStms.push(position); - this.xrefstms[position] = 1; // don't read it recursively - } - - position += contentLength; - } else { - position += token.length + 1; - } - } - // reading XRef streams - var i, ii; - for (i = 0, ii = xrefStms.length; i < ii; ++i) { - this.startXRefQueue.push(xrefStms[i]); - this.readXRef(/* recoveryMode */ true); - } - // finding main trailer - var dict; - for (i = 0, ii = trailers.length; i < ii; ++i) { - stream.pos = trailers[i]; - var parser = new Parser(new Lexer(stream), true, this); - var obj = parser.getObj(); - if (!isCmd(obj, 'trailer')) { - continue; - } - // read the trailer dictionary - if (!isDict(dict = parser.getObj())) { - continue; - } - // taking the first one with 'ID' - if (dict.has('ID')) { - return dict; - } - } - // no tailer with 'ID', taking last one (if exists) - if (dict) { - return dict; - } - // nothing helps - // calling error() would reject worker with an UnknownErrorException. - throw new InvalidPDFException('Invalid PDF structure'); - }, - - readXRef: function XRef_readXRef(recoveryMode) { - var stream = this.stream; - - try { - while (this.startXRefQueue.length) { - var startXRef = this.startXRefQueue[0]; - - stream.pos = startXRef + stream.start; - - var parser = new Parser(new Lexer(stream), true, this); - var obj = parser.getObj(); - var dict; - - // Get dictionary - if (isCmd(obj, 'xref')) { - // Parse end-of-file XRef - dict = this.processXRefTable(parser); - if (!this.topDict) { - this.topDict = dict; - } - - // Recursively get other XRefs 'XRefStm', if any - obj = dict.get('XRefStm'); - if (isInt(obj)) { - var pos = obj; - // ignore previously loaded xref streams - // (possible infinite recursion) - if (!(pos in this.xrefstms)) { - this.xrefstms[pos] = 1; - this.startXRefQueue.push(pos); - } - } - } else if (isInt(obj)) { - // Parse in-stream XRef - if (!isInt(parser.getObj()) || - !isCmd(parser.getObj(), 'obj') || - !isStream(obj = parser.getObj())) { - error('Invalid XRef stream'); - } - dict = this.processXRefStream(obj); - if (!this.topDict) { - this.topDict = dict; - } - if (!dict) { - error('Failed to read XRef stream'); - } - } else { - error('Invalid XRef stream header'); - } - - // Recursively get previous dictionary, if any - obj = dict.get('Prev'); - if (isInt(obj)) { - this.startXRefQueue.push(obj); - } else if (isRef(obj)) { - // The spec says Prev must not be a reference, i.e. "/Prev NNN" - // This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R" - this.startXRefQueue.push(obj.num); - } - - this.startXRefQueue.shift(); - } - - return this.topDict; - } catch (e) { - if (e instanceof MissingDataException) { - throw e; - } - info('(while reading XRef): ' + e); - } - - if (recoveryMode) { - return; - } - throw new XRefParseException(); - }, - - getEntry: function XRef_getEntry(i) { - var xrefEntry = this.entries[i]; - if (xrefEntry && !xrefEntry.free && xrefEntry.offset) { - return xrefEntry; - } - return null; - }, - - fetchIfRef: function XRef_fetchIfRef(obj) { - if (!isRef(obj)) { - return obj; - } - return this.fetch(obj); - }, - - fetch: function XRef_fetch(ref, suppressEncryption) { - assert(isRef(ref), 'ref object is not a reference'); - var num = ref.num; - if (num in this.cache) { - var cacheEntry = this.cache[num]; - return cacheEntry; - } - - var xrefEntry = this.getEntry(num); - - // the referenced entry can be free - if (xrefEntry === null) { - return (this.cache[num] = null); - } - - if (xrefEntry.uncompressed) { - xrefEntry = this.fetchUncompressed(ref, xrefEntry, suppressEncryption); - } else { - xrefEntry = this.fetchCompressed(xrefEntry, suppressEncryption); - } - if (isDict(xrefEntry)){ - xrefEntry.objId = ref.toString(); - } else if (isStream(xrefEntry)) { - xrefEntry.dict.objId = ref.toString(); - } - return xrefEntry; - }, - - fetchUncompressed: function XRef_fetchUncompressed(ref, xrefEntry, - suppressEncryption) { - var gen = ref.gen; - var num = ref.num; - if (xrefEntry.gen !== gen) { - error('inconsistent generation in XRef'); - } - var stream = this.stream.makeSubStream(xrefEntry.offset + - this.stream.start); - var parser = new Parser(new Lexer(stream), true, this); - var obj1 = parser.getObj(); - var obj2 = parser.getObj(); - var obj3 = parser.getObj(); - if (!isInt(obj1) || parseInt(obj1, 10) !== num || - !isInt(obj2) || parseInt(obj2, 10) !== gen || - !isCmd(obj3)) { - error('bad XRef entry'); - } - if (!isCmd(obj3, 'obj')) { - // some bad PDFs use "obj1234" and really mean 1234 - if (obj3.cmd.indexOf('obj') === 0) { - num = parseInt(obj3.cmd.substring(3), 10); - if (!isNaN(num)) { - return num; - } - } - error('bad XRef entry'); - } - if (this.encrypt && !suppressEncryption) { - xrefEntry = parser.getObj(this.encrypt.createCipherTransform(num, gen)); - } else { - xrefEntry = parser.getObj(); - } - if (!isStream(xrefEntry)) { - this.cache[num] = xrefEntry; - } - return xrefEntry; - }, - - fetchCompressed: function XRef_fetchCompressed(xrefEntry, - suppressEncryption) { - var tableOffset = xrefEntry.offset; - var stream = this.fetch(new Ref(tableOffset, 0)); - if (!isStream(stream)) { - error('bad ObjStm stream'); - } - var first = stream.dict.get('First'); - var n = stream.dict.get('N'); - if (!isInt(first) || !isInt(n)) { - error('invalid first and n parameters for ObjStm stream'); - } - var parser = new Parser(new Lexer(stream), false, this); - parser.allowStreams = true; - var i, entries = [], num, nums = []; - // read the object numbers to populate cache - for (i = 0; i < n; ++i) { - num = parser.getObj(); - if (!isInt(num)) { - error('invalid object number in the ObjStm stream: ' + num); - } - nums.push(num); - var offset = parser.getObj(); - if (!isInt(offset)) { - error('invalid object offset in the ObjStm stream: ' + offset); - } - } - // read stream objects for cache - for (i = 0; i < n; ++i) { - entries.push(parser.getObj()); - num = nums[i]; - var entry = this.entries[num]; - if (entry && entry.offset === tableOffset && entry.gen === i) { - this.cache[num] = entries[i]; - } - } - xrefEntry = entries[xrefEntry.gen]; - if (xrefEntry === undefined) { - error('bad XRef entry for compressed object'); - } - return xrefEntry; - }, - - fetchIfRefAsync: function XRef_fetchIfRefAsync(obj) { - if (!isRef(obj)) { - return Promise.resolve(obj); - } - return this.fetchAsync(obj); - }, - - fetchAsync: function XRef_fetchAsync(ref, suppressEncryption) { - var streamManager = this.stream.manager; - var xref = this; - return new Promise(function tryFetch(resolve, reject) { - try { - resolve(xref.fetch(ref, suppressEncryption)); - } catch (e) { - if (e instanceof MissingDataException) { - streamManager.requestRange(e.begin, e.end, function () { - tryFetch(resolve, reject); - }); - return; - } - reject(e); - } - }); - }, - - getCatalogObj: function XRef_getCatalogObj() { - return this.root; - } - }; - - return XRef; -})(); - -/** - * A NameTree is like a Dict but has some advantageous properties, see the - * spec (7.9.6) for more details. - * TODO: implement all the Dict functions and make this more efficent. - */ -var NameTree = (function NameTreeClosure() { - function NameTree(root, xref) { - this.root = root; - this.xref = xref; - } - - NameTree.prototype = { - getAll: function NameTree_getAll() { - var dict = {}; - if (!this.root) { - return dict; - } - var xref = this.xref; - // reading name tree - var processed = new RefSet(); - processed.put(this.root); - var queue = [this.root]; - while (queue.length > 0) { - var i, n; - var obj = xref.fetchIfRef(queue.shift()); - if (!isDict(obj)) { - continue; - } - if (obj.has('Kids')) { - var kids = obj.get('Kids'); - for (i = 0, n = kids.length; i < n; i++) { - var kid = kids[i]; - if (processed.has(kid)) { - error('invalid destinations'); - } - queue.push(kid); - processed.put(kid); - } - continue; - } - var names = obj.get('Names'); - if (names) { - for (i = 0, n = names.length; i < n; i += 2) { - dict[names[i]] = xref.fetchIfRef(names[i + 1]); - } - } - } - return dict; - }, - - get: function NameTree_get(destinationId) { - if (!this.root) { - return null; - } - - var xref = this.xref; - var kidsOrNames = xref.fetchIfRef(this.root); - var loopCount = 0; - var MAX_NAMES_LEVELS = 10; - var l, r, m; - - // Perform a binary search to quickly find the entry that - // contains the named destination we are looking for. - while (kidsOrNames.has('Kids')) { - loopCount++; - if (loopCount > MAX_NAMES_LEVELS) { - warn('Search depth limit for named destionations has been reached.'); - return null; - } - - var kids = kidsOrNames.get('Kids'); - if (!isArray(kids)) { - return null; - } - - l = 0; - r = kids.length - 1; - while (l <= r) { - m = (l + r) >> 1; - var kid = xref.fetchIfRef(kids[m]); - var limits = kid.get('Limits'); - - if (destinationId < limits[0]) { - r = m - 1; - } else if (destinationId > limits[1]) { - l = m + 1; - } else { - kidsOrNames = xref.fetchIfRef(kids[m]); - break; - } - } - if (l > r) { - return null; - } - } - - // If we get here, then we have found the right entry. Now - // go through the named destinations in the Named dictionary - // until we find the exact destination we're looking for. - var names = kidsOrNames.get('Names'); - if (isArray(names)) { - // Perform a binary search to reduce the lookup time. - l = 0; - r = names.length - 2; - while (l <= r) { - // Check only even indices (0, 2, 4, ...) because the - // odd indices contain the actual D array. - m = (l + r) & ~1; - if (destinationId < names[m]) { - r = m - 2; - } else if (destinationId > names[m]) { - l = m + 2; - } else { - return xref.fetchIfRef(names[m + 1]); - } - } - } - return null; - } - }; - return NameTree; -})(); - -/** - * "A PDF file can refer to the contents of another file by using a File - * Specification (PDF 1.1)", see the spec (7.11) for more details. - * NOTE: Only embedded files are supported (as part of the attachments support) - * TODO: support the 'URL' file system (with caching if !/V), portable - * collections attributes and related files (/RF) - */ -var FileSpec = (function FileSpecClosure() { - function FileSpec(root, xref) { - if (!root || !isDict(root)) { - return; - } - this.xref = xref; - this.root = root; - if (root.has('FS')) { - this.fs = root.get('FS'); - } - this.description = root.has('Desc') ? - stringToPDFString(root.get('Desc')) : - ''; - if (root.has('RF')) { - warn('Related file specifications are not supported'); - } - this.contentAvailable = true; - if (!root.has('EF')) { - this.contentAvailable = false; - warn('Non-embedded file specifications are not supported'); - } - } - - function pickPlatformItem(dict) { - // Look for the filename in this order: - // UF, F, Unix, Mac, DOS - if (dict.has('UF')) { - return dict.get('UF'); - } else if (dict.has('F')) { - return dict.get('F'); - } else if (dict.has('Unix')) { - return dict.get('Unix'); - } else if (dict.has('Mac')) { - return dict.get('Mac'); - } else if (dict.has('DOS')) { - return dict.get('DOS'); - } else { - return null; - } - } - - FileSpec.prototype = { - get filename() { - if (!this._filename && this.root) { - var filename = pickPlatformItem(this.root) || 'unnamed'; - this._filename = stringToPDFString(filename). - replace(/\\\\/g, '\\'). - replace(/\\\//g, '/'). - replace(/\\/g, '/'); - } - return this._filename; - }, - get content() { - if (!this.contentAvailable) { - return null; - } - if (!this.contentRef && this.root) { - this.contentRef = pickPlatformItem(this.root.get('EF')); - } - var content = null; - if (this.contentRef) { - var xref = this.xref; - var fileObj = xref.fetchIfRef(this.contentRef); - if (fileObj && isStream(fileObj)) { - content = fileObj.getBytes(); - } else { - warn('Embedded file specification points to non-existing/invalid ' + - 'content'); - } - } else { - warn('Embedded file specification does not have a content'); - } - return content; - }, - get serializable() { - return { - filename: this.filename, - content: this.content - }; - } - }; - return FileSpec; -})(); - -/** - * A helper for loading missing data in object graphs. It traverses the graph - * depth first and queues up any objects that have missing data. Once it has - * has traversed as many objects that are available it attempts to bundle the - * missing data requests and then resume from the nodes that weren't ready. - * - * NOTE: It provides protection from circular references by keeping track of - * of loaded references. However, you must be careful not to load any graphs - * that have references to the catalog or other pages since that will cause the - * entire PDF document object graph to be traversed. - */ -var ObjectLoader = (function() { - function mayHaveChildren(value) { - return isRef(value) || isDict(value) || isArray(value) || isStream(value); - } - - function addChildren(node, nodesToVisit) { - var value; - if (isDict(node) || isStream(node)) { - var map; - if (isDict(node)) { - map = node.map; - } else { - map = node.dict.map; - } - for (var key in map) { - value = map[key]; - if (mayHaveChildren(value)) { - nodesToVisit.push(value); - } - } - } else if (isArray(node)) { - for (var i = 0, ii = node.length; i < ii; i++) { - value = node[i]; - if (mayHaveChildren(value)) { - nodesToVisit.push(value); - } - } - } - } - - function ObjectLoader(obj, keys, xref) { - this.obj = obj; - this.keys = keys; - this.xref = xref; - this.refSet = null; - } - - ObjectLoader.prototype = { - load: function ObjectLoader_load() { - var keys = this.keys; - this.capability = createPromiseCapability(); - // Don't walk the graph if all the data is already loaded. - if (!(this.xref.stream instanceof ChunkedStream) || - this.xref.stream.getMissingChunks().length === 0) { - this.capability.resolve(); - return this.capability.promise; - } - - this.refSet = new RefSet(); - // Setup the initial nodes to visit. - var nodesToVisit = []; - for (var i = 0; i < keys.length; i++) { - nodesToVisit.push(this.obj[keys[i]]); - } - - this.walk(nodesToVisit); - return this.capability.promise; - }, - - walk: function ObjectLoader_walk(nodesToVisit) { - var nodesToRevisit = []; - var pendingRequests = []; - // DFS walk of the object graph. - while (nodesToVisit.length) { - var currentNode = nodesToVisit.pop(); - - // Only references or chunked streams can cause missing data exceptions. - if (isRef(currentNode)) { - // Skip nodes that have already been visited. - if (this.refSet.has(currentNode)) { - continue; - } - try { - var ref = currentNode; - this.refSet.put(ref); - currentNode = this.xref.fetch(currentNode); - } catch (e) { - if (!(e instanceof MissingDataException)) { - throw e; - } - nodesToRevisit.push(currentNode); - pendingRequests.push({ begin: e.begin, end: e.end }); - } - } - if (currentNode && currentNode.getBaseStreams) { - var baseStreams = currentNode.getBaseStreams(); - var foundMissingData = false; - for (var i = 0; i < baseStreams.length; i++) { - var stream = baseStreams[i]; - if (stream.getMissingChunks && stream.getMissingChunks().length) { - foundMissingData = true; - pendingRequests.push({ - begin: stream.start, - end: stream.end - }); - } - } - if (foundMissingData) { - nodesToRevisit.push(currentNode); - } - } - - addChildren(currentNode, nodesToVisit); - } - - if (pendingRequests.length) { - this.xref.stream.manager.requestRanges(pendingRequests, - function pendingRequestCallback() { - nodesToVisit = nodesToRevisit; - for (var i = 0; i < nodesToRevisit.length; i++) { - var node = nodesToRevisit[i]; - // Remove any reference nodes from the currrent refset so they - // aren't skipped when we revist them. - if (isRef(node)) { - this.refSet.remove(node); - } - } - this.walk(nodesToVisit); - }.bind(this)); - return; - } - // Everything is loaded. - this.refSet = null; - this.capability.resolve(); - } - }; - - return ObjectLoader; -})(); - - -var ISOAdobeCharset = [ - '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', - 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', - 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', - 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', - 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', - 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', - 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', - 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', - 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', - 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', - 'periodcentered', 'paragraph', 'bullet', 'quotesinglbase', - 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', - 'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', - 'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla', - 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', - 'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash', - 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu', - 'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', - 'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior', - 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright', - 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', - 'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute', - 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex', - 'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', - 'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute', - 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla', - 'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', - 'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis', - 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', - 'ugrave', 'yacute', 'ydieresis', 'zcaron' -]; - -var ExpertCharset = [ - '.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', - 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', - 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', - 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', - 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', - 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', - 'colon', 'semicolon', 'commasuperior', 'threequartersemdash', - 'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior', - 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', - 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', - 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', - 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', - 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', - 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', - 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', - 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle', - 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', - 'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall', - 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', - 'Cedillasmall', 'onequarter', 'onehalf', 'threequarters', - 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', - 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', - 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', - 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', - 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', - 'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall', - 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', - 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', - 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', - 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', - 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', - 'Ydieresissmall' -]; - -var ExpertSubsetCharset = [ - '.notdef', 'space', 'dollaroldstyle', 'dollarsuperior', - 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', - 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', - 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', - 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', - 'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior', - 'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior', - 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', - 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', - 'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted', - 'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter', - 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', - 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', - 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', - 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', - 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', - 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', - 'periodinferior', 'commainferior' -]; - - -var DEFAULT_ICON_SIZE = 22; // px -var SUPPORTED_TYPES = ['Link', 'Text', 'Widget']; - -var Annotation = (function AnnotationClosure() { - // 12.5.5: Algorithm: Appearance streams - function getTransformMatrix(rect, bbox, matrix) { - var bounds = Util.getAxialAlignedBoundingBox(bbox, matrix); - var minX = bounds[0]; - var minY = bounds[1]; - var maxX = bounds[2]; - var maxY = bounds[3]; - - if (minX === maxX || minY === maxY) { - // From real-life file, bbox was [0, 0, 0, 0]. In this case, - // just apply the transform for rect - return [1, 0, 0, 1, rect[0], rect[1]]; - } - - var xRatio = (rect[2] - rect[0]) / (maxX - minX); - var yRatio = (rect[3] - rect[1]) / (maxY - minY); - return [ - xRatio, - 0, - 0, - yRatio, - rect[0] - minX * xRatio, - rect[1] - minY * yRatio - ]; - } - - function getDefaultAppearance(dict) { - var appearanceState = dict.get('AP'); - if (!isDict(appearanceState)) { - return; - } - - var appearance; - var appearances = appearanceState.get('N'); - if (isDict(appearances)) { - var as = dict.get('AS'); - if (as && appearances.has(as.name)) { - appearance = appearances.get(as.name); - } - } else { - appearance = appearances; - } - return appearance; - } - - function Annotation(params) { - var dict = params.dict; - var data = this.data = {}; - - data.subtype = dict.get('Subtype').name; - var rect = dict.get('Rect') || [0, 0, 0, 0]; - data.rect = Util.normalizeRect(rect); - data.annotationFlags = dict.get('F'); - - var color = dict.get('C'); - if (!color) { - // The PDF spec does not mention how a missing color array is interpreted. - // Adobe Reader seems to default to black in this case. - data.color = [0, 0, 0]; - } else if (isArray(color)) { - switch (color.length) { - case 0: - // Empty array denotes transparent border. - data.color = null; - break; - case 1: - // TODO: implement DeviceGray - break; - case 3: - data.color = color; - break; - case 4: - // TODO: implement DeviceCMYK - break; - } - } - - // Some types of annotations have border style dict which has more - // info than the border array - if (dict.has('BS')) { - var borderStyle = dict.get('BS'); - data.borderWidth = borderStyle.has('W') ? borderStyle.get('W') : 1; - } else { - var borderArray = dict.get('Border') || [0, 0, 1]; - data.borderWidth = borderArray[2] || 0; - - // TODO: implement proper support for annotations with line dash patterns. - var dashArray = borderArray[3]; - if (data.borderWidth > 0 && dashArray) { - if (!isArray(dashArray)) { - // Ignore the border if dashArray is not actually an array, - // this is consistent with the behaviour in Adobe Reader. - data.borderWidth = 0; - } else { - var dashArrayLength = dashArray.length; - if (dashArrayLength > 0) { - // According to the PDF specification: the elements in a dashArray - // shall be numbers that are nonnegative and not all equal to zero. - var isInvalid = false; - var numPositive = 0; - for (var i = 0; i < dashArrayLength; i++) { - var validNumber = (+dashArray[i] >= 0); - if (!validNumber) { - isInvalid = true; - break; - } else if (dashArray[i] > 0) { - numPositive++; - } - } - if (isInvalid || numPositive === 0) { - data.borderWidth = 0; - } - } - } - } - } - - this.appearance = getDefaultAppearance(dict); - data.hasAppearance = !!this.appearance; - data.id = params.ref.num; - } - - Annotation.prototype = { - - getData: function Annotation_getData() { - return this.data; - }, - - isInvisible: function Annotation_isInvisible() { - var data = this.data; - if (data && SUPPORTED_TYPES.indexOf(data.subtype) !== -1) { - return false; - } else { - return !!(data && - data.annotationFlags && // Default: not invisible - data.annotationFlags & 0x1); // Invisible - } - }, - - isViewable: function Annotation_isViewable() { - var data = this.data; - return !!(!this.isInvisible() && - data && - (!data.annotationFlags || - !(data.annotationFlags & 0x22)) && // Hidden or NoView - data.rect); // rectangle is necessary - }, - - isPrintable: function Annotation_isPrintable() { - var data = this.data; - return !!(!this.isInvisible() && - data && - data.annotationFlags && // Default: not printable - data.annotationFlags & 0x4 && // Print - !(data.annotationFlags & 0x2) && // Hidden - data.rect); // rectangle is necessary - }, - - loadResources: function Annotation_loadResources(keys) { - return new Promise(function (resolve, reject) { - this.appearance.dict.getAsync('Resources').then(function (resources) { - if (!resources) { - resolve(); - return; - } - var objectLoader = new ObjectLoader(resources.map, - keys, - resources.xref); - objectLoader.load().then(function() { - resolve(resources); - }, reject); - }, reject); - }.bind(this)); - }, - - getOperatorList: function Annotation_getOperatorList(evaluator) { - - if (!this.appearance) { - return Promise.resolve(new OperatorList()); - } - - var data = this.data; - - var appearanceDict = this.appearance.dict; - var resourcesPromise = this.loadResources([ - 'ExtGState', - 'ColorSpace', - 'Pattern', - 'Shading', - 'XObject', - 'Font' - // ProcSet - // Properties - ]); - var bbox = appearanceDict.get('BBox') || [0, 0, 1, 1]; - var matrix = appearanceDict.get('Matrix') || [1, 0, 0, 1, 0 ,0]; - var transform = getTransformMatrix(data.rect, bbox, matrix); - var self = this; - - return resourcesPromise.then(function(resources) { - var opList = new OperatorList(); - opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]); - return evaluator.getOperatorList(self.appearance, resources, opList). - then(function () { - opList.addOp(OPS.endAnnotation, []); - self.appearance.reset(); - return opList; - }); - }); - } - }; - - Annotation.getConstructor = - function Annotation_getConstructor(subtype, fieldType) { - - if (!subtype) { - return; - } - - // TODO(mack): Implement FreeText annotations - if (subtype === 'Link') { - return LinkAnnotation; - } else if (subtype === 'Text') { - return TextAnnotation; - } else if (subtype === 'Widget') { - if (!fieldType) { - return; - } - - if (fieldType === 'Tx') { - return TextWidgetAnnotation; - } else { - return WidgetAnnotation; - } - } else { - return Annotation; - } - }; - - Annotation.fromRef = function Annotation_fromRef(xref, ref) { - - var dict = xref.fetchIfRef(ref); - if (!isDict(dict)) { - return; - } - - var subtype = dict.get('Subtype'); - subtype = isName(subtype) ? subtype.name : ''; - if (!subtype) { - return; - } - - var fieldType = Util.getInheritableProperty(dict, 'FT'); - fieldType = isName(fieldType) ? fieldType.name : ''; - - var Constructor = Annotation.getConstructor(subtype, fieldType); - if (!Constructor) { - return; - } - - var params = { - dict: dict, - ref: ref, - }; - - var annotation = new Constructor(params); - - if (annotation.isViewable() || annotation.isPrintable()) { - return annotation; - } else { - if (SUPPORTED_TYPES.indexOf(subtype) === -1) { - warn('unimplemented annotation type: ' + subtype); - } - } - }; - - Annotation.appendToOperatorList = function Annotation_appendToOperatorList( - annotations, opList, pdfManager, partialEvaluator, intent) { - - function reject(e) { - annotationsReadyCapability.reject(e); - } - - var annotationsReadyCapability = createPromiseCapability(); - - var annotationPromises = []; - for (var i = 0, n = annotations.length; i < n; ++i) { - if (intent === 'display' && annotations[i].isViewable() || - intent === 'print' && annotations[i].isPrintable()) { - annotationPromises.push( - annotations[i].getOperatorList(partialEvaluator)); - } - } - Promise.all(annotationPromises).then(function(datas) { - opList.addOp(OPS.beginAnnotations, []); - for (var i = 0, n = datas.length; i < n; ++i) { - var annotOpList = datas[i]; - opList.addOpList(annotOpList); - } - opList.addOp(OPS.endAnnotations, []); - annotationsReadyCapability.resolve(); - }, reject); - - return annotationsReadyCapability.promise; - }; - - return Annotation; -})(); - -var WidgetAnnotation = (function WidgetAnnotationClosure() { - - function WidgetAnnotation(params) { - Annotation.call(this, params); - - var dict = params.dict; - var data = this.data; - - data.fieldValue = stringToPDFString( - Util.getInheritableProperty(dict, 'V') || ''); - data.alternativeText = stringToPDFString(dict.get('TU') || ''); - data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || ''; - var fieldType = Util.getInheritableProperty(dict, 'FT'); - data.fieldType = isName(fieldType) ? fieldType.name : ''; - data.fieldFlags = Util.getInheritableProperty(dict, 'Ff') || 0; - this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty; - - // Building the full field name by collecting the field and - // its ancestors 'T' data and joining them using '.'. - var fieldName = []; - var namedItem = dict; - var ref = params.ref; - while (namedItem) { - var parent = namedItem.get('Parent'); - var parentRef = namedItem.getRaw('Parent'); - var name = namedItem.get('T'); - if (name) { - fieldName.unshift(stringToPDFString(name)); - } else if (parent && ref) { - // The field name is absent, that means more than one field - // with the same name may exist. Replacing the empty name - // with the '`' plus index in the parent's 'Kids' array. - // This is not in the PDF spec but necessary to id the - // the input controls. - var kids = parent.get('Kids'); - var j, jj; - for (j = 0, jj = kids.length; j < jj; j++) { - var kidRef = kids[j]; - if (kidRef.num === ref.num && kidRef.gen === ref.gen) { - break; - } - } - fieldName.unshift('`' + j); - } - namedItem = parent; - ref = parentRef; - } - data.fullName = fieldName.join('.'); - } - - var parent = Annotation.prototype; - Util.inherit(WidgetAnnotation, Annotation, { - isViewable: function WidgetAnnotation_isViewable() { - if (this.data.fieldType === 'Sig') { - warn('unimplemented annotation type: Widget signature'); - return false; - } - - return parent.isViewable.call(this); - } - }); - - return WidgetAnnotation; -})(); - -var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { - function TextWidgetAnnotation(params) { - WidgetAnnotation.call(this, params); - - this.data.textAlignment = Util.getInheritableProperty(params.dict, 'Q'); - this.data.annotationType = AnnotationType.WIDGET; - this.data.hasHtml = !this.data.hasAppearance && !!this.data.fieldValue; - } - - Util.inherit(TextWidgetAnnotation, WidgetAnnotation, { - getOperatorList: function TextWidgetAnnotation_getOperatorList(evaluator) { - if (this.appearance) { - return Annotation.prototype.getOperatorList.call(this, evaluator); - } - - var opList = new OperatorList(); - var data = this.data; - - // Even if there is an appearance stream, ignore it. This is the - // behaviour used by Adobe Reader. - if (!data.defaultAppearance) { - return Promise.resolve(opList); - } - - var stream = new Stream(stringToBytes(data.defaultAppearance)); - return evaluator.getOperatorList(stream, this.fieldResources, opList). - then(function () { - return opList; - }); - } - }); - - return TextWidgetAnnotation; -})(); - -var InteractiveAnnotation = (function InteractiveAnnotationClosure() { - function InteractiveAnnotation(params) { - Annotation.call(this, params); - - this.data.hasHtml = true; - } - - Util.inherit(InteractiveAnnotation, Annotation, { }); - - return InteractiveAnnotation; -})(); - -var TextAnnotation = (function TextAnnotationClosure() { - function TextAnnotation(params) { - InteractiveAnnotation.call(this, params); - - var dict = params.dict; - var data = this.data; - - var content = dict.get('Contents'); - var title = dict.get('T'); - data.annotationType = AnnotationType.TEXT; - data.content = stringToPDFString(content || ''); - data.title = stringToPDFString(title || ''); - - if (data.hasAppearance) { - data.name = 'NoIcon'; - } else { - data.rect[1] = data.rect[3] - DEFAULT_ICON_SIZE; - data.rect[2] = data.rect[0] + DEFAULT_ICON_SIZE; - data.name = dict.has('Name') ? dict.get('Name').name : 'Note'; - } - - if (dict.has('C')) { - data.hasBgColor = true; - } - } - - Util.inherit(TextAnnotation, InteractiveAnnotation, { }); - - return TextAnnotation; -})(); - -var LinkAnnotation = (function LinkAnnotationClosure() { - function LinkAnnotation(params) { - InteractiveAnnotation.call(this, params); - - var dict = params.dict; - var data = this.data; - data.annotationType = AnnotationType.LINK; - - var action = dict.get('A'); - if (action && isDict(action)) { - var linkType = action.get('S').name; - if (linkType === 'URI') { - var url = action.get('URI'); - if (isName(url)) { - // Some bad PDFs do not put parentheses around relative URLs. - url = '/' + url.name; - } else if (url) { - url = addDefaultProtocolToUrl(url); - } - // TODO: pdf spec mentions urls can be relative to a Base - // entry in the dictionary. - if (!isValidUrl(url, false)) { - url = ''; - } - data.url = url; - } else if (linkType === 'GoTo') { - data.dest = action.get('D'); - } else if (linkType === 'GoToR') { - var urlDict = action.get('F'); - if (isDict(urlDict)) { - // We assume that the 'url' is a Filspec dictionary - // and fetch the url without checking any further - url = urlDict.get('F') || ''; - } - - // TODO: pdf reference says that GoToR - // can also have 'NewWindow' attribute - if (!isValidUrl(url, false)) { - url = ''; - } - data.url = url; - data.dest = action.get('D'); - } else if (linkType === 'Named') { - data.action = action.get('N').name; - } else { - warn('unrecognized link type: ' + linkType); - } - } else if (dict.has('Dest')) { - // simple destination link - var dest = dict.get('Dest'); - data.dest = isName(dest) ? dest.name : dest; - } - } - - // Lets URLs beginning with 'www.' default to using the 'http://' protocol. - function addDefaultProtocolToUrl(url) { - if (url && url.indexOf('www.') === 0) { - return ('http://' + url); - } - return url; - } - - Util.inherit(LinkAnnotation, InteractiveAnnotation, { }); - - return LinkAnnotation; -})(); - - -var PDFFunction = (function PDFFunctionClosure() { - var CONSTRUCT_SAMPLED = 0; - var CONSTRUCT_INTERPOLATED = 2; - var CONSTRUCT_STICHED = 3; - var CONSTRUCT_POSTSCRIPT = 4; - - return { - getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps, - str) { - var i, ii; - var length = 1; - for (i = 0, ii = size.length; i < ii; i++) { - length *= size[i]; - } - length *= outputSize; - - var array = new Array(length); - var codeSize = 0; - var codeBuf = 0; - // 32 is a valid bps so shifting won't work - var sampleMul = 1.0 / (Math.pow(2.0, bps) - 1); - - var strBytes = str.getBytes((length * bps + 7) / 8); - var strIdx = 0; - for (i = 0; i < length; i++) { - while (codeSize < bps) { - codeBuf <<= 8; - codeBuf |= strBytes[strIdx++]; - codeSize += 8; - } - codeSize -= bps; - array[i] = (codeBuf >> codeSize) * sampleMul; - codeBuf &= (1 << codeSize) - 1; - } - return array; - }, - - getIR: function PDFFunction_getIR(xref, fn) { - var dict = fn.dict; - if (!dict) { - dict = fn; - } - - var types = [this.constructSampled, - null, - this.constructInterpolated, - this.constructStiched, - this.constructPostScript]; - - var typeNum = dict.get('FunctionType'); - var typeFn = types[typeNum]; - if (!typeFn) { - error('Unknown type of function'); - } - - return typeFn.call(this, fn, dict, xref); - }, - - fromIR: function PDFFunction_fromIR(IR) { - var type = IR[0]; - switch (type) { - case CONSTRUCT_SAMPLED: - return this.constructSampledFromIR(IR); - case CONSTRUCT_INTERPOLATED: - return this.constructInterpolatedFromIR(IR); - case CONSTRUCT_STICHED: - return this.constructStichedFromIR(IR); - //case CONSTRUCT_POSTSCRIPT: - default: - return this.constructPostScriptFromIR(IR); - } - }, - - parse: function PDFFunction_parse(xref, fn) { - var IR = this.getIR(xref, fn); - return this.fromIR(IR); - }, - - parseArray: function PDFFunction_parseArray(xref, fnObj) { - if (!isArray(fnObj)) { - // not an array -- parsing as regular function - return this.parse(xref, fnObj); - } - - var fnArray = []; - for (var j = 0, jj = fnObj.length; j < jj; j++) { - var obj = xref.fetchIfRef(fnObj[j]); - fnArray.push(PDFFunction.parse(xref, obj)); - } - return function (src, srcOffset, dest, destOffset) { - for (var i = 0, ii = fnArray.length; i < ii; i++) { - fnArray[i](src, srcOffset, dest, destOffset + i); - } - }; - }, - - constructSampled: function PDFFunction_constructSampled(str, dict) { - function toMultiArray(arr) { - var inputLength = arr.length; - var out = []; - var index = 0; - for (var i = 0; i < inputLength; i += 2) { - out[index] = [arr[i], arr[i + 1]]; - ++index; - } - return out; - } - var domain = dict.get('Domain'); - var range = dict.get('Range'); - - if (!domain || !range) { - error('No domain or range'); - } - - var inputSize = domain.length / 2; - var outputSize = range.length / 2; - - domain = toMultiArray(domain); - range = toMultiArray(range); - - var size = dict.get('Size'); - var bps = dict.get('BitsPerSample'); - var order = dict.get('Order') || 1; - if (order !== 1) { - // No description how cubic spline interpolation works in PDF32000:2008 - // As in poppler, ignoring order, linear interpolation may work as good - info('No support for cubic spline interpolation: ' + order); - } - - var encode = dict.get('Encode'); - if (!encode) { - encode = []; - for (var i = 0; i < inputSize; ++i) { - encode.push(0); - encode.push(size[i] - 1); - } - } - encode = toMultiArray(encode); - - var decode = dict.get('Decode'); - if (!decode) { - decode = range; - } else { - decode = toMultiArray(decode); - } - - var samples = this.getSampleArray(size, outputSize, bps, str); - - return [ - CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size, - outputSize, Math.pow(2, bps) - 1, range - ]; - }, - - constructSampledFromIR: function PDFFunction_constructSampledFromIR(IR) { - // See chapter 3, page 109 of the PDF reference - function interpolate(x, xmin, xmax, ymin, ymax) { - return ymin + ((x - xmin) * ((ymax - ymin) / (xmax - xmin))); - } - - return function constructSampledFromIRResult(src, srcOffset, - dest, destOffset) { - // See chapter 3, page 110 of the PDF reference. - var m = IR[1]; - var domain = IR[2]; - var encode = IR[3]; - var decode = IR[4]; - var samples = IR[5]; - var size = IR[6]; - var n = IR[7]; - //var mask = IR[8]; - var range = IR[9]; - - // Building the cube vertices: its part and sample index - // http://rjwagner49.com/Mathematics/Interpolation.pdf - var cubeVertices = 1 << m; - var cubeN = new Float64Array(cubeVertices); - var cubeVertex = new Uint32Array(cubeVertices); - var i, j; - for (j = 0; j < cubeVertices; j++) { - cubeN[j] = 1; - } - - var k = n, pos = 1; - // Map x_i to y_j for 0 <= i < m using the sampled function. - for (i = 0; i < m; ++i) { - // x_i' = min(max(x_i, Domain_2i), Domain_2i+1) - var domain_2i = domain[i][0]; - var domain_2i_1 = domain[i][1]; - var xi = Math.min(Math.max(src[srcOffset +i], domain_2i), - domain_2i_1); - - // e_i = Interpolate(x_i', Domain_2i, Domain_2i+1, - // Encode_2i, Encode_2i+1) - var e = interpolate(xi, domain_2i, domain_2i_1, - encode[i][0], encode[i][1]); - - // e_i' = min(max(e_i, 0), Size_i - 1) - var size_i = size[i]; - e = Math.min(Math.max(e, 0), size_i - 1); - - // Adjusting the cube: N and vertex sample index - var e0 = e < size_i - 1 ? Math.floor(e) : e - 1; // e1 = e0 + 1; - var n0 = e0 + 1 - e; // (e1 - e) / (e1 - e0); - var n1 = e - e0; // (e - e0) / (e1 - e0); - var offset0 = e0 * k; - var offset1 = offset0 + k; // e1 * k - for (j = 0; j < cubeVertices; j++) { - if (j & pos) { - cubeN[j] *= n1; - cubeVertex[j] += offset1; - } else { - cubeN[j] *= n0; - cubeVertex[j] += offset0; - } - } - - k *= size_i; - pos <<= 1; - } - - for (j = 0; j < n; ++j) { - // Sum all cube vertices' samples portions - var rj = 0; - for (i = 0; i < cubeVertices; i++) { - rj += samples[cubeVertex[i] + j] * cubeN[i]; - } - - // r_j' = Interpolate(r_j, 0, 2^BitsPerSample - 1, - // Decode_2j, Decode_2j+1) - rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); - - // y_j = min(max(r_j, range_2j), range_2j+1) - dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), - range[j][1]); - } - }; - }, - - constructInterpolated: function PDFFunction_constructInterpolated(str, - dict) { - var c0 = dict.get('C0') || [0]; - var c1 = dict.get('C1') || [1]; - var n = dict.get('N'); - - if (!isArray(c0) || !isArray(c1)) { - error('Illegal dictionary for interpolated function'); - } - - var length = c0.length; - var diff = []; - for (var i = 0; i < length; ++i) { - diff.push(c1[i] - c0[i]); - } - - return [CONSTRUCT_INTERPOLATED, c0, diff, n]; - }, - - constructInterpolatedFromIR: - function PDFFunction_constructInterpolatedFromIR(IR) { - var c0 = IR[1]; - var diff = IR[2]; - var n = IR[3]; - - var length = diff.length; - - return function constructInterpolatedFromIRResult(src, srcOffset, - dest, destOffset) { - var x = n === 1 ? src[srcOffset] : Math.pow(src[srcOffset], n); - - for (var j = 0; j < length; ++j) { - dest[destOffset + j] = c0[j] + (x * diff[j]); - } - }; - }, - - constructStiched: function PDFFunction_constructStiched(fn, dict, xref) { - var domain = dict.get('Domain'); - - if (!domain) { - error('No domain'); - } - - var inputSize = domain.length / 2; - if (inputSize !== 1) { - error('Bad domain for stiched function'); - } - - var fnRefs = dict.get('Functions'); - var fns = []; - for (var i = 0, ii = fnRefs.length; i < ii; ++i) { - fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i]))); - } - - var bounds = dict.get('Bounds'); - var encode = dict.get('Encode'); - - return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; - }, - - constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) { - var domain = IR[1]; - var bounds = IR[2]; - var encode = IR[3]; - var fnsIR = IR[4]; - var fns = []; - var tmpBuf = new Float32Array(1); - - for (var i = 0, ii = fnsIR.length; i < ii; i++) { - fns.push(PDFFunction.fromIR(fnsIR[i])); - } - - return function constructStichedFromIRResult(src, srcOffset, - dest, destOffset) { - var clip = function constructStichedFromIRClip(v, min, max) { - if (v > max) { - v = max; - } else if (v < min) { - v = min; - } - return v; - }; - - // clip to domain - var v = clip(src[srcOffset], domain[0], domain[1]); - // calulate which bound the value is in - for (var i = 0, ii = bounds.length; i < ii; ++i) { - if (v < bounds[i]) { - break; - } - } - - // encode value into domain of function - var dmin = domain[0]; - if (i > 0) { - dmin = bounds[i - 1]; - } - var dmax = domain[1]; - if (i < bounds.length) { - dmax = bounds[i]; - } - - var rmin = encode[2 * i]; - var rmax = encode[2 * i + 1]; - - tmpBuf[0] = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); - - // call the appropriate function - fns[i](tmpBuf, 0, dest, destOffset); - }; - }, - - constructPostScript: function PDFFunction_constructPostScript(fn, dict, - xref) { - var domain = dict.get('Domain'); - var range = dict.get('Range'); - - if (!domain) { - error('No domain.'); - } - - if (!range) { - error('No range.'); - } - - var lexer = new PostScriptLexer(fn); - var parser = new PostScriptParser(lexer); - var code = parser.parse(); - - return [CONSTRUCT_POSTSCRIPT, domain, range, code]; - }, - - constructPostScriptFromIR: function PDFFunction_constructPostScriptFromIR( - IR) { - var domain = IR[1]; - var range = IR[2]; - var code = IR[3]; - - var compiled = (new PostScriptCompiler()).compile(code, domain, range); - if (compiled) { - // Compiled function consists of simple expressions such as addition, - // subtraction, Math.max, and also contains 'var' and 'return' - // statements. See the generation in the PostScriptCompiler below. - /*jshint -W054 */ - return new Function('src', 'srcOffset', 'dest', 'destOffset', compiled); - } - - info('Unable to compile PS function'); - - var numOutputs = range.length >> 1; - var numInputs = domain.length >> 1; - var evaluator = new PostScriptEvaluator(code); - // Cache the values for a big speed up, the cache size is limited though - // since the number of possible values can be huge from a PS function. - var cache = {}; - // The MAX_CACHE_SIZE is set to ~4x the maximum number of distinct values - // seen in our tests. - var MAX_CACHE_SIZE = 2048 * 4; - var cache_available = MAX_CACHE_SIZE; - var tmpBuf = new Float32Array(numInputs); - - return function constructPostScriptFromIRResult(src, srcOffset, - dest, destOffset) { - var i, value; - var key = ''; - var input = tmpBuf; - for (i = 0; i < numInputs; i++) { - value = src[srcOffset + i]; - input[i] = value; - key += value + '_'; - } - - var cachedValue = cache[key]; - if (cachedValue !== undefined) { - dest.set(cachedValue, destOffset); - return; - } - - var output = new Float32Array(numOutputs); - var stack = evaluator.execute(input); - var stackIndex = stack.length - numOutputs; - for (i = 0; i < numOutputs; i++) { - value = stack[stackIndex + i]; - var bound = range[i * 2]; - if (value < bound) { - value = bound; - } else { - bound = range[i * 2 +1]; - if (value > bound) { - value = bound; - } - } - output[i] = value; - } - if (cache_available > 0) { - cache_available--; - cache[key] = output; - } - dest.set(output, destOffset); - }; - } - }; -})(); - -function isPDFFunction(v) { - var fnDict; - if (typeof v !== 'object') { - return false; - } else if (isDict(v)) { - fnDict = v; - } else if (isStream(v)) { - fnDict = v.dict; - } else { - return false; - } - return fnDict.has('FunctionType'); -} - -var PostScriptStack = (function PostScriptStackClosure() { - var MAX_STACK_SIZE = 100; - function PostScriptStack(initialStack) { - this.stack = !initialStack ? [] : - Array.prototype.slice.call(initialStack, 0); - } - - PostScriptStack.prototype = { - push: function PostScriptStack_push(value) { - if (this.stack.length >= MAX_STACK_SIZE) { - error('PostScript function stack overflow.'); - } - this.stack.push(value); - }, - pop: function PostScriptStack_pop() { - if (this.stack.length <= 0) { - error('PostScript function stack underflow.'); - } - return this.stack.pop(); - }, - copy: function PostScriptStack_copy(n) { - if (this.stack.length + n >= MAX_STACK_SIZE) { - error('PostScript function stack overflow.'); - } - var stack = this.stack; - for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) { - stack.push(stack[i]); - } - }, - index: function PostScriptStack_index(n) { - this.push(this.stack[this.stack.length - n - 1]); - }, - // rotate the last n stack elements p times - roll: function PostScriptStack_roll(n, p) { - var stack = this.stack; - var l = stack.length - n; - var r = stack.length - 1, c = l + (p - Math.floor(p / n) * n), i, j, t; - for (i = l, j = r; i < j; i++, j--) { - t = stack[i]; stack[i] = stack[j]; stack[j] = t; - } - for (i = l, j = c - 1; i < j; i++, j--) { - t = stack[i]; stack[i] = stack[j]; stack[j] = t; - } - for (i = c, j = r; i < j; i++, j--) { - t = stack[i]; stack[i] = stack[j]; stack[j] = t; - } - } - }; - return PostScriptStack; -})(); -var PostScriptEvaluator = (function PostScriptEvaluatorClosure() { - function PostScriptEvaluator(operators) { - this.operators = operators; - } - PostScriptEvaluator.prototype = { - execute: function PostScriptEvaluator_execute(initialStack) { - var stack = new PostScriptStack(initialStack); - var counter = 0; - var operators = this.operators; - var length = operators.length; - var operator, a, b; - while (counter < length) { - operator = operators[counter++]; - if (typeof operator === 'number') { - // Operator is really an operand and should be pushed to the stack. - stack.push(operator); - continue; - } - switch (operator) { - // non standard ps operators - case 'jz': // jump if false - b = stack.pop(); - a = stack.pop(); - if (!a) { - counter = b; - } - break; - case 'j': // jump - a = stack.pop(); - counter = a; - break; - - // all ps operators in alphabetical order (excluding if/ifelse) - case 'abs': - a = stack.pop(); - stack.push(Math.abs(a)); - break; - case 'add': - b = stack.pop(); - a = stack.pop(); - stack.push(a + b); - break; - case 'and': - b = stack.pop(); - a = stack.pop(); - if (isBool(a) && isBool(b)) { - stack.push(a && b); - } else { - stack.push(a & b); - } - break; - case 'atan': - a = stack.pop(); - stack.push(Math.atan(a)); - break; - case 'bitshift': - b = stack.pop(); - a = stack.pop(); - if (a > 0) { - stack.push(a << b); - } else { - stack.push(a >> b); - } - break; - case 'ceiling': - a = stack.pop(); - stack.push(Math.ceil(a)); - break; - case 'copy': - a = stack.pop(); - stack.copy(a); - break; - case 'cos': - a = stack.pop(); - stack.push(Math.cos(a)); - break; - case 'cvi': - a = stack.pop() | 0; - stack.push(a); - break; - case 'cvr': - // noop - break; - case 'div': - b = stack.pop(); - a = stack.pop(); - stack.push(a / b); - break; - case 'dup': - stack.copy(1); - break; - case 'eq': - b = stack.pop(); - a = stack.pop(); - stack.push(a === b); - break; - case 'exch': - stack.roll(2, 1); - break; - case 'exp': - b = stack.pop(); - a = stack.pop(); - stack.push(Math.pow(a, b)); - break; - case 'false': - stack.push(false); - break; - case 'floor': - a = stack.pop(); - stack.push(Math.floor(a)); - break; - case 'ge': - b = stack.pop(); - a = stack.pop(); - stack.push(a >= b); - break; - case 'gt': - b = stack.pop(); - a = stack.pop(); - stack.push(a > b); - break; - case 'idiv': - b = stack.pop(); - a = stack.pop(); - stack.push((a / b) | 0); - break; - case 'index': - a = stack.pop(); - stack.index(a); - break; - case 'le': - b = stack.pop(); - a = stack.pop(); - stack.push(a <= b); - break; - case 'ln': - a = stack.pop(); - stack.push(Math.log(a)); - break; - case 'log': - a = stack.pop(); - stack.push(Math.log(a) / Math.LN10); - break; - case 'lt': - b = stack.pop(); - a = stack.pop(); - stack.push(a < b); - break; - case 'mod': - b = stack.pop(); - a = stack.pop(); - stack.push(a % b); - break; - case 'mul': - b = stack.pop(); - a = stack.pop(); - stack.push(a * b); - break; - case 'ne': - b = stack.pop(); - a = stack.pop(); - stack.push(a !== b); - break; - case 'neg': - a = stack.pop(); - stack.push(-a); - break; - case 'not': - a = stack.pop(); - if (isBool(a)) { - stack.push(!a); - } else { - stack.push(~a); - } - break; - case 'or': - b = stack.pop(); - a = stack.pop(); - if (isBool(a) && isBool(b)) { - stack.push(a || b); - } else { - stack.push(a | b); - } - break; - case 'pop': - stack.pop(); - break; - case 'roll': - b = stack.pop(); - a = stack.pop(); - stack.roll(a, b); - break; - case 'round': - a = stack.pop(); - stack.push(Math.round(a)); - break; - case 'sin': - a = stack.pop(); - stack.push(Math.sin(a)); - break; - case 'sqrt': - a = stack.pop(); - stack.push(Math.sqrt(a)); - break; - case 'sub': - b = stack.pop(); - a = stack.pop(); - stack.push(a - b); - break; - case 'true': - stack.push(true); - break; - case 'truncate': - a = stack.pop(); - a = a < 0 ? Math.ceil(a) : Math.floor(a); - stack.push(a); - break; - case 'xor': - b = stack.pop(); - a = stack.pop(); - if (isBool(a) && isBool(b)) { - stack.push(a !== b); - } else { - stack.push(a ^ b); - } - break; - default: - error('Unknown operator ' + operator); - break; - } - } - return stack.stack; - } - }; - return PostScriptEvaluator; -})(); - -// Most of the PDFs functions consist of simple operations such as: -// roll, exch, sub, cvr, pop, index, dup, mul, if, gt, add. -// -// We can compile most of such programs, and at the same moment, we can -// optimize some expressions using basic math properties. Keeping track of -// min/max values will allow us to avoid extra Math.min/Math.max calls. -var PostScriptCompiler = (function PostScriptCompilerClosure() { - function AstNode(type) { - this.type = type; - } - AstNode.prototype.visit = function (visitor) { - throw new Error('abstract method'); - }; - - function AstArgument(index, min, max) { - AstNode.call(this, 'args'); - this.index = index; - this.min = min; - this.max = max; - } - AstArgument.prototype = Object.create(AstNode.prototype); - AstArgument.prototype.visit = function (visitor) { - visitor.visitArgument(this); - }; - - function AstLiteral(number) { - AstNode.call(this, 'literal'); - this.number = number; - this.min = number; - this.max = number; - } - AstLiteral.prototype = Object.create(AstNode.prototype); - AstLiteral.prototype.visit = function (visitor) { - visitor.visitLiteral(this); - }; - - function AstBinaryOperation(op, arg1, arg2, min, max) { - AstNode.call(this, 'binary'); - this.op = op; - this.arg1 = arg1; - this.arg2 = arg2; - this.min = min; - this.max = max; - } - AstBinaryOperation.prototype = Object.create(AstNode.prototype); - AstBinaryOperation.prototype.visit = function (visitor) { - visitor.visitBinaryOperation(this); - }; - - function AstMin(arg, max) { - AstNode.call(this, 'max'); - this.arg = arg; - this.min = arg.min; - this.max = max; - } - AstMin.prototype = Object.create(AstNode.prototype); - AstMin.prototype.visit = function (visitor) { - visitor.visitMin(this); - }; - - function AstVariable(index, min, max) { - AstNode.call(this, 'var'); - this.index = index; - this.min = min; - this.max = max; - } - AstVariable.prototype = Object.create(AstNode.prototype); - AstVariable.prototype.visit = function (visitor) { - visitor.visitVariable(this); - }; - - function AstVariableDefinition(variable, arg) { - AstNode.call(this, 'definition'); - this.variable = variable; - this.arg = arg; - } - AstVariableDefinition.prototype = Object.create(AstNode.prototype); - AstVariableDefinition.prototype.visit = function (visitor) { - visitor.visitVariableDefinition(this); - }; - - function ExpressionBuilderVisitor() { - this.parts = []; - } - ExpressionBuilderVisitor.prototype = { - visitArgument: function (arg) { - this.parts.push('Math.max(', arg.min, ', Math.min(', - arg.max, ', src[srcOffset + ', arg.index, ']))'); - }, - visitVariable: function (variable) { - this.parts.push('v', variable.index); - }, - visitLiteral: function (literal) { - this.parts.push(literal.number); - }, - visitBinaryOperation: function (operation) { - this.parts.push('('); - operation.arg1.visit(this); - this.parts.push(' ', operation.op, ' '); - operation.arg2.visit(this); - this.parts.push(')'); - }, - visitVariableDefinition: function (definition) { - this.parts.push('var '); - definition.variable.visit(this); - this.parts.push(' = '); - definition.arg.visit(this); - this.parts.push(';'); - }, - visitMin: function (max) { - this.parts.push('Math.min('); - max.arg.visit(this); - this.parts.push(', ', max.max, ')'); - }, - toString: function () { - return this.parts.join(''); - } - }; - - function buildAddOperation(num1, num2) { - if (num2.type === 'literal' && num2.number === 0) { - // optimization: second operand is 0 - return num1; - } - if (num1.type === 'literal' && num1.number === 0) { - // optimization: first operand is 0 - return num2; - } - if (num2.type === 'literal' && num1.type === 'literal') { - // optimization: operands operand are literals - return new AstLiteral(num1.number + num2.number); - } - return new AstBinaryOperation('+', num1, num2, - num1.min + num2.min, num1.max + num2.max); - } - - function buildMulOperation(num1, num2) { - if (num2.type === 'literal') { - // optimization: second operands is a literal... - if (num2.number === 0) { - return new AstLiteral(0); // and it's 0 - } else if (num2.number === 1) { - return num1; // and it's 1 - } else if (num1.type === 'literal') { - // ... and first operands is a literal too - return new AstLiteral(num1.number * num2.number); - } - } - if (num1.type === 'literal') { - // optimization: first operands is a literal... - if (num1.number === 0) { - return new AstLiteral(0); // and it's 0 - } else if (num1.number === 1) { - return num2; // and it's 1 - } - } - var min = Math.min(num1.min * num2.min, num1.min * num2.max, - num1.max * num2.min, num1.max * num2.max); - var max = Math.max(num1.min * num2.min, num1.min * num2.max, - num1.max * num2.min, num1.max * num2.max); - return new AstBinaryOperation('*', num1, num2, min, max); - } - - function buildSubOperation(num1, num2) { - if (num2.type === 'literal') { - // optimization: second operands is a literal... - if (num2.number === 0) { - return num1; // ... and it's 0 - } else if (num1.type === 'literal') { - // ... and first operands is a literal too - return new AstLiteral(num1.number - num2.number); - } - } - if (num2.type === 'binary' && num2.op === '-' && - num1.type === 'literal' && num1.number === 1 && - num2.arg1.type === 'literal' && num2.arg1.number === 1) { - // optimization for case: 1 - (1 - x) - return num2.arg2; - } - return new AstBinaryOperation('-', num1, num2, - num1.min - num2.max, num1.max - num2.min); - } - - function buildMinOperation(num1, max) { - if (num1.min >= max) { - // optimization: num1 min value is not less than required max - return new AstLiteral(max); // just returning max - } else if (num1.max <= max) { - // optimization: num1 max value is not greater than required max - return num1; // just returning an argument - } - return new AstMin(num1, max); - } - - function PostScriptCompiler() {} - PostScriptCompiler.prototype = { - compile: function PostScriptCompiler_compile(code, domain, range) { - var stack = []; - var i, ii; - var instructions = []; - var inputSize = domain.length >> 1, outputSize = range.length >> 1; - var lastRegister = 0; - var n, j, min, max; - var num1, num2, ast1, ast2, tmpVar, item; - for (i = 0; i < inputSize; i++) { - stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1])); - } - - for (i = 0, ii = code.length; i < ii; i++) { - item = code[i]; - if (typeof item === 'number') { - stack.push(new AstLiteral(item)); - continue; - } - - switch (item) { - case 'add': - if (stack.length < 2) { - return null; - } - num2 = stack.pop(); - num1 = stack.pop(); - stack.push(buildAddOperation(num1, num2)); - break; - case 'cvr': - if (stack.length < 1) { - return null; - } - break; - case 'mul': - if (stack.length < 2) { - return null; - } - num2 = stack.pop(); - num1 = stack.pop(); - stack.push(buildMulOperation(num1, num2)); - break; - case 'sub': - if (stack.length < 2) { - return null; - } - num2 = stack.pop(); - num1 = stack.pop(); - stack.push(buildSubOperation(num1, num2)); - break; - case 'exch': - if (stack.length < 2) { - return null; - } - ast1 = stack.pop(); ast2 = stack.pop(); - stack.push(ast1, ast2); - break; - case 'pop': - if (stack.length < 1) { - return null; - } - stack.pop(); - break; - case 'index': - if (stack.length < 1) { - return null; - } - num1 = stack.pop(); - if (num1.type !== 'literal') { - return null; - } - n = num1.number; - if (n < 0 || (n|0) !== n || stack.length < n) { - return null; - } - ast1 = stack[stack.length - n - 1]; - if (ast1.type === 'literal' || ast1.type === 'var') { - stack.push(ast1); - break; - } - tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max); - stack[stack.length - n - 1] = tmpVar; - stack.push(tmpVar); - instructions.push(new AstVariableDefinition(tmpVar, ast1)); - break; - case 'dup': - if (stack.length < 1) { - return null; - } - if (typeof code[i + 1] === 'number' && code[i + 2] === 'gt' && - code[i + 3] === i + 7 && code[i + 4] === 'jz' && - code[i + 5] === 'pop' && code[i + 6] === code[i + 1]) { - // special case of the commands sequence for the min operation - num1 = stack.pop(); - stack.push(buildMinOperation(num1, code[i + 1])); - i += 6; - break; - } - ast1 = stack[stack.length - 1]; - if (ast1.type === 'literal' || ast1.type === 'var') { - // we don't have to save into intermediate variable a literal or - // variable. - stack.push(ast1); - break; - } - tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max); - stack[stack.length - 1] = tmpVar; - stack.push(tmpVar); - instructions.push(new AstVariableDefinition(tmpVar, ast1)); - break; - case 'roll': - if (stack.length < 2) { - return null; - } - num2 = stack.pop(); - num1 = stack.pop(); - if (num2.type !== 'literal' || num1.type !== 'literal') { - // both roll operands must be numbers - return null; - } - j = num2.number; - n = num1.number; - if (n <= 0 || (n|0) !== n || (j|0) !== j || stack.length < n) { - // ... and integers - return null; - } - j = ((j % n) + n) % n; - if (j === 0) { - break; // just skipping -- there are nothing to rotate - } - Array.prototype.push.apply(stack, - stack.splice(stack.length - n, n - j)); - break; - default: - return null; // unsupported operator - } - } - - if (stack.length !== outputSize) { - return null; - } - - var result = []; - instructions.forEach(function (instruction) { - var statementBuilder = new ExpressionBuilderVisitor(); - instruction.visit(statementBuilder); - result.push(statementBuilder.toString()); - }); - stack.forEach(function (expr, i) { - var statementBuilder = new ExpressionBuilderVisitor(); - expr.visit(statementBuilder); - var min = range[i * 2], max = range[i * 2 + 1]; - var out = [statementBuilder.toString()]; - if (min > expr.min) { - out.unshift('Math.max(', min, ', '); - out.push(')'); - } - if (max < expr.max) { - out.unshift('Math.min(', max, ', '); - out.push(')'); - } - out.unshift('dest[destOffset + ', i, '] = '); - out.push(';'); - result.push(out.join('')); - }); - return result.join('\n'); - } - }; - - return PostScriptCompiler; -})(); - - -var ColorSpace = (function ColorSpaceClosure() { - // Constructor should define this.numComps, this.defaultColor, this.name - function ColorSpace() { - error('should not call ColorSpace constructor'); - } - - ColorSpace.prototype = { - /** - * Converts the color value to the RGB color. The color components are - * located in the src array starting from the srcOffset. Returns the array - * of the rgb components, each value ranging from [0,255]. - */ - getRgb: function ColorSpace_getRgb(src, srcOffset) { - var rgb = new Uint8Array(3); - this.getRgbItem(src, srcOffset, rgb, 0); - return rgb; - }, - /** - * Converts the color value to the RGB color, similar to the getRgb method. - * The result placed into the dest array starting from the destOffset. - */ - getRgbItem: function ColorSpace_getRgbItem(src, srcOffset, - dest, destOffset) { - error('Should not call ColorSpace.getRgbItem'); - }, - /** - * Converts the specified number of the color values to the RGB colors. - * The colors are located in the src array starting from the srcOffset. - * The result is placed into the dest array starting from the destOffset. - * The src array items shall be in [0,2^bits) range, the dest array items - * will be in [0,255] range. alpha01 indicates how many alpha components - * there are in the dest array; it will be either 0 (RGB array) or 1 (RGBA - * array). - */ - getRgbBuffer: function ColorSpace_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - error('Should not call ColorSpace.getRgbBuffer'); - }, - /** - * Determines the number of bytes required to store the result of the - * conversion done by the getRgbBuffer method. As in getRgbBuffer, - * |alpha01| is either 0 (RGB output) or 1 (RGBA output). - */ - getOutputLength: function ColorSpace_getOutputLength(inputLength, - alpha01) { - error('Should not call ColorSpace.getOutputLength'); - }, - /** - * Returns true if source data will be equal the result/output data. - */ - isPassthrough: function ColorSpace_isPassthrough(bits) { - return false; - }, - /** - * Fills in the RGB colors in the destination buffer. alpha01 indicates - * how many alpha components there are in the dest array; it will be either - * 0 (RGB array) or 1 (RGBA array). - */ - fillRgb: function ColorSpace_fillRgb(dest, originalWidth, - originalHeight, width, height, - actualHeight, bpc, comps, alpha01) { - var count = originalWidth * originalHeight; - var rgbBuf = null; - var numComponentColors = 1 << bpc; - var needsResizing = originalHeight !== height || originalWidth !== width; - var i, ii; - - if (this.isPassthrough(bpc)) { - rgbBuf = comps; - } else if (this.numComps === 1 && count > numComponentColors && - this.name !== 'DeviceGray' && this.name !== 'DeviceRGB') { - // Optimization: create a color map when there is just one component and - // we are converting more colors than the size of the color map. We - // don't build the map if the colorspace is gray or rgb since those - // methods are faster than building a map. This mainly offers big speed - // ups for indexed and alternate colorspaces. - // - // TODO it may be worth while to cache the color map. While running - // testing I never hit a cache so I will leave that out for now (perhaps - // we are reparsing colorspaces too much?). - var allColors = bpc <= 8 ? new Uint8Array(numComponentColors) : - new Uint16Array(numComponentColors); - var key; - for (i = 0; i < numComponentColors; i++) { - allColors[i] = i; - } - var colorMap = new Uint8Array(numComponentColors * 3); - this.getRgbBuffer(allColors, 0, numComponentColors, colorMap, 0, bpc, - /* alpha01 = */ 0); - - var destPos, rgbPos; - if (!needsResizing) { - // Fill in the RGB values directly into |dest|. - destPos = 0; - for (i = 0; i < count; ++i) { - key = comps[i] * 3; - dest[destPos++] = colorMap[key]; - dest[destPos++] = colorMap[key + 1]; - dest[destPos++] = colorMap[key + 2]; - destPos += alpha01; - } - } else { - rgbBuf = new Uint8Array(count * 3); - rgbPos = 0; - for (i = 0; i < count; ++i) { - key = comps[i] * 3; - rgbBuf[rgbPos++] = colorMap[key]; - rgbBuf[rgbPos++] = colorMap[key + 1]; - rgbBuf[rgbPos++] = colorMap[key + 2]; - } - } - } else { - if (!needsResizing) { - // Fill in the RGB values directly into |dest|. - this.getRgbBuffer(comps, 0, width * actualHeight, dest, 0, bpc, - alpha01); - } else { - rgbBuf = new Uint8Array(count * 3); - this.getRgbBuffer(comps, 0, count, rgbBuf, 0, bpc, - /* alpha01 = */ 0); - } - } - - if (rgbBuf) { - if (needsResizing) { - PDFImage.resize(rgbBuf, bpc, 3, originalWidth, originalHeight, width, - height, dest, alpha01); - } else { - rgbPos = 0; - destPos = 0; - for (i = 0, ii = width * actualHeight; i < ii; i++) { - dest[destPos++] = rgbBuf[rgbPos++]; - dest[destPos++] = rgbBuf[rgbPos++]; - dest[destPos++] = rgbBuf[rgbPos++]; - destPos += alpha01; - } - } - } - }, - /** - * True if the colorspace has components in the default range of [0, 1]. - * This should be true for all colorspaces except for lab color spaces - * which are [0,100], [-128, 127], [-128, 127]. - */ - usesZeroToOneRange: true - }; - - ColorSpace.parse = function ColorSpace_parse(cs, xref, res) { - var IR = ColorSpace.parseToIR(cs, xref, res); - if (IR instanceof AlternateCS) { - return IR; - } - return ColorSpace.fromIR(IR); - }; - - ColorSpace.fromIR = function ColorSpace_fromIR(IR) { - var name = isArray(IR) ? IR[0] : IR; - var whitePoint, blackPoint, gamma; - - switch (name) { - case 'DeviceGrayCS': - return this.singletons.gray; - case 'DeviceRgbCS': - return this.singletons.rgb; - case 'DeviceCmykCS': - return this.singletons.cmyk; - case 'CalGrayCS': - whitePoint = IR[1].WhitePoint; - blackPoint = IR[1].BlackPoint; - gamma = IR[1].Gamma; - return new CalGrayCS(whitePoint, blackPoint, gamma); - case 'CalRGBCS': - whitePoint = IR[1].WhitePoint; - blackPoint = IR[1].BlackPoint; - gamma = IR[1].Gamma; - var matrix = IR[1].Matrix; - return new CalRGBCS(whitePoint, blackPoint, gamma, matrix); - case 'PatternCS': - var basePatternCS = IR[1]; - if (basePatternCS) { - basePatternCS = ColorSpace.fromIR(basePatternCS); - } - return new PatternCS(basePatternCS); - case 'IndexedCS': - var baseIndexedCS = IR[1]; - var hiVal = IR[2]; - var lookup = IR[3]; - return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup); - case 'AlternateCS': - var numComps = IR[1]; - var alt = IR[2]; - var tintFnIR = IR[3]; - - return new AlternateCS(numComps, ColorSpace.fromIR(alt), - PDFFunction.fromIR(tintFnIR)); - case 'LabCS': - whitePoint = IR[1].WhitePoint; - blackPoint = IR[1].BlackPoint; - var range = IR[1].Range; - return new LabCS(whitePoint, blackPoint, range); - default: - error('Unknown name ' + name); - } - return null; - }; - - ColorSpace.parseToIR = function ColorSpace_parseToIR(cs, xref, res) { - if (isName(cs)) { - var colorSpaces = res.get('ColorSpace'); - if (isDict(colorSpaces)) { - var refcs = colorSpaces.get(cs.name); - if (refcs) { - cs = refcs; - } - } - } - - cs = xref.fetchIfRef(cs); - var mode; - - if (isName(cs)) { - mode = cs.name; - this.mode = mode; - - switch (mode) { - case 'DeviceGray': - case 'G': - return 'DeviceGrayCS'; - case 'DeviceRGB': - case 'RGB': - return 'DeviceRgbCS'; - case 'DeviceCMYK': - case 'CMYK': - return 'DeviceCmykCS'; - case 'Pattern': - return ['PatternCS', null]; - default: - error('unrecognized colorspace ' + mode); - } - } else if (isArray(cs)) { - mode = cs[0].name; - this.mode = mode; - var numComps, params; - - switch (mode) { - case 'DeviceGray': - case 'G': - return 'DeviceGrayCS'; - case 'DeviceRGB': - case 'RGB': - return 'DeviceRgbCS'; - case 'DeviceCMYK': - case 'CMYK': - return 'DeviceCmykCS'; - case 'CalGray': - params = xref.fetchIfRef(cs[1]).getAll(); - return ['CalGrayCS', params]; - case 'CalRGB': - params = xref.fetchIfRef(cs[1]).getAll(); - return ['CalRGBCS', params]; - case 'ICCBased': - var stream = xref.fetchIfRef(cs[1]); - var dict = stream.dict; - numComps = dict.get('N'); - if (numComps === 1) { - return 'DeviceGrayCS'; - } else if (numComps === 3) { - return 'DeviceRgbCS'; - } else if (numComps === 4) { - return 'DeviceCmykCS'; - } - break; - case 'Pattern': - var basePatternCS = cs[1]; - if (basePatternCS) { - basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res); - } - return ['PatternCS', basePatternCS]; - case 'Indexed': - case 'I': - var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res); - var hiVal = cs[2] + 1; - var lookup = xref.fetchIfRef(cs[3]); - if (isStream(lookup)) { - lookup = lookup.getBytes(); - } - return ['IndexedCS', baseIndexedCS, hiVal, lookup]; - case 'Separation': - case 'DeviceN': - var name = cs[1]; - numComps = 1; - if (isName(name)) { - numComps = 1; - } else if (isArray(name)) { - numComps = name.length; - } - var alt = ColorSpace.parseToIR(cs[2], xref, res); - var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3])); - return ['AlternateCS', numComps, alt, tintFnIR]; - case 'Lab': - params = cs[1].getAll(); - return ['LabCS', params]; - default: - error('unimplemented color space object "' + mode + '"'); - } - } else { - error('unrecognized color space object: "' + cs + '"'); - } - return null; - }; - /** - * Checks if a decode map matches the default decode map for a color space. - * This handles the general decode maps where there are two values per - * component. e.g. [0, 1, 0, 1, 0, 1] for a RGB color. - * This does not handle Lab, Indexed, or Pattern decode maps since they are - * slightly different. - * @param {Array} decode Decode map (usually from an image). - * @param {Number} n Number of components the color space has. - */ - ColorSpace.isDefaultDecode = function ColorSpace_isDefaultDecode(decode, n) { - if (!decode) { - return true; - } - - if (n * 2 !== decode.length) { - warn('The decode map is not the correct length'); - return true; - } - for (var i = 0, ii = decode.length; i < ii; i += 2) { - if (decode[i] !== 0 || decode[i + 1] !== 1) { - return false; - } - } - return true; - }; - - ColorSpace.singletons = { - get gray() { - return shadow(this, 'gray', new DeviceGrayCS()); - }, - get rgb() { - return shadow(this, 'rgb', new DeviceRgbCS()); - }, - get cmyk() { - return shadow(this, 'cmyk', new DeviceCmykCS()); - } - }; - - return ColorSpace; -})(); - -/** - * Alternate color space handles both Separation and DeviceN color spaces. A - * Separation color space is actually just a DeviceN with one color component. - * Both color spaces use a tinting function to convert colors to a base color - * space. - */ -var AlternateCS = (function AlternateCSClosure() { - function AlternateCS(numComps, base, tintFn) { - this.name = 'Alternate'; - this.numComps = numComps; - this.defaultColor = new Float32Array(numComps); - for (var i = 0; i < numComps; ++i) { - this.defaultColor[i] = 1; - } - this.base = base; - this.tintFn = tintFn; - this.tmpBuf = new Float32Array(base.numComps); - } - - AlternateCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function AlternateCS_getRgbItem(src, srcOffset, - dest, destOffset) { - var tmpBuf = this.tmpBuf; - this.tintFn(src, srcOffset, tmpBuf, 0); - this.base.getRgbItem(tmpBuf, 0, dest, destOffset); - }, - getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var tintFn = this.tintFn; - var base = this.base; - var scale = 1 / ((1 << bits) - 1); - var baseNumComps = base.numComps; - var usesZeroToOneRange = base.usesZeroToOneRange; - var isPassthrough = (base.isPassthrough(8) || !usesZeroToOneRange) && - alpha01 === 0; - var pos = isPassthrough ? destOffset : 0; - var baseBuf = isPassthrough ? dest : new Uint8Array(baseNumComps * count); - var numComps = this.numComps; - - var scaled = new Float32Array(numComps); - var tinted = new Float32Array(baseNumComps); - var i, j; - if (usesZeroToOneRange) { - for (i = 0; i < count; i++) { - for (j = 0; j < numComps; j++) { - scaled[j] = src[srcOffset++] * scale; - } - tintFn(scaled, 0, tinted, 0); - for (j = 0; j < baseNumComps; j++) { - baseBuf[pos++] = tinted[j] * 255; - } - } - } else { - for (i = 0; i < count; i++) { - for (j = 0; j < numComps; j++) { - scaled[j] = src[srcOffset++] * scale; - } - tintFn(scaled, 0, tinted, 0); - base.getRgbItem(tinted, 0, baseBuf, pos); - pos += baseNumComps; - } - } - if (!isPassthrough) { - base.getRgbBuffer(baseBuf, 0, count, dest, destOffset, 8, alpha01); - } - }, - getOutputLength: function AlternateCS_getOutputLength(inputLength, - alpha01) { - return this.base.getOutputLength(inputLength * - this.base.numComps / this.numComps, - alpha01); - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function AlternateCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - }, - usesZeroToOneRange: true - }; - - return AlternateCS; -})(); - -var PatternCS = (function PatternCSClosure() { - function PatternCS(baseCS) { - this.name = 'Pattern'; - this.base = baseCS; - } - PatternCS.prototype = {}; - - return PatternCS; -})(); - -var IndexedCS = (function IndexedCSClosure() { - function IndexedCS(base, highVal, lookup) { - this.name = 'Indexed'; - this.numComps = 1; - this.defaultColor = new Uint8Array([0]); - this.base = base; - this.highVal = highVal; - - var baseNumComps = base.numComps; - var length = baseNumComps * highVal; - var lookupArray; - - if (isStream(lookup)) { - lookupArray = new Uint8Array(length); - var bytes = lookup.getBytes(length); - lookupArray.set(bytes); - } else if (isString(lookup)) { - lookupArray = new Uint8Array(length); - for (var i = 0; i < length; ++i) { - lookupArray[i] = lookup.charCodeAt(i); - } - } else if (lookup instanceof Uint8Array || lookup instanceof Array) { - lookupArray = lookup; - } else { - error('Unrecognized lookup table: ' + lookup); - } - this.lookup = lookupArray; - } - - IndexedCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function IndexedCS_getRgbItem(src, srcOffset, - dest, destOffset) { - var numComps = this.base.numComps; - var start = src[srcOffset] * numComps; - this.base.getRgbItem(this.lookup, start, dest, destOffset); - }, - getRgbBuffer: function IndexedCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var base = this.base; - var numComps = base.numComps; - var outputDelta = base.getOutputLength(numComps, alpha01); - var lookup = this.lookup; - - for (var i = 0; i < count; ++i) { - var lookupPos = src[srcOffset++] * numComps; - base.getRgbBuffer(lookup, lookupPos, 1, dest, destOffset, 8, alpha01); - destOffset += outputDelta; - } - }, - getOutputLength: function IndexedCS_getOutputLength(inputLength, alpha01) { - return this.base.getOutputLength(inputLength * this.base.numComps, - alpha01); - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function IndexedCS_isDefaultDecode(decodeMap) { - // indexed color maps shouldn't be changed - return true; - }, - usesZeroToOneRange: true - }; - return IndexedCS; -})(); - -var DeviceGrayCS = (function DeviceGrayCSClosure() { - function DeviceGrayCS() { - this.name = 'DeviceGray'; - this.numComps = 1; - this.defaultColor = new Float32Array([0]); - } - - DeviceGrayCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function DeviceGrayCS_getRgbItem(src, srcOffset, - dest, destOffset) { - var c = (src[srcOffset] * 255) | 0; - c = c < 0 ? 0 : c > 255 ? 255 : c; - dest[destOffset] = dest[destOffset + 1] = dest[destOffset + 2] = c; - }, - getRgbBuffer: function DeviceGrayCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var scale = 255 / ((1 << bits) - 1); - var j = srcOffset, q = destOffset; - for (var i = 0; i < count; ++i) { - var c = (scale * src[j++]) | 0; - dest[q++] = c; - dest[q++] = c; - dest[q++] = c; - q += alpha01; - } - }, - getOutputLength: function DeviceGrayCS_getOutputLength(inputLength, - alpha01) { - return inputLength * (3 + alpha01); - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function DeviceGrayCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - }, - usesZeroToOneRange: true - }; - return DeviceGrayCS; -})(); - -var DeviceRgbCS = (function DeviceRgbCSClosure() { - function DeviceRgbCS() { - this.name = 'DeviceRGB'; - this.numComps = 3; - this.defaultColor = new Float32Array([0, 0, 0]); - } - DeviceRgbCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function DeviceRgbCS_getRgbItem(src, srcOffset, - dest, destOffset) { - var r = (src[srcOffset] * 255) | 0; - var g = (src[srcOffset + 1] * 255) | 0; - var b = (src[srcOffset + 2] * 255) | 0; - dest[destOffset] = r < 0 ? 0 : r > 255 ? 255 : r; - dest[destOffset + 1] = g < 0 ? 0 : g > 255 ? 255 : g; - dest[destOffset + 2] = b < 0 ? 0 : b > 255 ? 255 : b; - }, - getRgbBuffer: function DeviceRgbCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - if (bits === 8 && alpha01 === 0) { - dest.set(src.subarray(srcOffset, srcOffset + count * 3), destOffset); - return; - } - var scale = 255 / ((1 << bits) - 1); - var j = srcOffset, q = destOffset; - for (var i = 0; i < count; ++i) { - dest[q++] = (scale * src[j++]) | 0; - dest[q++] = (scale * src[j++]) | 0; - dest[q++] = (scale * src[j++]) | 0; - q += alpha01; - } - }, - getOutputLength: function DeviceRgbCS_getOutputLength(inputLength, - alpha01) { - return (inputLength * (3 + alpha01) / 3) | 0; - }, - isPassthrough: function DeviceRgbCS_isPassthrough(bits) { - return bits === 8; - }, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function DeviceRgbCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - }, - usesZeroToOneRange: true - }; - return DeviceRgbCS; -})(); - -var DeviceCmykCS = (function DeviceCmykCSClosure() { - // The coefficients below was found using numerical analysis: the method of - // steepest descent for the sum((f_i - color_value_i)^2) for r/g/b colors, - // where color_value is the tabular value from the table of sampled RGB colors - // from CMYK US Web Coated (SWOP) colorspace, and f_i is the corresponding - // CMYK color conversion using the estimation below: - // f(A, B,.. N) = Acc+Bcm+Ccy+Dck+c+Fmm+Gmy+Hmk+Im+Jyy+Kyk+Ly+Mkk+Nk+255 - function convertToRgb(src, srcOffset, srcScale, dest, destOffset) { - var c = src[srcOffset + 0] * srcScale; - var m = src[srcOffset + 1] * srcScale; - var y = src[srcOffset + 2] * srcScale; - var k = src[srcOffset + 3] * srcScale; - - var r = - (c * (-4.387332384609988 * c + 54.48615194189176 * m + - 18.82290502165302 * y + 212.25662451639585 * k + - -285.2331026137004) + - m * (1.7149763477362134 * m - 5.6096736904047315 * y + - -17.873870861415444 * k - 5.497006427196366) + - y * (-2.5217340131683033 * y - 21.248923337353073 * k + - 17.5119270841813) + - k * (-21.86122147463605 * k - 189.48180835922747) + 255) | 0; - var g = - (c * (8.841041422036149 * c + 60.118027045597366 * m + - 6.871425592049007 * y + 31.159100130055922 * k + - -79.2970844816548) + - m * (-15.310361306967817 * m + 17.575251261109482 * y + - 131.35250912493976 * k - 190.9453302588951) + - y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) + - k * (-20.737325471181034 * k - 187.80453709719578) + 255) | 0; - var b = - (c * (0.8842522430003296 * c + 8.078677503112928 * m + - 30.89978309703729 * y - 0.23883238689178934 * k + - -14.183576799673286) + - m * (10.49593273432072 * m + 63.02378494754052 * y + - 50.606957656360734 * k - 112.23884253719248) + - y * (0.03296041114873217 * y + 115.60384449646641 * k + - -193.58209356861505) + - k * (-22.33816807309886 * k - 180.12613974708367) + 255) | 0; - - dest[destOffset] = r > 255 ? 255 : r < 0 ? 0 : r; - dest[destOffset + 1] = g > 255 ? 255 : g < 0 ? 0 : g; - dest[destOffset + 2] = b > 255 ? 255 : b < 0 ? 0 : b; - } - - function DeviceCmykCS() { - this.name = 'DeviceCMYK'; - this.numComps = 4; - this.defaultColor = new Float32Array([0, 0, 0, 1]); - } - DeviceCmykCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function DeviceCmykCS_getRgbItem(src, srcOffset, - dest, destOffset) { - convertToRgb(src, srcOffset, 1, dest, destOffset); - }, - getRgbBuffer: function DeviceCmykCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var scale = 1 / ((1 << bits) - 1); - for (var i = 0; i < count; i++) { - convertToRgb(src, srcOffset, scale, dest, destOffset); - srcOffset += 4; - destOffset += 3 + alpha01; - } - }, - getOutputLength: function DeviceCmykCS_getOutputLength(inputLength, - alpha01) { - return (inputLength / 4 * (3 + alpha01)) | 0; - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function DeviceCmykCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - }, - usesZeroToOneRange: true - }; - - return DeviceCmykCS; -})(); - -// -// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245 -// -var CalGrayCS = (function CalGrayCSClosure() { - function CalGrayCS(whitePoint, blackPoint, gamma) { - this.name = 'CalGray'; - this.numComps = 1; - this.defaultColor = new Float32Array([0]); - - if (!whitePoint) { - error('WhitePoint missing - required for color space CalGray'); - } - blackPoint = blackPoint || [0, 0, 0]; - gamma = gamma || 1; - - // Translate arguments to spec variables. - this.XW = whitePoint[0]; - this.YW = whitePoint[1]; - this.ZW = whitePoint[2]; - - this.XB = blackPoint[0]; - this.YB = blackPoint[1]; - this.ZB = blackPoint[2]; - - this.G = gamma; - - // Validate variables as per spec. - if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { - error('Invalid WhitePoint components for ' + this.name + - ', no fallback available'); - } - - if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { - info('Invalid BlackPoint for ' + this.name + ', falling back to default'); - this.XB = this.YB = this.ZB = 0; - } - - if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) { - warn(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB + - ', ZB: ' + this.ZB + ', only default values are supported.'); - } - - if (this.G < 1) { - info('Invalid Gamma: ' + this.G + ' for ' + this.name + - ', falling back to default'); - this.G = 1; - } - } - - function convertToRgb(cs, src, srcOffset, dest, destOffset, scale) { - // A represents a gray component of a calibrated gray space. - // A <---> AG in the spec - var A = src[srcOffset] * scale; - var AG = Math.pow(A, cs.G); - - // Computes L as per spec. ( = cs.YW * AG ) - // Except if other than default BlackPoint values are used. - var L = cs.YW * AG; - // http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4. - // Convert values to rgb range [0, 255]. - var val = Math.max(295.8 * Math.pow(L, 0.333333333333333333) - 40.8, 0) | 0; - dest[destOffset] = val; - dest[destOffset + 1] = val; - dest[destOffset + 2] = val; - } - - CalGrayCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset, - dest, destOffset) { - convertToRgb(this, src, srcOffset, dest, destOffset, 1); - }, - getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var scale = 1 / ((1 << bits) - 1); - - for (var i = 0; i < count; ++i) { - convertToRgb(this, src, srcOffset, dest, destOffset, scale); - srcOffset += 1; - destOffset += 3 + alpha01; - } - }, - getOutputLength: function CalGrayCS_getOutputLength(inputLength, alpha01) { - return inputLength * (3 + alpha01); - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - }, - usesZeroToOneRange: true - }; - return CalGrayCS; -})(); - -// -// CalRGBCS: Based on "PDF Reference, Sixth Ed", p.247 -// -var CalRGBCS = (function CalRGBCSClosure() { - - // See http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html for these - // matrices. - var BRADFORD_SCALE_MATRIX = new Float32Array([ - 0.8951, 0.2664, -0.1614, - -0.7502, 1.7135, 0.0367, - 0.0389, -0.0685, 1.0296]); - - var BRADFORD_SCALE_INVERSE_MATRIX = new Float32Array([ - 0.9869929, -0.1470543, 0.1599627, - 0.4323053, 0.5183603, 0.0492912, - -0.0085287, 0.0400428, 0.9684867]); - - // See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html. - var SRGB_D65_XYZ_TO_RGB_MATRIX = new Float32Array([ - 3.2404542, -1.5371385, -0.4985314, - -0.9692660, 1.8760108, 0.0415560, - 0.0556434, -0.2040259, 1.0572252]); - - var FLAT_WHITEPOINT_MATRIX = new Float32Array([1, 1, 1]); - - var tempNormalizeMatrix = new Float32Array(3); - var tempConvertMatrix1 = new Float32Array(3); - var tempConvertMatrix2 = new Float32Array(3); - - var DECODE_L_CONSTANT = Math.pow(((8 + 16) / 116), 3) / 8.0; - - function CalRGBCS(whitePoint, blackPoint, gamma, matrix) { - this.name = 'CalRGB'; - this.numComps = 3; - this.defaultColor = new Float32Array(3); - - if (!whitePoint) { - error('WhitePoint missing - required for color space CalRGB'); - } - blackPoint = blackPoint || new Float32Array(3); - gamma = gamma || new Float32Array([1, 1, 1]); - matrix = matrix || new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]); - - // Translate arguments to spec variables. - var XW = whitePoint[0]; - var YW = whitePoint[1]; - var ZW = whitePoint[2]; - this.whitePoint = whitePoint; - - var XB = blackPoint[0]; - var YB = blackPoint[1]; - var ZB = blackPoint[2]; - this.blackPoint = blackPoint; - - this.GR = gamma[0]; - this.GG = gamma[1]; - this.GB = gamma[2]; - - this.MXA = matrix[0]; - this.MYA = matrix[1]; - this.MZA = matrix[2]; - this.MXB = matrix[3]; - this.MYB = matrix[4]; - this.MZB = matrix[5]; - this.MXC = matrix[6]; - this.MYC = matrix[7]; - this.MZC = matrix[8]; - - // Validate variables as per spec. - if (XW < 0 || ZW < 0 || YW !== 1) { - error('Invalid WhitePoint components for ' + this.name + - ', no fallback available'); - } - - if (XB < 0 || YB < 0 || ZB < 0) { - info('Invalid BlackPoint for ' + this.name + ' [' + XB + ', ' + YB + - ', ' + ZB + '], falling back to default'); - this.blackPoint = new Float32Array(3); - } - - if (this.GR < 0 || this.GG < 0 || this.GB < 0) { - info('Invalid Gamma [' + this.GR + ', ' + this.GG + ', ' + this.GB + - '] for ' + this.name + ', falling back to default'); - this.GR = this.GG = this.GB = 1; - } - - if (this.MXA < 0 || this.MYA < 0 || this.MZA < 0 || - this.MXB < 0 || this.MYB < 0 || this.MZB < 0 || - this.MXC < 0 || this.MYC < 0 || this.MZC < 0) { - info('Invalid Matrix for ' + this.name + ' [' + - this.MXA + ', ' + this.MYA + ', ' + this.MZA + - this.MXB + ', ' + this.MYB + ', ' + this.MZB + - this.MXC + ', ' + this.MYC + ', ' + this.MZC + - '], falling back to default'); - this.MXA = this.MYB = this.MZC = 1; - this.MXB = this.MYA = this.MZA = this.MXC = this.MYC = this.MZB = 0; - } - } - - function matrixProduct(a, b, result) { - result[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - result[1] = a[3] * b[0] + a[4] * b[1] + a[5] * b[2]; - result[2] = a[6] * b[0] + a[7] * b[1] + a[8] * b[2]; - } - - function convertToFlat(sourceWhitePoint, LMS, result) { - result[0] = LMS[0] * 1 / sourceWhitePoint[0]; - result[1] = LMS[1] * 1 / sourceWhitePoint[1]; - result[2] = LMS[2] * 1 / sourceWhitePoint[2]; - } - - function convertToD65(sourceWhitePoint, LMS, result) { - var D65X = 0.95047; - var D65Y = 1; - var D65Z = 1.08883; - - result[0] = LMS[0] * D65X / sourceWhitePoint[0]; - result[1] = LMS[1] * D65Y / sourceWhitePoint[1]; - result[2] = LMS[2] * D65Z / sourceWhitePoint[2]; - } - - function sRGBTransferFunction(color) { - // See http://en.wikipedia.org/wiki/SRGB. - if (color <= 0.0031308){ - return adjustToRange(0, 1, 12.92 * color); - } - - return adjustToRange(0, 1, (1 + 0.055) * Math.pow(color, 1 / 2.4) - 0.055); - } - - function adjustToRange(min, max, value) { - return Math.max(min, Math.min(max, value)); - } - - function decodeL(L) { - if (L < 0) { - return -decodeL(-L); - } - - if (L > 8.0) { - return Math.pow(((L + 16) / 116), 3); - } - - return L * DECODE_L_CONSTANT; - } - - function compensateBlackPoint(sourceBlackPoint, XYZ_Flat, result) { - - // In case the blackPoint is already the default blackPoint then there is - // no need to do compensation. - if (sourceBlackPoint[0] === 0 && - sourceBlackPoint[1] === 0 && - sourceBlackPoint[2] === 0) { - result[0] = XYZ_Flat[0]; - result[1] = XYZ_Flat[1]; - result[2] = XYZ_Flat[2]; - return; - } - - // For the blackPoint calculation details, please see - // http://www.adobe.com/content/dam/Adobe/en/devnet/photoshop/sdk/ - // AdobeBPC.pdf. - // The destination blackPoint is the default blackPoint [0, 0, 0]. - var zeroDecodeL = decodeL(0); - - var X_DST = zeroDecodeL; - var X_SRC = decodeL(sourceBlackPoint[0]); - - var Y_DST = zeroDecodeL; - var Y_SRC = decodeL(sourceBlackPoint[1]); - - var Z_DST = zeroDecodeL; - var Z_SRC = decodeL(sourceBlackPoint[2]); - - var X_Scale = (1 - X_DST) / (1 - X_SRC); - var X_Offset = 1 - X_Scale; - - var Y_Scale = (1 - Y_DST) / (1 - Y_SRC); - var Y_Offset = 1 - Y_Scale; - - var Z_Scale = (1 - Z_DST) / (1 - Z_SRC); - var Z_Offset = 1 - Z_Scale; - - result[0] = XYZ_Flat[0] * X_Scale + X_Offset; - result[1] = XYZ_Flat[1] * Y_Scale + Y_Offset; - result[2] = XYZ_Flat[2] * Z_Scale + Z_Offset; - } - - function normalizeWhitePointToFlat(sourceWhitePoint, XYZ_In, result) { - - // In case the whitePoint is already flat then there is no need to do - // normalization. - if (sourceWhitePoint[0] === 1 && sourceWhitePoint[2] === 1) { - result[0] = XYZ_In[0]; - result[1] = XYZ_In[1]; - result[2] = XYZ_In[2]; - return; - } - - var LMS = result; - matrixProduct(BRADFORD_SCALE_MATRIX, XYZ_In, LMS); - - var LMS_Flat = tempNormalizeMatrix; - convertToFlat(sourceWhitePoint, LMS, LMS_Flat); - - matrixProduct(BRADFORD_SCALE_INVERSE_MATRIX, LMS_Flat, result); - } - - function normalizeWhitePointToD65(sourceWhitePoint, XYZ_In, result) { - - var LMS = result; - matrixProduct(BRADFORD_SCALE_MATRIX, XYZ_In, LMS); - - var LMS_D65 = tempNormalizeMatrix; - convertToD65(sourceWhitePoint, LMS, LMS_D65); - - matrixProduct(BRADFORD_SCALE_INVERSE_MATRIX, LMS_D65, result); - } - - function convertToRgb(cs, src, srcOffset, dest, destOffset, scale) { - // A, B and C represent a red, green and blue components of a calibrated - // rgb space. - var A = adjustToRange(0, 1, src[srcOffset] * scale); - var B = adjustToRange(0, 1, src[srcOffset + 1] * scale); - var C = adjustToRange(0, 1, src[srcOffset + 2] * scale); - - // A <---> AGR in the spec - // B <---> BGG in the spec - // C <---> CGB in the spec - var AGR = Math.pow(A, cs.GR); - var BGG = Math.pow(B, cs.GG); - var CGB = Math.pow(C, cs.GB); - - // Computes intermediate variables L, M, N as per spec. - // To decode X, Y, Z values map L, M, N directly to them. - var X = cs.MXA * AGR + cs.MXB * BGG + cs.MXC * CGB; - var Y = cs.MYA * AGR + cs.MYB * BGG + cs.MYC * CGB; - var Z = cs.MZA * AGR + cs.MZB * BGG + cs.MZC * CGB; - - // The following calculations are based on this document: - // http://www.adobe.com/content/dam/Adobe/en/devnet/photoshop/sdk/ - // AdobeBPC.pdf. - var XYZ = tempConvertMatrix1; - XYZ[0] = X; - XYZ[1] = Y; - XYZ[2] = Z; - var XYZ_Flat = tempConvertMatrix2; - - normalizeWhitePointToFlat(cs.whitePoint, XYZ, XYZ_Flat); - - var XYZ_Black = tempConvertMatrix1; - compensateBlackPoint(cs.blackPoint, XYZ_Flat, XYZ_Black); - - var XYZ_D65 = tempConvertMatrix2; - normalizeWhitePointToD65(FLAT_WHITEPOINT_MATRIX, XYZ_Black, XYZ_D65); - - var SRGB = tempConvertMatrix1; - matrixProduct(SRGB_D65_XYZ_TO_RGB_MATRIX, XYZ_D65, SRGB); - - var sR = sRGBTransferFunction(SRGB[0]); - var sG = sRGBTransferFunction(SRGB[1]); - var sB = sRGBTransferFunction(SRGB[2]); - - // Convert the values to rgb range [0, 255]. - dest[destOffset] = Math.round(sR * 255); - dest[destOffset + 1] = Math.round(sG * 255); - dest[destOffset + 2] = Math.round(sB * 255); - } - - CalRGBCS.prototype = { - getRgb: function CalRGBCS_getRgb(src, srcOffset) { - var rgb = new Uint8Array(3); - this.getRgbItem(src, srcOffset, rgb, 0); - return rgb; - }, - getRgbItem: function CalRGBCS_getRgbItem(src, srcOffset, - dest, destOffset) { - convertToRgb(this, src, srcOffset, dest, destOffset, 1); - }, - getRgbBuffer: function CalRGBCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var scale = 1 / ((1 << bits) - 1); - - for (var i = 0; i < count; ++i) { - convertToRgb(this, src, srcOffset, dest, destOffset, scale); - srcOffset += 3; - destOffset += 3 + alpha01; - } - }, - getOutputLength: function CalRGBCS_getOutputLength(inputLength, alpha01) { - return (inputLength * (3 + alpha01) / 3) | 0; - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function CalRGBCS_isDefaultDecode(decodeMap) { - return ColorSpace.isDefaultDecode(decodeMap, this.numComps); - }, - usesZeroToOneRange: true - }; - return CalRGBCS; -})(); - -// -// LabCS: Based on "PDF Reference, Sixth Ed", p.250 -// -var LabCS = (function LabCSClosure() { - function LabCS(whitePoint, blackPoint, range) { - this.name = 'Lab'; - this.numComps = 3; - this.defaultColor = new Float32Array([0, 0, 0]); - - if (!whitePoint) { - error('WhitePoint missing - required for color space Lab'); - } - blackPoint = blackPoint || [0, 0, 0]; - range = range || [-100, 100, -100, 100]; - - // Translate args to spec variables - this.XW = whitePoint[0]; - this.YW = whitePoint[1]; - this.ZW = whitePoint[2]; - this.amin = range[0]; - this.amax = range[1]; - this.bmin = range[2]; - this.bmax = range[3]; - - // These are here just for completeness - the spec doesn't offer any - // formulas that use BlackPoint in Lab - this.XB = blackPoint[0]; - this.YB = blackPoint[1]; - this.ZB = blackPoint[2]; - - // Validate vars as per spec - if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) { - error('Invalid WhitePoint components, no fallback available'); - } - - if (this.XB < 0 || this.YB < 0 || this.ZB < 0) { - info('Invalid BlackPoint, falling back to default'); - this.XB = this.YB = this.ZB = 0; - } - - if (this.amin > this.amax || this.bmin > this.bmax) { - info('Invalid Range, falling back to defaults'); - this.amin = -100; - this.amax = 100; - this.bmin = -100; - this.bmax = 100; - } - } - - // Function g(x) from spec - function fn_g(x) { - if (x >= 6 / 29) { - return x * x * x; - } else { - return (108 / 841) * (x - 4 / 29); - } - } - - function decode(value, high1, low2, high2) { - return low2 + (value) * (high2 - low2) / (high1); - } - - // If decoding is needed maxVal should be 2^bits per component - 1. - function convertToRgb(cs, src, srcOffset, maxVal, dest, destOffset) { - // XXX: Lab input is in the range of [0, 100], [amin, amax], [bmin, bmax] - // not the usual [0, 1]. If a command like setFillColor is used the src - // values will already be within the correct range. However, if we are - // converting an image we have to map the values to the correct range given - // above. - // Ls,as,bs <---> L*,a*,b* in the spec - var Ls = src[srcOffset]; - var as = src[srcOffset + 1]; - var bs = src[srcOffset + 2]; - if (maxVal !== false) { - Ls = decode(Ls, maxVal, 0, 100); - as = decode(as, maxVal, cs.amin, cs.amax); - bs = decode(bs, maxVal, cs.bmin, cs.bmax); - } - - // Adjust limits of 'as' and 'bs' - as = as > cs.amax ? cs.amax : as < cs.amin ? cs.amin : as; - bs = bs > cs.bmax ? cs.bmax : bs < cs.bmin ? cs.bmin : bs; - - // Computes intermediate variables X,Y,Z as per spec - var M = (Ls + 16) / 116; - var L = M + (as / 500); - var N = M - (bs / 200); - - var X = cs.XW * fn_g(L); - var Y = cs.YW * fn_g(M); - var Z = cs.ZW * fn_g(N); - - var r, g, b; - // Using different conversions for D50 and D65 white points, - // per http://www.color.org/srgb.pdf - if (cs.ZW < 1) { - // Assuming D50 (X=0.9642, Y=1.00, Z=0.8249) - r = X * 3.1339 + Y * -1.6170 + Z * -0.4906; - g = X * -0.9785 + Y * 1.9160 + Z * 0.0333; - b = X * 0.0720 + Y * -0.2290 + Z * 1.4057; - } else { - // Assuming D65 (X=0.9505, Y=1.00, Z=1.0888) - r = X * 3.2406 + Y * -1.5372 + Z * -0.4986; - g = X * -0.9689 + Y * 1.8758 + Z * 0.0415; - b = X * 0.0557 + Y * -0.2040 + Z * 1.0570; - } - // clamp color values to [0,1] range then convert to [0,255] range. - dest[destOffset] = r <= 0 ? 0 : r >= 1 ? 255 : Math.sqrt(r) * 255 | 0; - dest[destOffset + 1] = g <= 0 ? 0 : g >= 1 ? 255 : Math.sqrt(g) * 255 | 0; - dest[destOffset + 2] = b <= 0 ? 0 : b >= 1 ? 255 : Math.sqrt(b) * 255 | 0; - } - - LabCS.prototype = { - getRgb: ColorSpace.prototype.getRgb, - getRgbItem: function LabCS_getRgbItem(src, srcOffset, dest, destOffset) { - convertToRgb(this, src, srcOffset, false, dest, destOffset); - }, - getRgbBuffer: function LabCS_getRgbBuffer(src, srcOffset, count, - dest, destOffset, bits, - alpha01) { - var maxVal = (1 << bits) - 1; - for (var i = 0; i < count; i++) { - convertToRgb(this, src, srcOffset, maxVal, dest, destOffset); - srcOffset += 3; - destOffset += 3 + alpha01; - } - }, - getOutputLength: function LabCS_getOutputLength(inputLength, alpha01) { - return (inputLength * (3 + alpha01) / 3) | 0; - }, - isPassthrough: ColorSpace.prototype.isPassthrough, - fillRgb: ColorSpace.prototype.fillRgb, - isDefaultDecode: function LabCS_isDefaultDecode(decodeMap) { - // XXX: Decoding is handled with the lab conversion because of the strange - // ranges that are used. - return true; - }, - usesZeroToOneRange: false - }; - return LabCS; -})(); - - -var ARCFourCipher = (function ARCFourCipherClosure() { - function ARCFourCipher(key) { - this.a = 0; - this.b = 0; - var s = new Uint8Array(256); - var i, j = 0, tmp, keyLength = key.length; - for (i = 0; i < 256; ++i) { - s[i] = i; - } - for (i = 0; i < 256; ++i) { - tmp = s[i]; - j = (j + tmp + key[i % keyLength]) & 0xFF; - s[i] = s[j]; - s[j] = tmp; - } - this.s = s; - } - - ARCFourCipher.prototype = { - encryptBlock: function ARCFourCipher_encryptBlock(data) { - var i, n = data.length, tmp, tmp2; - var a = this.a, b = this.b, s = this.s; - var output = new Uint8Array(n); - for (i = 0; i < n; ++i) { - a = (a + 1) & 0xFF; - tmp = s[a]; - b = (b + tmp) & 0xFF; - tmp2 = s[b]; - s[a] = tmp2; - s[b] = tmp; - output[i] = data[i] ^ s[(tmp + tmp2) & 0xFF]; - } - this.a = a; - this.b = b; - return output; - } - }; - ARCFourCipher.prototype.decryptBlock = ARCFourCipher.prototype.encryptBlock; - - return ARCFourCipher; -})(); - -var calculateMD5 = (function calculateMD5Closure() { - var r = new Uint8Array([ - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); - - var k = new Int32Array([ - -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, - -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, - 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, - 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, - 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, - 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, - -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, - -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, - -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, - -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, - -145523070, -1120210379, 718787259, -343485551]); - - function hash(data, offset, length) { - var h0 = 1732584193, h1 = -271733879, h2 = -1732584194, h3 = 271733878; - // pre-processing - var paddedLength = (length + 72) & ~63; // data + 9 extra bytes - var padded = new Uint8Array(paddedLength); - var i, j, n; - for (i = 0; i < length; ++i) { - padded[i] = data[offset++]; - } - padded[i++] = 0x80; - n = paddedLength - 8; - while (i < n) { - padded[i++] = 0; - } - padded[i++] = (length << 3) & 0xFF; - padded[i++] = (length >> 5) & 0xFF; - padded[i++] = (length >> 13) & 0xFF; - padded[i++] = (length >> 21) & 0xFF; - padded[i++] = (length >>> 29) & 0xFF; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - var w = new Int32Array(16); - for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j, i += 4) { - w[j] = (padded[i] | (padded[i + 1] << 8) | - (padded[i + 2] << 16) | (padded[i + 3] << 24)); - } - var a = h0, b = h1, c = h2, d = h3, f, g; - for (j = 0; j < 64; ++j) { - if (j < 16) { - f = (b & c) | ((~b) & d); - g = j; - } else if (j < 32) { - f = (d & b) | ((~d) & c); - g = (5 * j + 1) & 15; - } else if (j < 48) { - f = b ^ c ^ d; - g = (3 * j + 5) & 15; - } else { - f = c ^ (b | (~d)); - g = (7 * j) & 15; - } - var tmp = d, rotateArg = (a + f + k[j] + w[g]) | 0, rotate = r[j]; - d = c; - c = b; - b = (b + ((rotateArg << rotate) | (rotateArg >>> (32 - rotate)))) | 0; - a = tmp; - } - h0 = (h0 + a) | 0; - h1 = (h1 + b) | 0; - h2 = (h2 + c) | 0; - h3 = (h3 + d) | 0; - } - return new Uint8Array([ - h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >>> 24) & 0xFF, - h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >>> 24) & 0xFF, - h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >>> 24) & 0xFF, - h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >>> 24) & 0xFF - ]); - } - - return hash; -})(); -var Word64 = (function Word64Closure() { - function Word64(highInteger, lowInteger) { - this.high = highInteger | 0; - this.low = lowInteger | 0; - } - Word64.prototype = { - and: function Word64_and(word) { - this.high &= word.high; - this.low &= word.low; - }, - xor: function Word64_xor(word) { - this.high ^= word.high; - this.low ^= word.low; - }, - - or: function Word64_or(word) { - this.high |= word.high; - this.low |= word.low; - }, - - shiftRight: function Word64_shiftRight(places) { - if (places >= 32) { - this.low = (this.high >>> (places - 32)) | 0; - this.high = 0; - } else { - this.low = (this.low >>> places) | (this.high << (32 - places)); - this.high = (this.high >>> places) | 0; - } - }, - - shiftLeft: function Word64_shiftLeft(places) { - if (places >= 32) { - this.high = this.low << (places - 32); - this.low = 0; - } else { - this.high = (this.high << places) | (this.low >>> (32 - places)); - this.low = this.low << places; - } - }, - - rotateRight: function Word64_rotateRight(places) { - var low, high; - if (places & 32) { - high = this.low; - low = this.high; - } else { - low = this.low; - high = this.high; - } - places &= 31; - this.low = (low >>> places) | (high << (32 - places)); - this.high = (high >>> places) | (low << (32 - places)); - }, - - not: function Word64_not() { - this.high = ~this.high; - this.low = ~this.low; - }, - - add: function Word64_add(word) { - var lowAdd = (this.low >>> 0) + (word.low >>> 0); - var highAdd = (this.high >>> 0) + (word.high >>> 0); - if (lowAdd > 0xFFFFFFFF) { - highAdd += 1; - } - this.low = lowAdd | 0; - this.high = highAdd | 0; - }, - - copyTo: function Word64_copyTo(bytes, offset) { - bytes[offset] = (this.high >>> 24) & 0xFF; - bytes[offset + 1] = (this.high >> 16) & 0xFF; - bytes[offset + 2] = (this.high >> 8) & 0xFF; - bytes[offset + 3] = this.high & 0xFF; - bytes[offset + 4] = (this.low >>> 24) & 0xFF; - bytes[offset + 5] = (this.low >> 16) & 0xFF; - bytes[offset + 6] = (this.low >> 8) & 0xFF; - bytes[offset + 7] = this.low & 0xFF; - }, - - assign: function Word64_assign(word) { - this.high = word.high; - this.low = word.low; - } - }; - return Word64; -})(); - -var calculateSHA256 = (function calculateSHA256Closure() { - function rotr(x, n) { - return (x >>> n) | (x << 32 - n); - } - - function ch(x, y, z) { - return (x & y) ^ (~x & z); - } - - function maj(x, y, z) { - return (x & y) ^ (x & z) ^ (y & z); - } - - function sigma(x) { - return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); - } - - function sigmaPrime(x) { - return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); - } - - function littleSigma(x) { - return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3; - } - - function littleSigmaPrime(x) { - return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10; - } - - var k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]; - - function hash(data, offset, length) { - // initial hash values - var h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, - h3 = 0xa54ff53a, h4 = 0x510e527f, h5 = 0x9b05688c, - h6 = 0x1f83d9ab, h7 = 0x5be0cd19; - // pre-processing - var paddedLength = Math.ceil((length + 9) / 64) * 64; - var padded = new Uint8Array(paddedLength); - var i, j, n; - for (i = 0; i < length; ++i) { - padded[i] = data[offset++]; - } - padded[i++] = 0x80; - n = paddedLength - 8; - while (i < n) { - padded[i++] = 0; - } - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = (length >>> 29) & 0xFF; - padded[i++] = (length >> 21) & 0xFF; - padded[i++] = (length >> 13) & 0xFF; - padded[i++] = (length >> 5) & 0xFF; - padded[i++] = (length << 3) & 0xFF; - var w = new Uint32Array(64); - // for each 512 bit block - for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j) { - w[j] = (padded[i] << 24 | (padded[i + 1] << 16) | - (padded[i + 2] << 8) | (padded[i + 3])); - i += 4; - } - - for (j = 16; j < 64; ++j) { - w[j] = littleSigmaPrime(w[j - 2]) + w[j - 7] + - littleSigma(w[j - 15]) + w[j - 16] | 0; - } - var a = h0, b = h1, c = h2, d = h3, e = h4, - f = h5, g = h6, h = h7, t1, t2; - for (j = 0; j < 64; ++j) { - t1 = h + sigmaPrime(e) + ch(e, f, g) + k[j] + w[j]; - t2 = sigma(a) + maj(a, b, c); - h = g; - g = f; - f = e; - e = (d + t1) | 0; - d = c; - c = b; - b = a; - a = (t1 + t2) | 0; - } - h0 = (h0 + a) | 0; - h1 = (h1 + b) | 0; - h2 = (h2 + c) | 0; - h3 = (h3 + d) | 0; - h4 = (h4 + e) | 0; - h5 = (h5 + f) | 0; - h6 = (h6 + g) | 0; - h7 = (h7 + h) | 0; - } - return new Uint8Array([ - (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, (h0) & 0xFF, - (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, (h1) & 0xFF, - (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, (h2) & 0xFF, - (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, (h3) & 0xFF, - (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, (h4) & 0xFF, - (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, (h5) & 0xFF, - (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, (h6) & 0xFF, - (h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, (h7) & 0xFF - ]); - } - - return hash; -})(); - -var calculateSHA512 = (function calculateSHA512Closure() { - function ch(result, x, y, z, tmp) { - result.assign(x); - result.and(y); - tmp.assign(x); - tmp.not(); - tmp.and(z); - result.xor(tmp); - } - - function maj(result, x, y, z, tmp) { - result.assign(x); - result.and(y); - tmp.assign(x); - tmp.and(z); - result.xor(tmp); - tmp.assign(y); - tmp.and(z); - result.xor(tmp); - } - - function sigma(result, x, tmp) { - result.assign(x); - result.rotateRight(28); - tmp.assign(x); - tmp.rotateRight(34); - result.xor(tmp); - tmp.assign(x); - tmp.rotateRight(39); - result.xor(tmp); - } - - function sigmaPrime(result, x, tmp) { - result.assign(x); - result.rotateRight(14); - tmp.assign(x); - tmp.rotateRight(18); - result.xor(tmp); - tmp.assign(x); - tmp.rotateRight(41); - result.xor(tmp); - } - - function littleSigma(result, x, tmp) { - result.assign(x); - result.rotateRight(1); - tmp.assign(x); - tmp.rotateRight(8); - result.xor(tmp); - tmp.assign(x); - tmp.shiftRight(7); - result.xor(tmp); - } - - function littleSigmaPrime(result, x, tmp) { - result.assign(x); - result.rotateRight(19); - tmp.assign(x); - tmp.rotateRight(61); - result.xor(tmp); - tmp.assign(x); - tmp.shiftRight(6); - result.xor(tmp); - } - - var k = [ - new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), - new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), - new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), - new Word64(0x923f82a4, 0xaf194f9b), new Word64(0xab1c5ed5, 0xda6d8118), - new Word64(0xd807aa98, 0xa3030242), new Word64(0x12835b01, 0x45706fbe), - new Word64(0x243185be, 0x4ee4b28c), new Word64(0x550c7dc3, 0xd5ffb4e2), - new Word64(0x72be5d74, 0xf27b896f), new Word64(0x80deb1fe, 0x3b1696b1), - new Word64(0x9bdc06a7, 0x25c71235), new Word64(0xc19bf174, 0xcf692694), - new Word64(0xe49b69c1, 0x9ef14ad2), new Word64(0xefbe4786, 0x384f25e3), - new Word64(0x0fc19dc6, 0x8b8cd5b5), new Word64(0x240ca1cc, 0x77ac9c65), - new Word64(0x2de92c6f, 0x592b0275), new Word64(0x4a7484aa, 0x6ea6e483), - new Word64(0x5cb0a9dc, 0xbd41fbd4), new Word64(0x76f988da, 0x831153b5), - new Word64(0x983e5152, 0xee66dfab), new Word64(0xa831c66d, 0x2db43210), - new Word64(0xb00327c8, 0x98fb213f), new Word64(0xbf597fc7, 0xbeef0ee4), - new Word64(0xc6e00bf3, 0x3da88fc2), new Word64(0xd5a79147, 0x930aa725), - new Word64(0x06ca6351, 0xe003826f), new Word64(0x14292967, 0x0a0e6e70), - new Word64(0x27b70a85, 0x46d22ffc), new Word64(0x2e1b2138, 0x5c26c926), - new Word64(0x4d2c6dfc, 0x5ac42aed), new Word64(0x53380d13, 0x9d95b3df), - new Word64(0x650a7354, 0x8baf63de), new Word64(0x766a0abb, 0x3c77b2a8), - new Word64(0x81c2c92e, 0x47edaee6), new Word64(0x92722c85, 0x1482353b), - new Word64(0xa2bfe8a1, 0x4cf10364), new Word64(0xa81a664b, 0xbc423001), - new Word64(0xc24b8b70, 0xd0f89791), new Word64(0xc76c51a3, 0x0654be30), - new Word64(0xd192e819, 0xd6ef5218), new Word64(0xd6990624, 0x5565a910), - new Word64(0xf40e3585, 0x5771202a), new Word64(0x106aa070, 0x32bbd1b8), - new Word64(0x19a4c116, 0xb8d2d0c8), new Word64(0x1e376c08, 0x5141ab53), - new Word64(0x2748774c, 0xdf8eeb99), new Word64(0x34b0bcb5, 0xe19b48a8), - new Word64(0x391c0cb3, 0xc5c95a63), new Word64(0x4ed8aa4a, 0xe3418acb), - new Word64(0x5b9cca4f, 0x7763e373), new Word64(0x682e6ff3, 0xd6b2b8a3), - new Word64(0x748f82ee, 0x5defb2fc), new Word64(0x78a5636f, 0x43172f60), - new Word64(0x84c87814, 0xa1f0ab72), new Word64(0x8cc70208, 0x1a6439ec), - new Word64(0x90befffa, 0x23631e28), new Word64(0xa4506ceb, 0xde82bde9), - new Word64(0xbef9a3f7, 0xb2c67915), new Word64(0xc67178f2, 0xe372532b), - new Word64(0xca273ece, 0xea26619c), new Word64(0xd186b8c7, 0x21c0c207), - new Word64(0xeada7dd6, 0xcde0eb1e), new Word64(0xf57d4f7f, 0xee6ed178), - new Word64(0x06f067aa, 0x72176fba), new Word64(0x0a637dc5, 0xa2c898a6), - new Word64(0x113f9804, 0xbef90dae), new Word64(0x1b710b35, 0x131c471b), - new Word64(0x28db77f5, 0x23047d84), new Word64(0x32caab7b, 0x40c72493), - new Word64(0x3c9ebe0a, 0x15c9bebc), new Word64(0x431d67c4, 0x9c100d4c), - new Word64(0x4cc5d4be, 0xcb3e42b6), new Word64(0x597f299c, 0xfc657e2a), - new Word64(0x5fcb6fab, 0x3ad6faec), new Word64(0x6c44198c, 0x4a475817)]; - - function hash(data, offset, length, mode384) { - mode384 = !!mode384; - // initial hash values - var h0, h1, h2, h3, h4, h5, h6, h7; - if (!mode384) { - h0 = new Word64(0x6a09e667, 0xf3bcc908); - h1 = new Word64(0xbb67ae85, 0x84caa73b); - h2 = new Word64(0x3c6ef372, 0xfe94f82b); - h3 = new Word64(0xa54ff53a, 0x5f1d36f1); - h4 = new Word64(0x510e527f, 0xade682d1); - h5 = new Word64(0x9b05688c, 0x2b3e6c1f); - h6 = new Word64(0x1f83d9ab, 0xfb41bd6b); - h7 = new Word64(0x5be0cd19, 0x137e2179); - } - else { - // SHA384 is exactly the same - // except with different starting values and a trimmed result - h0 = new Word64(0xcbbb9d5d, 0xc1059ed8); - h1 = new Word64(0x629a292a, 0x367cd507); - h2 = new Word64(0x9159015a, 0x3070dd17); - h3 = new Word64(0x152fecd8, 0xf70e5939); - h4 = new Word64(0x67332667, 0xffc00b31); - h5 = new Word64(0x8eb44a87, 0x68581511); - h6 = new Word64(0xdb0c2e0d, 0x64f98fa7); - h7 = new Word64(0x47b5481d, 0xbefa4fa4); - } - - // pre-processing - var paddedLength = Math.ceil((length + 17) / 128) * 128; - var padded = new Uint8Array(paddedLength); - var i, j, n; - for (i = 0; i < length; ++i) { - padded[i] = data[offset++]; - } - padded[i++] = 0x80; - n = paddedLength - 16; - while (i < n) { - padded[i++] = 0; - } - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = (length >>> 29) & 0xFF; - padded[i++] = (length >> 21) & 0xFF; - padded[i++] = (length >> 13) & 0xFF; - padded[i++] = (length >> 5) & 0xFF; - padded[i++] = (length << 3) & 0xFF; - - var w = new Array(80); - for (i = 0; i < 80; i++) { - w[i] = new Word64(0, 0); - } - var a = new Word64(0, 0), b = new Word64(0, 0), c = new Word64(0, 0); - var d = new Word64(0, 0), e = new Word64(0, 0), f = new Word64(0, 0); - var g = new Word64(0, 0), h = new Word64(0, 0); - var t1 = new Word64(0, 0), t2 = new Word64(0, 0); - var tmp1 = new Word64(0, 0), tmp2 = new Word64(0, 0), tmp3; - - // for each 1024 bit block - for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j) { - w[j].high = (padded[i] << 24) | (padded[i + 1] << 16) | - (padded[i + 2] << 8) | (padded[i + 3]); - w[j].low = (padded[i + 4]) << 24 | (padded[i + 5]) << 16 | - (padded[i + 6]) << 8 | (padded[i + 7]); - i += 8; - } - for (j = 16; j < 80; ++j) { - tmp3 = w[j]; - littleSigmaPrime(tmp3, w[j - 2], tmp2); - tmp3.add(w[j - 7]); - littleSigma(tmp1, w[j - 15], tmp2); - tmp3.add(tmp1); - tmp3.add(w[j - 16]); - } - - a.assign(h0); b.assign(h1); c.assign(h2); d.assign(h3); - e.assign(h4); f.assign(h5); g.assign(h6); h.assign(h7); - for (j = 0; j < 80; ++j) { - t1.assign(h); - sigmaPrime(tmp1, e, tmp2); - t1.add(tmp1); - ch(tmp1, e, f, g, tmp2); - t1.add(tmp1); - t1.add(k[j]); - t1.add(w[j]); - - sigma(t2, a, tmp2); - maj(tmp1, a, b, c, tmp2); - t2.add(tmp1); - - tmp3 = h; - h = g; - g = f; - f = e; - d.add(t1); - e = d; - d = c; - c = b; - b = a; - tmp3.assign(t1); - tmp3.add(t2); - a = tmp3; - } - h0.add(a); - h1.add(b); - h2.add(c); - h3.add(d); - h4.add(e); - h5.add(f); - h6.add(g); - h7.add(h); - } - - var result; - if (!mode384) { - result = new Uint8Array(64); - h0.copyTo(result,0); - h1.copyTo(result,8); - h2.copyTo(result,16); - h3.copyTo(result,24); - h4.copyTo(result,32); - h5.copyTo(result,40); - h6.copyTo(result,48); - h7.copyTo(result,56); - } - else { - result = new Uint8Array(48); - h0.copyTo(result,0); - h1.copyTo(result,8); - h2.copyTo(result,16); - h3.copyTo(result,24); - h4.copyTo(result,32); - h5.copyTo(result,40); - } - return result; - } - - return hash; -})(); -var calculateSHA384 = (function calculateSHA384Closure() { - function hash(data, offset, length) { - return calculateSHA512(data, offset, length, true); - } - - return hash; -})(); -var NullCipher = (function NullCipherClosure() { - function NullCipher() { - } - - NullCipher.prototype = { - decryptBlock: function NullCipher_decryptBlock(data) { - return data; - } - }; - - return NullCipher; -})(); - -var AES128Cipher = (function AES128CipherClosure() { - var rcon = new Uint8Array([ - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, - 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, - 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, - 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, - 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, - 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, - 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, - 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, - 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, - 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, - 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, - 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, - 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, - 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, - 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, - 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d]); - - var s = new Uint8Array([ - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, - 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, - 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, - 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, - 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, - 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, - 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, - 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, - 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, - 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, - 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, - 0xb0, 0x54, 0xbb, 0x16]); - - var inv_s = new Uint8Array([ - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, - 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, - 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, - 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, - 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, - 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, - 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, - 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, - 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, - 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0c, 0x7d]); - var mixCol = new Uint8Array(256); - for (var i = 0; i < 256; i++) { - if (i < 128) { - mixCol[i] = i << 1; - } else { - mixCol[i] = (i << 1) ^ 0x1b; - } - } - var mix = new Uint32Array([ - 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, - 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, - 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, - 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, - 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, - 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, - 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, - 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, - 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, - 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, - 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, - 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, - 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, - 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, - 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, - 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, - 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, - 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, - 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, - 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, - 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, - 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, - 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, - 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, - 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, - 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, - 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, - 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, - 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, - 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, - 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, - 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, - 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, - 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, - 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, - 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, - 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, - 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, - 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, - 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, - 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, - 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, - 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]); - - function expandKey128(cipherKey) { - var b = 176, result = new Uint8Array(b); - result.set(cipherKey); - for (var j = 16, i = 1; j < b; ++i) { - // RotWord - var t1 = result[j - 3], t2 = result[j - 2], - t3 = result[j - 1], t4 = result[j - 4]; - // SubWord - t1 = s[t1]; - t2 = s[t2]; - t3 = s[t3]; - t4 = s[t4]; - // Rcon - t1 = t1 ^ rcon[i]; - for (var n = 0; n < 4; ++n) { - result[j] = (t1 ^= result[j - 16]); - j++; - result[j] = (t2 ^= result[j - 16]); - j++; - result[j] = (t3 ^= result[j - 16]); - j++; - result[j] = (t4 ^= result[j - 16]); - j++; - } - } - return result; - } - - function decrypt128(input, key) { - var state = new Uint8Array(16); - state.set(input); - var i, j, k; - var t, u, v; - // AddRoundKey - for (j = 0, k = 160; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - for (i = 9; i >= 1; --i) { - // InvShiftRows - t = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = t; - t = state[14]; - u = state[10]; - state[14] = state[6]; - state[10] = state[2]; - state[6] = t; - state[2] = u; - t = state[15]; - u = state[11]; - v = state[7]; - state[15] = state[3]; - state[11] = t; - state[7] = u; - state[3] = v; - // InvSubBytes - for (j = 0; j < 16; ++j) { - state[j] = inv_s[state[j]]; - } - // AddRoundKey - for (j = 0, k = i * 16; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - // InvMixColumns - for (j = 0; j < 16; j += 4) { - var s0 = mix[state[j]], s1 = mix[state[j + 1]], - s2 = mix[state[j + 2]], s3 = mix[state[j + 3]]; - t = (s0 ^ (s1 >>> 8) ^ (s1 << 24) ^ (s2 >>> 16) ^ (s2 << 16) ^ - (s3 >>> 24) ^ (s3 << 8)); - state[j] = (t >>> 24) & 0xFF; - state[j + 1] = (t >> 16) & 0xFF; - state[j + 2] = (t >> 8) & 0xFF; - state[j + 3] = t & 0xFF; - } - } - // InvShiftRows - t = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = t; - t = state[14]; - u = state[10]; - state[14] = state[6]; - state[10] = state[2]; - state[6] = t; - state[2] = u; - t = state[15]; - u = state[11]; - v = state[7]; - state[15] = state[3]; - state[11] = t; - state[7] = u; - state[3] = v; - for (j = 0; j < 16; ++j) { - // InvSubBytes - state[j] = inv_s[state[j]]; - // AddRoundKey - state[j] ^= key[j]; - } - return state; - } - - function encrypt128(input, key) { - var t, u, v, k; - var state = new Uint8Array(16); - state.set(input); - for (j = 0; j < 16; ++j) { - // AddRoundKey - state[j] ^= key[j]; - } - - for (i = 1; i < 10; i++) { - //SubBytes - for (j = 0; j < 16; ++j) { - state[j] = s[state[j]]; - } - //ShiftRows - v = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = v; - v = state[2]; - u = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = v; - state[14] = u; - v = state[3]; - u = state[7]; - t = state[11]; - state[3] = state[15]; - state[7] = v; - state[11] = u; - state[15] = t; - //MixColumns - for (var j = 0; j < 16; j += 4) { - var s0 = state[j + 0], s1 = state[j + 1]; - var s2 = state[j + 2], s3 = state[j + 3]; - t = s0 ^ s1 ^ s2 ^ s3; - state[j + 0] ^= t ^ mixCol[s0 ^ s1]; - state[j + 1] ^= t ^ mixCol[s1 ^ s2]; - state[j + 2] ^= t ^ mixCol[s2 ^ s3]; - state[j + 3] ^= t ^ mixCol[s3 ^ s0]; - } - //AddRoundKey - for (j = 0, k = i * 16; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - } - - //SubBytes - for (j = 0; j < 16; ++j) { - state[j] = s[state[j]]; - } - //ShiftRows - v = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = v; - v = state[2]; - u = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = v; - state[14] = u; - v = state[3]; - u = state[7]; - t = state[11]; - state[3] = state[15]; - state[7] = v; - state[11] = u; - state[15] = t; - //AddRoundKey - for (j = 0, k = 160; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - return state; - } - - function AES128Cipher(key) { - this.key = expandKey128(key); - this.buffer = new Uint8Array(16); - this.bufferPosition = 0; - } - - function decryptBlock2(data, finalize) { - var i, j, ii, sourceLength = data.length, - buffer = this.buffer, bufferLength = this.bufferPosition, - result = [], iv = this.iv; - for (i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; - if (bufferLength < 16) { - continue; - } - // buffer is full, decrypting - var plain = decrypt128(buffer, this.key); - // xor-ing the IV vector to get plain text - for (j = 0; j < 16; ++j) { - plain[j] ^= iv[j]; - } - iv = buffer; - result.push(plain); - buffer = new Uint8Array(16); - bufferLength = 0; - } - // saving incomplete buffer - this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; - if (result.length === 0) { - return new Uint8Array([]); - } - // combining plain text blocks into one - var outputLength = 16 * result.length; - if (finalize) { - // undo a padding that is described in RFC 2898 - var lastBlock = result[result.length - 1]; - var psLen = lastBlock[15]; - if (psLen <= 16) { - for (i = 15, ii = 16 - psLen; i >= ii; --i) { - if (lastBlock[i] !== psLen) { - // Invalid padding, assume that the block has no padding. - psLen = 0; - break; - } - } - outputLength -= psLen; - result[result.length - 1] = lastBlock.subarray(0, 16 - psLen); - } - } - var output = new Uint8Array(outputLength); - for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { - output.set(result[i], j); - } - return output; - } - - AES128Cipher.prototype = { - decryptBlock: function AES128Cipher_decryptBlock(data, finalize) { - var i, sourceLength = data.length; - var buffer = this.buffer, bufferLength = this.bufferPosition; - // waiting for IV values -- they are at the start of the stream - for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) { - buffer[bufferLength] = data[i]; - } - if (bufferLength < 16) { - // need more data - this.bufferLength = bufferLength; - return new Uint8Array([]); - } - this.iv = buffer; - this.buffer = new Uint8Array(16); - this.bufferLength = 0; - // starting decryption - this.decryptBlock = decryptBlock2; - return this.decryptBlock(data.subarray(16), finalize); - }, - encrypt: function AES128Cipher_encrypt(data, iv) { - var i, j, ii, sourceLength = data.length, - buffer = this.buffer, bufferLength = this.bufferPosition, - result = []; - if (!iv) { - iv = new Uint8Array(16); - } - for (i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; - if (bufferLength < 16) { - continue; - } - for (j = 0; j < 16; ++j) { - buffer[j] ^= iv[j]; - } - - // buffer is full, encrypting - var cipher = encrypt128(buffer, this.key); - iv = cipher; - result.push(cipher); - buffer = new Uint8Array(16); - bufferLength = 0; - } - // saving incomplete buffer - this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; - if (result.length === 0) { - return new Uint8Array([]); - } - // combining plain text blocks into one - var outputLength = 16 * result.length; - var output = new Uint8Array(outputLength); - for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { - output.set(result[i], j); - } - return output; - } - }; - - return AES128Cipher; -})(); - -var AES256Cipher = (function AES256CipherClosure() { - var rcon = new Uint8Array([ - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, - 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, - 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, - 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, - 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, - 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, - 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, - 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, - 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, - 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, - 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, - 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, - 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, - 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, - 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, - 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, - 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, - 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, - 0x74, 0xe8, 0xcb, 0x8d]); - - var s = new Uint8Array([ - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, - 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, - 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, - 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, - 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, - 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, - 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, - 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, - 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, - 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, - 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, - 0xb0, 0x54, 0xbb, 0x16]); - - var inv_s = new Uint8Array([ - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, - 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, - 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, - 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, - 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, - 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, - 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, - 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, - 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, - 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0c, 0x7d]); - - var mixCol = new Uint8Array(256); - for (var i = 0; i < 256; i++) { - if (i < 128) { - mixCol[i] = i << 1; - } else { - mixCol[i] = (i << 1) ^ 0x1b; - } - } - var mix = new Uint32Array([ - 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, - 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, - 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, - 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, - 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, - 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, - 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28, - 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012, - 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, - 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, - 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd, - 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7, - 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, - 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, - 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815, - 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f, - 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, - 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, - 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36, - 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c, - 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, - 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, - 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4, - 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e, - 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, - 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, - 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87, - 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd, - 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, - 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, - 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f, - 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55, - 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, - 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, - 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba, - 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480, - 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, - 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, - 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929, - 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713, - 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, - 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, - 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3]); - - function expandKey256(cipherKey) { - var b = 240, result = new Uint8Array(b); - var r = 1; - - result.set(cipherKey); - for (var j = 32, i = 1; j < b; ++i) { - if (j % 32 === 16) { - t1 = s[t1]; - t2 = s[t2]; - t3 = s[t3]; - t4 = s[t4]; - } else if (j % 32 === 0) { - // RotWord - var t1 = result[j - 3], t2 = result[j - 2], - t3 = result[j - 1], t4 = result[j - 4]; - // SubWord - t1 = s[t1]; - t2 = s[t2]; - t3 = s[t3]; - t4 = s[t4]; - // Rcon - t1 = t1 ^ r; - if ((r <<= 1) >= 256) { - r = (r ^ 0x1b) & 0xFF; - } - } - - for (var n = 0; n < 4; ++n) { - result[j] = (t1 ^= result[j - 32]); - j++; - result[j] = (t2 ^= result[j - 32]); - j++; - result[j] = (t3 ^= result[j - 32]); - j++; - result[j] = (t4 ^= result[j - 32]); - j++; - } - } - return result; - } - - function decrypt256(input, key) { - var state = new Uint8Array(16); - state.set(input); - var i, j, k; - var t, u, v; - // AddRoundKey - for (j = 0, k = 224; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - for (i = 13; i >= 1; --i) { - // InvShiftRows - t = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = t; - t = state[14]; - u = state[10]; - state[14] = state[6]; - state[10] = state[2]; - state[6] = t; - state[2] = u; - t = state[15]; - u = state[11]; - v = state[7]; - state[15] = state[3]; - state[11] = t; - state[7] = u; - state[3] = v; - // InvSubBytes - for (j = 0; j < 16; ++j) { - state[j] = inv_s[state[j]]; - } - // AddRoundKey - for (j = 0, k = i * 16; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - // InvMixColumns - for (j = 0; j < 16; j += 4) { - var s0 = mix[state[j]], s1 = mix[state[j + 1]], - s2 = mix[state[j + 2]], s3 = mix[state[j + 3]]; - t = (s0 ^ (s1 >>> 8) ^ (s1 << 24) ^ (s2 >>> 16) ^ (s2 << 16) ^ - (s3 >>> 24) ^ (s3 << 8)); - state[j] = (t >>> 24) & 0xFF; - state[j + 1] = (t >> 16) & 0xFF; - state[j + 2] = (t >> 8) & 0xFF; - state[j + 3] = t & 0xFF; - } - } - // InvShiftRows - t = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = t; - t = state[14]; - u = state[10]; - state[14] = state[6]; - state[10] = state[2]; - state[6] = t; - state[2] = u; - t = state[15]; - u = state[11]; - v = state[7]; - state[15] = state[3]; - state[11] = t; - state[7] = u; - state[3] = v; - for (j = 0; j < 16; ++j) { - // InvSubBytes - state[j] = inv_s[state[j]]; - // AddRoundKey - state[j] ^= key[j]; - } - return state; - } - - function encrypt256(input, key) { - var t, u, v, k; - var state = new Uint8Array(16); - state.set(input); - for (j = 0; j < 16; ++j) { - // AddRoundKey - state[j] ^= key[j]; - } - - for (i = 1; i < 14; i++) { - //SubBytes - for (j = 0; j < 16; ++j) { - state[j] = s[state[j]]; - } - //ShiftRows - v = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = v; - v = state[2]; - u = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = v; - state[14] = u; - v = state[3]; - u = state[7]; - t = state[11]; - state[3] = state[15]; - state[7] = v; - state[11] = u; - state[15] = t; - //MixColumns - for (var j = 0; j < 16; j += 4) { - var s0 = state[j + 0], s1 = state[j + 1]; - var s2 = state[j + 2], s3 = state[j + 3]; - t = s0 ^ s1 ^ s2 ^ s3; - state[j + 0] ^= t ^ mixCol[s0 ^ s1]; - state[j + 1] ^= t ^ mixCol[s1 ^ s2]; - state[j + 2] ^= t ^ mixCol[s2 ^ s3]; - state[j + 3] ^= t ^ mixCol[s3 ^ s0]; - } - //AddRoundKey - for (j = 0, k = i * 16; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - } - - //SubBytes - for (j = 0; j < 16; ++j) { - state[j] = s[state[j]]; - } - //ShiftRows - v = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = v; - v = state[2]; - u = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = v; - state[14] = u; - v = state[3]; - u = state[7]; - t = state[11]; - state[3] = state[15]; - state[7] = v; - state[11] = u; - state[15] = t; - //AddRoundKey - for (j = 0, k = 224; j < 16; ++j, ++k) { - state[j] ^= key[k]; - } - - return state; - - } - - function AES256Cipher(key) { - this.key = expandKey256(key); - this.buffer = new Uint8Array(16); - this.bufferPosition = 0; - } - - function decryptBlock2(data, finalize) { - var i, j, ii, sourceLength = data.length, - buffer = this.buffer, bufferLength = this.bufferPosition, - result = [], iv = this.iv; - - for (i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; - if (bufferLength < 16) { - continue; - } - // buffer is full, decrypting - var plain = decrypt256(buffer, this.key); - // xor-ing the IV vector to get plain text - for (j = 0; j < 16; ++j) { - plain[j] ^= iv[j]; - } - iv = buffer; - result.push(plain); - buffer = new Uint8Array(16); - bufferLength = 0; - } - // saving incomplete buffer - this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; - if (result.length === 0) { - return new Uint8Array([]); - } - // combining plain text blocks into one - var outputLength = 16 * result.length; - if (finalize) { - // undo a padding that is described in RFC 2898 - var lastBlock = result[result.length - 1]; - var psLen = lastBlock[15]; - if (psLen <= 16) { - for (i = 15, ii = 16 - psLen; i >= ii; --i) { - if (lastBlock[i] !== psLen) { - // Invalid padding, assume that the block has no padding. - psLen = 0; - break; - } - } - outputLength -= psLen; - result[result.length - 1] = lastBlock.subarray(0, 16 - psLen); - } - } - var output = new Uint8Array(outputLength); - for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { - output.set(result[i], j); - } - return output; - - } - - AES256Cipher.prototype = { - decryptBlock: function AES256Cipher_decryptBlock(data, finalize, iv) { - var i, sourceLength = data.length; - var buffer = this.buffer, bufferLength = this.bufferPosition; - // if not supplied an IV wait for IV values - // they are at the start of the stream - if (iv) { - this.iv = iv; - } else { - for (i = 0; bufferLength < 16 && - i < sourceLength; ++i, ++bufferLength) { - buffer[bufferLength] = data[i]; - } - if (bufferLength < 16) { - //need more data - this.bufferLength = bufferLength; - return new Uint8Array([]); - } - this.iv = buffer; - data = data.subarray(16); - } - this.buffer = new Uint8Array(16); - this.bufferLength = 0; - // starting decryption - this.decryptBlock = decryptBlock2; - return this.decryptBlock(data, finalize); - }, - encrypt: function AES256Cipher_encrypt(data, iv) { - var i, j, ii, sourceLength = data.length, - buffer = this.buffer, bufferLength = this.bufferPosition, - result = []; - if (!iv) { - iv = new Uint8Array(16); - } - for (i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; - if (bufferLength < 16) { - continue; - } - for (j = 0; j < 16; ++j) { - buffer[j] ^= iv[j]; - } - - // buffer is full, encrypting - var cipher = encrypt256(buffer, this.key); - this.iv = cipher; - result.push(cipher); - buffer = new Uint8Array(16); - bufferLength = 0; - } - // saving incomplete buffer - this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; - if (result.length === 0) { - return new Uint8Array([]); - } - // combining plain text blocks into one - var outputLength = 16 * result.length; - var output = new Uint8Array(outputLength); - for (i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { - output.set(result[i], j); - } - return output; - } - }; - - return AES256Cipher; -})(); - -var PDF17 = (function PDF17Closure() { - - function compareByteArrays(array1, array2) { - if (array1.length !== array2.length) { - return false; - } - for (var i = 0; i < array1.length; i++) { - if (array1[i] !== array2[i]) { - return false; - } - } - return true; - } - - function PDF17() { - } - - PDF17.prototype = { - checkOwnerPassword: function PDF17_checkOwnerPassword(password, - ownerValidationSalt, - userBytes, - ownerPassword) { - var hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerValidationSalt, password.length); - hashData.set(userBytes, password.length + ownerValidationSalt.length); - var result = calculateSHA256(hashData, 0, hashData.length); - return compareByteArrays(result, ownerPassword); - }, - checkUserPassword: function PDF17_checkUserPassword(password, - userValidationSalt, - userPassword) { - var hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userValidationSalt, password.length); - var result = calculateSHA256(hashData, 0, hashData.length); - return compareByteArrays(result, userPassword); - }, - getOwnerKey: function PDF17_getOwnerKey(password, ownerKeySalt, userBytes, - ownerEncryption) { - var hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerKeySalt, password.length); - hashData.set(userBytes, password.length + ownerKeySalt.length); - var key = calculateSHA256(hashData, 0, hashData.length); - var cipher = new AES256Cipher(key); - return cipher.decryptBlock(ownerEncryption, - false, - new Uint8Array(16)); - - }, - getUserKey: function PDF17_getUserKey(password, userKeySalt, - userEncryption) { - var hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userKeySalt, password.length); - //key is the decryption key for the UE string - var key = calculateSHA256(hashData, 0, hashData.length); - var cipher = new AES256Cipher(key); - return cipher.decryptBlock(userEncryption, - false, - new Uint8Array(16)); - } - }; - return PDF17; -})(); - -var PDF20 = (function PDF20Closure() { - - function concatArrays(array1, array2) { - var t = new Uint8Array(array1.length + array2.length); - t.set(array1, 0); - t.set(array2, array1.length); - return t; - } - - function calculatePDF20Hash(password, input, userBytes) { - //This refers to Algorithm 2.B as defined in ISO 32000-2 - var k = calculateSHA256(input, 0, input.length).subarray(0, 32); - var e = [0]; - var i = 0; - while (i < 64 || e[e.length - 1] > i - 32) { - var arrayLength = password.length + k.length + userBytes.length; - - var k1 = new Uint8Array(arrayLength * 64); - var array = concatArrays(password, k); - array = concatArrays(array, userBytes); - for (var j = 0, pos = 0; j < 64; j++, pos += arrayLength) { - k1.set(array, pos); - } - //AES128 CBC NO PADDING with - //first 16 bytes of k as the key and the second 16 as the iv. - var cipher = new AES128Cipher(k.subarray(0, 16)); - e = cipher.encrypt(k1, k.subarray(16, 32)); - //Now we have to take the first 16 bytes of an unsigned - //big endian integer... and compute the remainder - //modulo 3.... That is a fairly large number and - //JavaScript isn't going to handle that well... - //So we're using a trick that allows us to perform - //modulo math byte by byte - var remainder = 0; - for (var z = 0; z < 16; z++) { - remainder *= (256 % 3); - remainder %= 3; - remainder += ((e[z] >>> 0) % 3); - remainder %= 3; - } - if (remainder === 0) { - k = calculateSHA256(e, 0, e.length); - } - else if (remainder === 1) { - k = calculateSHA384(e, 0, e.length); - } - else if (remainder === 2) { - k = calculateSHA512(e, 0, e.length); - } - i++; - } - return k.subarray(0, 32); - } - - function PDF20() { - } - - function compareByteArrays(array1, array2) { - if (array1.length !== array2.length) { - return false; - } - for (var i = 0; i < array1.length; i++) { - if (array1[i] !== array2[i]) { - return false; - } - } - return true; - } - - PDF20.prototype = { - hash: function PDF20_hash(password, concatBytes, userBytes) { - return calculatePDF20Hash(password, concatBytes, userBytes); - }, - checkOwnerPassword: function PDF20_checkOwnerPassword(password, - ownerValidationSalt, - userBytes, - ownerPassword) { - var hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerValidationSalt, password.length); - hashData.set(userBytes, password.length + ownerValidationSalt.length); - var result = calculatePDF20Hash(password, hashData, userBytes); - return compareByteArrays(result, ownerPassword); - }, - checkUserPassword: function PDF20_checkUserPassword(password, - userValidationSalt, - userPassword) { - var hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userValidationSalt, password.length); - var result = calculatePDF20Hash(password, hashData, []); - return compareByteArrays(result, userPassword); - }, - getOwnerKey: function PDF20_getOwnerKey(password, ownerKeySalt, userBytes, - ownerEncryption) { - var hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerKeySalt, password.length); - hashData.set(userBytes, password.length + ownerKeySalt.length); - var key = calculatePDF20Hash(password, hashData, userBytes); - var cipher = new AES256Cipher(key); - return cipher.decryptBlock(ownerEncryption, - false, - new Uint8Array(16)); - - }, - getUserKey: function PDF20_getUserKey(password, userKeySalt, - userEncryption) { - var hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userKeySalt, password.length); - //key is the decryption key for the UE string - var key = calculatePDF20Hash(password, hashData, []); - var cipher = new AES256Cipher(key); - return cipher.decryptBlock(userEncryption, - false, - new Uint8Array(16)); - } - }; - return PDF20; -})(); - -var CipherTransform = (function CipherTransformClosure() { - function CipherTransform(stringCipherConstructor, streamCipherConstructor) { - this.stringCipherConstructor = stringCipherConstructor; - this.streamCipherConstructor = streamCipherConstructor; - } - - CipherTransform.prototype = { - createStream: function CipherTransform_createStream(stream, length) { - var cipher = new this.streamCipherConstructor(); - return new DecryptStream(stream, length, - function cipherTransformDecryptStream(data, finalize) { - return cipher.decryptBlock(data, finalize); - } - ); - }, - decryptString: function CipherTransform_decryptString(s) { - var cipher = new this.stringCipherConstructor(); - var data = stringToBytes(s); - data = cipher.decryptBlock(data, true); - return bytesToString(data); - } - }; - return CipherTransform; -})(); - -var CipherTransformFactory = (function CipherTransformFactoryClosure() { - var defaultPasswordBytes = new Uint8Array([ - 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, - 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, - 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, - 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A]); - - function createEncryptionKey20(revision, password, ownerPassword, - ownerValidationSalt, ownerKeySalt, uBytes, - userPassword, userValidationSalt, userKeySalt, - ownerEncryption, userEncryption, perms) { - if (password) { - var passwordLength = Math.min(127, password.length); - password = password.subarray(0, passwordLength); - } else { - password = []; - } - var pdfAlgorithm; - if (revision === 6) { - pdfAlgorithm = new PDF20(); - } else { - pdfAlgorithm = new PDF17(); - } - - if (pdfAlgorithm) { - if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, - userPassword)) { - return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption); - } else if (pdfAlgorithm.checkOwnerPassword(password, ownerValidationSalt, - uBytes, - ownerPassword)) { - return pdfAlgorithm.getOwnerKey(password, ownerKeySalt, uBytes, - ownerEncryption); - } - } - - return null; - } - - function prepareKeyData(fileId, password, ownerPassword, userPassword, - flags, revision, keyLength, encryptMetadata) { - var hashDataSize = 40 + ownerPassword.length + fileId.length; - var hashData = new Uint8Array(hashDataSize), i = 0, j, n; - if (password) { - n = Math.min(32, password.length); - for (; i < n; ++i) { - hashData[i] = password[i]; - } - } - j = 0; - while (i < 32) { - hashData[i++] = defaultPasswordBytes[j++]; - } - // as now the padded password in the hashData[0..i] - for (j = 0, n = ownerPassword.length; j < n; ++j) { - hashData[i++] = ownerPassword[j]; - } - hashData[i++] = flags & 0xFF; - hashData[i++] = (flags >> 8) & 0xFF; - hashData[i++] = (flags >> 16) & 0xFF; - hashData[i++] = (flags >>> 24) & 0xFF; - for (j = 0, n = fileId.length; j < n; ++j) { - hashData[i++] = fileId[j]; - } - if (revision >= 4 && !encryptMetadata) { - hashData[i++] = 0xFF; - hashData[i++] = 0xFF; - hashData[i++] = 0xFF; - hashData[i++] = 0xFF; - } - var hash = calculateMD5(hashData, 0, i); - var keyLengthInBytes = keyLength >> 3; - if (revision >= 3) { - for (j = 0; j < 50; ++j) { - hash = calculateMD5(hash, 0, keyLengthInBytes); - } - } - var encryptionKey = hash.subarray(0, keyLengthInBytes); - var cipher, checkData; - - if (revision >= 3) { - for (i = 0; i < 32; ++i) { - hashData[i] = defaultPasswordBytes[i]; - } - for (j = 0, n = fileId.length; j < n; ++j) { - hashData[i++] = fileId[j]; - } - cipher = new ARCFourCipher(encryptionKey); - checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); - n = encryptionKey.length; - var derivedKey = new Uint8Array(n), k; - for (j = 1; j <= 19; ++j) { - for (k = 0; k < n; ++k) { - derivedKey[k] = encryptionKey[k] ^ j; - } - cipher = new ARCFourCipher(derivedKey); - checkData = cipher.encryptBlock(checkData); - } - for (j = 0, n = checkData.length; j < n; ++j) { - if (userPassword[j] !== checkData[j]) { - return null; - } - } - } else { - cipher = new ARCFourCipher(encryptionKey); - checkData = cipher.encryptBlock(defaultPasswordBytes); - for (j = 0, n = checkData.length; j < n; ++j) { - if (userPassword[j] !== checkData[j]) { - return null; - } - } - } - return encryptionKey; - } - - function decodeUserPassword(password, ownerPassword, revision, keyLength) { - var hashData = new Uint8Array(32), i = 0, j, n; - n = Math.min(32, password.length); - for (; i < n; ++i) { - hashData[i] = password[i]; - } - j = 0; - while (i < 32) { - hashData[i++] = defaultPasswordBytes[j++]; - } - var hash = calculateMD5(hashData, 0, i); - var keyLengthInBytes = keyLength >> 3; - if (revision >= 3) { - for (j = 0; j < 50; ++j) { - hash = calculateMD5(hash, 0, hash.length); - } - } - - var cipher, userPassword; - if (revision >= 3) { - userPassword = ownerPassword; - var derivedKey = new Uint8Array(keyLengthInBytes), k; - for (j = 19; j >= 0; j--) { - for (k = 0; k < keyLengthInBytes; ++k) { - derivedKey[k] = hash[k] ^ j; - } - cipher = new ARCFourCipher(derivedKey); - userPassword = cipher.encryptBlock(userPassword); - } - } else { - cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes)); - userPassword = cipher.encryptBlock(ownerPassword); - } - return userPassword; - } - - var identityName = Name.get('Identity'); - - function CipherTransformFactory(dict, fileId, password) { - var filter = dict.get('Filter'); - if (!isName(filter) || filter.name !== 'Standard') { - error('unknown encryption method'); - } - this.dict = dict; - var algorithm = dict.get('V'); - if (!isInt(algorithm) || - (algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && - algorithm !== 5)) { - error('unsupported encryption algorithm'); - } - this.algorithm = algorithm; - var keyLength = dict.get('Length') || 40; - if (!isInt(keyLength) || - keyLength < 40 || (keyLength % 8) !== 0) { - error('invalid key length'); - } - - // prepare keys - var ownerPassword = stringToBytes(dict.get('O')).subarray(0, 32); - var userPassword = stringToBytes(dict.get('U')).subarray(0, 32); - var flags = dict.get('P'); - var revision = dict.get('R'); - // meaningful when V is 4 or 5 - var encryptMetadata = ((algorithm === 4 || algorithm === 5) && - dict.get('EncryptMetadata') !== false); - this.encryptMetadata = encryptMetadata; - - var fileIdBytes = stringToBytes(fileId); - var passwordBytes; - if (password) { - passwordBytes = stringToBytes(password); - } - - var encryptionKey; - if (algorithm !== 5) { - encryptionKey = prepareKeyData(fileIdBytes, passwordBytes, - ownerPassword, userPassword, flags, - revision, keyLength, encryptMetadata); - } - else { - var ownerValidationSalt = stringToBytes(dict.get('O')).subarray(32, 40); - var ownerKeySalt = stringToBytes(dict.get('O')).subarray(40, 48); - var uBytes = stringToBytes(dict.get('U')).subarray(0, 48); - var userValidationSalt = stringToBytes(dict.get('U')).subarray(32, 40); - var userKeySalt = stringToBytes(dict.get('U')).subarray(40, 48); - var ownerEncryption = stringToBytes(dict.get('OE')); - var userEncryption = stringToBytes(dict.get('UE')); - var perms = stringToBytes(dict.get('Perms')); - encryptionKey = - createEncryptionKey20(revision, passwordBytes, - ownerPassword, ownerValidationSalt, - ownerKeySalt, uBytes, - userPassword, userValidationSalt, - userKeySalt, ownerEncryption, - userEncryption, perms); - } - if (!encryptionKey && !password) { - throw new PasswordException('No password given', - PasswordResponses.NEED_PASSWORD); - } else if (!encryptionKey && password) { - // Attempting use the password as an owner password - var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword, - revision, keyLength); - encryptionKey = prepareKeyData(fileIdBytes, decodedPassword, - ownerPassword, userPassword, flags, - revision, keyLength, encryptMetadata); - } - - if (!encryptionKey) { - throw new PasswordException('Incorrect Password', - PasswordResponses.INCORRECT_PASSWORD); - } - - this.encryptionKey = encryptionKey; - - if (algorithm >= 4) { - this.cf = dict.get('CF'); - this.stmf = dict.get('StmF') || identityName; - this.strf = dict.get('StrF') || identityName; - this.eff = dict.get('EFF') || this.stmf; - } - } - - function buildObjectKey(num, gen, encryptionKey, isAes) { - var key = new Uint8Array(encryptionKey.length + 9), i, n; - for (i = 0, n = encryptionKey.length; i < n; ++i) { - key[i] = encryptionKey[i]; - } - key[i++] = num & 0xFF; - key[i++] = (num >> 8) & 0xFF; - key[i++] = (num >> 16) & 0xFF; - key[i++] = gen & 0xFF; - key[i++] = (gen >> 8) & 0xFF; - if (isAes) { - key[i++] = 0x73; - key[i++] = 0x41; - key[i++] = 0x6C; - key[i++] = 0x54; - } - var hash = calculateMD5(key, 0, i); - return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); - } - - function buildCipherConstructor(cf, name, num, gen, key) { - var cryptFilter = cf.get(name.name); - var cfm; - if (cryptFilter !== null && cryptFilter !== undefined) { - cfm = cryptFilter.get('CFM'); - } - if (!cfm || cfm.name === 'None') { - return function cipherTransformFactoryBuildCipherConstructorNone() { - return new NullCipher(); - }; - } - if ('V2' === cfm.name) { - return function cipherTransformFactoryBuildCipherConstructorV2() { - return new ARCFourCipher(buildObjectKey(num, gen, key, false)); - }; - } - if ('AESV2' === cfm.name) { - return function cipherTransformFactoryBuildCipherConstructorAESV2() { - return new AES128Cipher(buildObjectKey(num, gen, key, true)); - }; - } - if ('AESV3' === cfm.name) { - return function cipherTransformFactoryBuildCipherConstructorAESV3() { - return new AES256Cipher(key); - }; - } - error('Unknown crypto method'); - } - - CipherTransformFactory.prototype = { - createCipherTransform: - function CipherTransformFactory_createCipherTransform(num, gen) { - if (this.algorithm === 4 || this.algorithm === 5) { - return new CipherTransform( - buildCipherConstructor(this.cf, this.stmf, - num, gen, this.encryptionKey), - buildCipherConstructor(this.cf, this.strf, - num, gen, this.encryptionKey)); - } - // algorithms 1 and 2 - var key = buildObjectKey(num, gen, this.encryptionKey, false); - var cipherConstructor = function buildCipherCipherConstructor() { - return new ARCFourCipher(key); - }; - return new CipherTransform(cipherConstructor, cipherConstructor); - } - }; - - return CipherTransformFactory; -})(); - - -var PatternType = { - FUNCTION_BASED: 1, - AXIAL: 2, - RADIAL: 3, - FREE_FORM_MESH: 4, - LATTICE_FORM_MESH: 5, - COONS_PATCH_MESH: 6, - TENSOR_PATCH_MESH: 7 -}; - -var Pattern = (function PatternClosure() { - // Constructor should define this.getPattern - function Pattern() { - error('should not call Pattern constructor'); - } - - Pattern.prototype = { - // Input: current Canvas context - // Output: the appropriate fillStyle or strokeStyle - getPattern: function Pattern_getPattern(ctx) { - error('Should not call Pattern.getStyle: ' + ctx); - } - }; - - Pattern.parseShading = function Pattern_parseShading(shading, matrix, xref, - res) { - - var dict = isStream(shading) ? shading.dict : shading; - var type = dict.get('ShadingType'); - - try { - switch (type) { - case PatternType.AXIAL: - case PatternType.RADIAL: - // Both radial and axial shadings are handled by RadialAxial shading. - return new Shadings.RadialAxial(dict, matrix, xref, res); - case PatternType.FREE_FORM_MESH: - case PatternType.LATTICE_FORM_MESH: - case PatternType.COONS_PATCH_MESH: - case PatternType.TENSOR_PATCH_MESH: - return new Shadings.Mesh(shading, matrix, xref, res); - default: - throw new Error('Unknown PatternType: ' + type); - } - } catch (ex) { - if (ex instanceof MissingDataException) { - throw ex; - } - UnsupportedManager.notify(UNSUPPORTED_FEATURES.shadingPattern); - warn(ex); - return new Shadings.Dummy(); - } - }; - return Pattern; -})(); - -var Shadings = {}; - -// A small number to offset the first/last color stops so we can insert ones to -// support extend. Number.MIN_VALUE appears to be too small and breaks the -// extend. 1e-7 works in FF but chrome seems to use an even smaller sized number -// internally so we have to go bigger. -Shadings.SMALL_NUMBER = 1e-2; - -// Radial and axial shading have very similar implementations -// If needed, the implementations can be broken into two classes -Shadings.RadialAxial = (function RadialAxialClosure() { - function RadialAxial(dict, matrix, xref, res) { - this.matrix = matrix; - this.coordsArr = dict.get('Coords'); - this.shadingType = dict.get('ShadingType'); - this.type = 'Pattern'; - var cs = dict.get('ColorSpace', 'CS'); - cs = ColorSpace.parse(cs, xref, res); - this.cs = cs; - - var t0 = 0.0, t1 = 1.0; - if (dict.has('Domain')) { - var domainArr = dict.get('Domain'); - t0 = domainArr[0]; - t1 = domainArr[1]; - } - - var extendStart = false, extendEnd = false; - if (dict.has('Extend')) { - var extendArr = dict.get('Extend'); - extendStart = extendArr[0]; - extendEnd = extendArr[1]; - } - - if (this.shadingType === PatternType.RADIAL && - (!extendStart || !extendEnd)) { - // Radial gradient only currently works if either circle is fully within - // the other circle. - var x1 = this.coordsArr[0]; - var y1 = this.coordsArr[1]; - var r1 = this.coordsArr[2]; - var x2 = this.coordsArr[3]; - var y2 = this.coordsArr[4]; - var r2 = this.coordsArr[5]; - var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); - if (r1 <= r2 + distance && - r2 <= r1 + distance) { - warn('Unsupported radial gradient.'); - } - } - - this.extendStart = extendStart; - this.extendEnd = extendEnd; - - var fnObj = dict.get('Function'); - var fn = PDFFunction.parseArray(xref, fnObj); - - // 10 samples seems good enough for now, but probably won't work - // if there are sharp color changes. Ideally, we would implement - // the spec faithfully and add lossless optimizations. - var diff = t1 - t0; - var step = diff / 10; - - var colorStops = this.colorStops = []; - - // Protect against bad domains so we don't end up in an infinte loop below. - if (t0 >= t1 || step <= 0) { - // Acrobat doesn't seem to handle these cases so we'll ignore for - // now. - info('Bad shading domain.'); - return; - } - - var color = new Float32Array(cs.numComps), ratio = new Float32Array(1); - var rgbColor; - for (var i = t0; i <= t1; i += step) { - ratio[0] = i; - fn(ratio, 0, color, 0); - rgbColor = cs.getRgb(color, 0); - var cssColor = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]); - colorStops.push([(i - t0) / diff, cssColor]); - } - - var background = 'transparent'; - if (dict.has('Background')) { - rgbColor = cs.getRgb(dict.get('Background'), 0); - background = Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]); - } - - if (!extendStart) { - // Insert a color stop at the front and offset the first real color stop - // so it doesn't conflict with the one we insert. - colorStops.unshift([0, background]); - colorStops[1][0] += Shadings.SMALL_NUMBER; - } - if (!extendEnd) { - // Same idea as above in extendStart but for the end. - colorStops[colorStops.length - 1][0] -= Shadings.SMALL_NUMBER; - colorStops.push([1, background]); - } - - this.colorStops = colorStops; - } - - RadialAxial.prototype = { - getIR: function RadialAxial_getIR() { - var coordsArr = this.coordsArr; - var shadingType = this.shadingType; - var type, p0, p1, r0, r1; - if (shadingType === PatternType.AXIAL) { - p0 = [coordsArr[0], coordsArr[1]]; - p1 = [coordsArr[2], coordsArr[3]]; - r0 = null; - r1 = null; - type = 'axial'; - } else if (shadingType === PatternType.RADIAL) { - p0 = [coordsArr[0], coordsArr[1]]; - p1 = [coordsArr[3], coordsArr[4]]; - r0 = coordsArr[2]; - r1 = coordsArr[5]; - type = 'radial'; - } else { - error('getPattern type unknown: ' + shadingType); - } - - var matrix = this.matrix; - if (matrix) { - p0 = Util.applyTransform(p0, matrix); - p1 = Util.applyTransform(p1, matrix); - } - - return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1]; - } - }; - - return RadialAxial; -})(); - -// All mesh shading. For now, they will be presented as set of the triangles -// to be drawn on the canvas and rgb color for each vertex. -Shadings.Mesh = (function MeshClosure() { - function MeshStreamReader(stream, context) { - this.stream = stream; - this.context = context; - this.buffer = 0; - this.bufferLength = 0; - - var numComps = context.numComps; - this.tmpCompsBuf = new Float32Array(numComps); - var csNumComps = context.colorSpace; - this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : - this.tmpCompsBuf; - } - MeshStreamReader.prototype = { - get hasData() { - if (this.stream.end) { - return this.stream.pos < this.stream.end; - } - if (this.bufferLength > 0) { - return true; - } - var nextByte = this.stream.getByte(); - if (nextByte < 0) { - return false; - } - this.buffer = nextByte; - this.bufferLength = 8; - return true; - }, - readBits: function MeshStreamReader_readBits(n) { - var buffer = this.buffer; - var bufferLength = this.bufferLength; - if (n === 32) { - if (bufferLength === 0) { - return ((this.stream.getByte() << 24) | - (this.stream.getByte() << 16) | (this.stream.getByte() << 8) | - this.stream.getByte()) >>> 0; - } - buffer = (buffer << 24) | (this.stream.getByte() << 16) | - (this.stream.getByte() << 8) | this.stream.getByte(); - var nextByte = this.stream.getByte(); - this.buffer = nextByte & ((1 << bufferLength) - 1); - return ((buffer << (8 - bufferLength)) | - ((nextByte & 0xFF) >> bufferLength)) >>> 0; - } - if (n === 8 && bufferLength === 0) { - return this.stream.getByte(); - } - while (bufferLength < n) { - buffer = (buffer << 8) | this.stream.getByte(); - bufferLength += 8; - } - bufferLength -= n; - this.bufferLength = bufferLength; - this.buffer = buffer & ((1 << bufferLength) - 1); - return buffer >> bufferLength; - }, - align: function MeshStreamReader_align() { - this.buffer = 0; - this.bufferLength = 0; - }, - readFlag: function MeshStreamReader_readFlag() { - return this.readBits(this.context.bitsPerFlag); - }, - readCoordinate: function MeshStreamReader_readCoordinate() { - var bitsPerCoordinate = this.context.bitsPerCoordinate; - var xi = this.readBits(bitsPerCoordinate); - var yi = this.readBits(bitsPerCoordinate); - var decode = this.context.decode; - var scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : - 2.3283064365386963e-10; // 2 ^ -32 - return [ - xi * scale * (decode[1] - decode[0]) + decode[0], - yi * scale * (decode[3] - decode[2]) + decode[2] - ]; - }, - readComponents: function MeshStreamReader_readComponents() { - var numComps = this.context.numComps; - var bitsPerComponent = this.context.bitsPerComponent; - var scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : - 2.3283064365386963e-10; // 2 ^ -32 - var decode = this.context.decode; - var components = this.tmpCompsBuf; - for (var i = 0, j = 4; i < numComps; i++, j += 2) { - var ci = this.readBits(bitsPerComponent); - components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j]; - } - var color = this.tmpCsCompsBuf; - if (this.context.colorFn) { - this.context.colorFn(components, 0, color, 0); - } - return this.context.colorSpace.getRgb(color, 0); - } - }; - - function decodeType4Shading(mesh, reader) { - var coords = mesh.coords; - var colors = mesh.colors; - var operators = []; - var ps = []; // not maintaining cs since that will match ps - var verticesLeft = 0; // assuming we have all data to start a new triangle - while (reader.hasData) { - var f = reader.readFlag(); - var coord = reader.readCoordinate(); - var color = reader.readComponents(); - if (verticesLeft === 0) { // ignoring flags if we started a triangle - assert(0 <= f && f <= 2, 'Unknown type4 flag'); - switch (f) { - case 0: - verticesLeft = 3; - break; - case 1: - ps.push(ps[ps.length - 2], ps[ps.length - 1]); - verticesLeft = 1; - break; - case 2: - ps.push(ps[ps.length - 3], ps[ps.length - 1]); - verticesLeft = 1; - break; - } - operators.push(f); - } - ps.push(coords.length); - coords.push(coord); - colors.push(color); - verticesLeft--; - - reader.align(); - } - - var psPacked = new Int32Array(ps); - - mesh.figures.push({ - type: 'triangles', - coords: psPacked, - colors: psPacked - }); - } - - function decodeType5Shading(mesh, reader, verticesPerRow) { - var coords = mesh.coords; - var colors = mesh.colors; - var ps = []; // not maintaining cs since that will match ps - while (reader.hasData) { - var coord = reader.readCoordinate(); - var color = reader.readComponents(); - ps.push(coords.length); - coords.push(coord); - colors.push(color); - } - - var psPacked = new Int32Array(ps); - - mesh.figures.push({ - type: 'lattice', - coords: psPacked, - colors: psPacked, - verticesPerRow: verticesPerRow - }); - } - - var MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3; - var MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20; - - var TRIANGLE_DENSITY = 20; // count of triangles per entire mesh bounds - - var getB = (function getBClosure() { - function buildB(count) { - var lut = []; - for (var i = 0; i <= count; i++) { - var t = i / count, t_ = 1 - t; - lut.push(new Float32Array([t_ * t_ * t_, 3 * t * t_ * t_, - 3 * t * t * t_, t * t * t])); - } - return lut; - } - var cache = []; - return function getB(count) { - if (!cache[count]) { - cache[count] = buildB(count); - } - return cache[count]; - }; - })(); - - function buildFigureFromPatch(mesh, index) { - var figure = mesh.figures[index]; - assert(figure.type === 'patch', 'Unexpected patch mesh figure'); - - var coords = mesh.coords, colors = mesh.colors; - var pi = figure.coords; - var ci = figure.colors; - - var figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], - coords[pi[12]][0], coords[pi[15]][0]); - var figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], - coords[pi[12]][1], coords[pi[15]][1]); - var figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], - coords[pi[12]][0], coords[pi[15]][0]); - var figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], - coords[pi[12]][1], coords[pi[15]][1]); - var splitXBy = Math.ceil((figureMaxX - figureMinX) * TRIANGLE_DENSITY / - (mesh.bounds[2] - mesh.bounds[0])); - splitXBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT, - Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy)); - var splitYBy = Math.ceil((figureMaxY - figureMinY) * TRIANGLE_DENSITY / - (mesh.bounds[3] - mesh.bounds[1])); - splitYBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT, - Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy)); - - var verticesPerRow = splitXBy + 1; - var figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow); - var figureColors = new Int32Array((splitYBy + 1) * verticesPerRow); - var k = 0; - var cl = new Uint8Array(3), cr = new Uint8Array(3); - var c0 = colors[ci[0]], c1 = colors[ci[1]], - c2 = colors[ci[2]], c3 = colors[ci[3]]; - var bRow = getB(splitYBy), bCol = getB(splitXBy); - for (var row = 0; row <= splitYBy; row++) { - cl[0] = ((c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy) | 0; - cl[1] = ((c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy) | 0; - cl[2] = ((c0[2] * (splitYBy - row) + c2[2] * row) / splitYBy) | 0; - - cr[0] = ((c1[0] * (splitYBy - row) + c3[0] * row) / splitYBy) | 0; - cr[1] = ((c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy) | 0; - cr[2] = ((c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy) | 0; - - for (var col = 0; col <= splitXBy; col++, k++) { - if ((row === 0 || row === splitYBy) && - (col === 0 || col === splitXBy)) { - continue; - } - var x = 0, y = 0; - var q = 0; - for (var i = 0; i <= 3; i++) { - for (var j = 0; j <= 3; j++, q++) { - var m = bRow[row][i] * bCol[col][j]; - x += coords[pi[q]][0] * m; - y += coords[pi[q]][1] * m; - } - } - figureCoords[k] = coords.length; - coords.push([x, y]); - figureColors[k] = colors.length; - var newColor = new Uint8Array(3); - newColor[0] = ((cl[0] * (splitXBy - col) + cr[0] * col) / splitXBy) | 0; - newColor[1] = ((cl[1] * (splitXBy - col) + cr[1] * col) / splitXBy) | 0; - newColor[2] = ((cl[2] * (splitXBy - col) + cr[2] * col) / splitXBy) | 0; - colors.push(newColor); - } - } - figureCoords[0] = pi[0]; - figureColors[0] = ci[0]; - figureCoords[splitXBy] = pi[3]; - figureColors[splitXBy] = ci[1]; - figureCoords[verticesPerRow * splitYBy] = pi[12]; - figureColors[verticesPerRow * splitYBy] = ci[2]; - figureCoords[verticesPerRow * splitYBy + splitXBy] = pi[15]; - figureColors[verticesPerRow * splitYBy + splitXBy] = ci[3]; - - mesh.figures[index] = { - type: 'lattice', - coords: figureCoords, - colors: figureColors, - verticesPerRow: verticesPerRow - }; - } - - function decodeType6Shading(mesh, reader) { - // A special case of Type 7. The p11, p12, p21, p22 automatically filled - var coords = mesh.coords; - var colors = mesh.colors; - var ps = new Int32Array(16); // p00, p10, ..., p30, p01, ..., p33 - var cs = new Int32Array(4); // c00, c30, c03, c33 - while (reader.hasData) { - var f = reader.readFlag(); - assert(0 <= f && f <= 3, 'Unknown type6 flag'); - var i, ii; - var pi = coords.length; - for (i = 0, ii = (f !== 0 ? 8 : 12); i < ii; i++) { - coords.push(reader.readCoordinate()); - } - var ci = colors.length; - for (i = 0, ii = (f !== 0 ? 2 : 4); i < ii; i++) { - colors.push(reader.readComponents()); - } - var tmp1, tmp2, tmp3, tmp4; - switch (f) { - case 0: - ps[12] = pi + 3; ps[13] = pi + 4; ps[14] = pi + 5; ps[15] = pi + 6; - ps[ 8] = pi + 2; /* values for 5, 6, 9, 10 are */ ps[11] = pi + 7; - ps[ 4] = pi + 1; /* calculated below */ ps[ 7] = pi + 8; - ps[ 0] = pi; ps[ 1] = pi + 11; ps[ 2] = pi + 10; ps[ 3] = pi + 9; - cs[2] = ci + 1; cs[3] = ci + 2; - cs[0] = ci; cs[1] = ci + 3; - break; - case 1: - tmp1 = ps[12]; tmp2 = ps[13]; tmp3 = ps[14]; tmp4 = ps[15]; - ps[12] = pi + 5; ps[13] = pi + 4; ps[14] = pi + 3; ps[15] = pi + 2; - ps[ 8] = pi + 6; /* values for 5, 6, 9, 10 are */ ps[11] = pi + 1; - ps[ 4] = pi + 7; /* calculated below */ ps[ 7] = pi; - ps[ 0] = tmp1; ps[ 1] = tmp2; ps[ 2] = tmp3; ps[ 3] = tmp4; - tmp1 = cs[2]; tmp2 = cs[3]; - cs[2] = ci + 1; cs[3] = ci; - cs[0] = tmp1; cs[1] = tmp2; - break; - case 2: - ps[12] = ps[15]; ps[13] = pi + 7; ps[14] = pi + 6; ps[15] = pi + 5; - ps[ 8] = ps[11]; /* values for 5, 6, 9, 10 are */ ps[11] = pi + 4; - ps[ 4] = ps[7]; /* calculated below */ ps[ 7] = pi + 3; - ps[ 0] = ps[3]; ps[ 1] = pi; ps[ 2] = pi + 1; ps[ 3] = pi + 2; - cs[2] = cs[3]; cs[3] = ci + 1; - cs[0] = cs[1]; cs[1] = ci; - break; - case 3: - ps[12] = ps[0]; ps[13] = ps[1]; ps[14] = ps[2]; ps[15] = ps[3]; - ps[ 8] = pi; /* values for 5, 6, 9, 10 are */ ps[11] = pi + 7; - ps[ 4] = pi + 1; /* calculated below */ ps[ 7] = pi + 6; - ps[ 0] = pi + 2; ps[ 1] = pi + 3; ps[ 2] = pi + 4; ps[ 3] = pi + 5; - cs[2] = cs[0]; cs[3] = cs[1]; - cs[0] = ci; cs[1] = ci + 1; - break; - } - // set p11, p12, p21, p22 - ps[5] = coords.length; - coords.push([ - (-4 * coords[ps[0]][0] - coords[ps[15]][0] + - 6 * (coords[ps[4]][0] + coords[ps[1]][0]) - - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + - 3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9, - (-4 * coords[ps[0]][1] - coords[ps[15]][1] + - 6 * (coords[ps[4]][1] + coords[ps[1]][1]) - - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + - 3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9 - ]); - ps[6] = coords.length; - coords.push([ - (-4 * coords[ps[3]][0] - coords[ps[12]][0] + - 6 * (coords[ps[2]][0] + coords[ps[7]][0]) - - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + - 3 * (coords[ps[4]][0] + coords[ps[14]][0])) / 9, - (-4 * coords[ps[3]][1] - coords[ps[12]][1] + - 6 * (coords[ps[2]][1] + coords[ps[7]][1]) - - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + - 3 * (coords[ps[4]][1] + coords[ps[14]][1])) / 9 - ]); - ps[9] = coords.length; - coords.push([ - (-4 * coords[ps[12]][0] - coords[ps[3]][0] + - 6 * (coords[ps[8]][0] + coords[ps[13]][0]) - - 2 * (coords[ps[0]][0] + coords[ps[15]][0]) + - 3 * (coords[ps[11]][0] + coords[ps[1]][0])) / 9, - (-4 * coords[ps[12]][1] - coords[ps[3]][1] + - 6 * (coords[ps[8]][1] + coords[ps[13]][1]) - - 2 * (coords[ps[0]][1] + coords[ps[15]][1]) + - 3 * (coords[ps[11]][1] + coords[ps[1]][1])) / 9 - ]); - ps[10] = coords.length; - coords.push([ - (-4 * coords[ps[15]][0] - coords[ps[0]][0] + - 6 * (coords[ps[11]][0] + coords[ps[14]][0]) - - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + - 3 * (coords[ps[2]][0] + coords[ps[8]][0])) / 9, - (-4 * coords[ps[15]][1] - coords[ps[0]][1] + - 6 * (coords[ps[11]][1] + coords[ps[14]][1]) - - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + - 3 * (coords[ps[2]][1] + coords[ps[8]][1])) / 9 - ]); - mesh.figures.push({ - type: 'patch', - coords: new Int32Array(ps), // making copies of ps and cs - colors: new Int32Array(cs) - }); - } - } - - function decodeType7Shading(mesh, reader) { - var coords = mesh.coords; - var colors = mesh.colors; - var ps = new Int32Array(16); // p00, p10, ..., p30, p01, ..., p33 - var cs = new Int32Array(4); // c00, c30, c03, c33 - while (reader.hasData) { - var f = reader.readFlag(); - assert(0 <= f && f <= 3, 'Unknown type7 flag'); - var i, ii; - var pi = coords.length; - for (i = 0, ii = (f !== 0 ? 12 : 16); i < ii; i++) { - coords.push(reader.readCoordinate()); - } - var ci = colors.length; - for (i = 0, ii = (f !== 0 ? 2 : 4); i < ii; i++) { - colors.push(reader.readComponents()); - } - var tmp1, tmp2, tmp3, tmp4; - switch (f) { - case 0: - ps[12] = pi + 3; ps[13] = pi + 4; ps[14] = pi + 5; ps[15] = pi + 6; - ps[ 8] = pi + 2; ps[ 9] = pi + 13; ps[10] = pi + 14; ps[11] = pi + 7; - ps[ 4] = pi + 1; ps[ 5] = pi + 12; ps[ 6] = pi + 15; ps[ 7] = pi + 8; - ps[ 0] = pi; ps[ 1] = pi + 11; ps[ 2] = pi + 10; ps[ 3] = pi + 9; - cs[2] = ci + 1; cs[3] = ci + 2; - cs[0] = ci; cs[1] = ci + 3; - break; - case 1: - tmp1 = ps[12]; tmp2 = ps[13]; tmp3 = ps[14]; tmp4 = ps[15]; - ps[12] = pi + 5; ps[13] = pi + 4; ps[14] = pi + 3; ps[15] = pi + 2; - ps[ 8] = pi + 6; ps[ 9] = pi + 11; ps[10] = pi + 10; ps[11] = pi + 1; - ps[ 4] = pi + 7; ps[ 5] = pi + 8; ps[ 6] = pi + 9; ps[ 7] = pi; - ps[ 0] = tmp1; ps[ 1] = tmp2; ps[ 2] = tmp3; ps[ 3] = tmp4; - tmp1 = cs[2]; tmp2 = cs[3]; - cs[2] = ci + 1; cs[3] = ci; - cs[0] = tmp1; cs[1] = tmp2; - break; - case 2: - ps[12] = ps[15]; ps[13] = pi + 7; ps[14] = pi + 6; ps[15] = pi + 5; - ps[ 8] = ps[11]; ps[ 9] = pi + 8; ps[10] = pi + 11; ps[11] = pi + 4; - ps[ 4] = ps[7]; ps[ 5] = pi + 9; ps[ 6] = pi + 10; ps[ 7] = pi + 3; - ps[ 0] = ps[3]; ps[ 1] = pi; ps[ 2] = pi + 1; ps[ 3] = pi + 2; - cs[2] = cs[3]; cs[3] = ci + 1; - cs[0] = cs[1]; cs[1] = ci; - break; - case 3: - ps[12] = ps[0]; ps[13] = ps[1]; ps[14] = ps[2]; ps[15] = ps[3]; - ps[ 8] = pi; ps[ 9] = pi + 9; ps[10] = pi + 8; ps[11] = pi + 7; - ps[ 4] = pi + 1; ps[ 5] = pi + 10; ps[ 6] = pi + 11; ps[ 7] = pi + 6; - ps[ 0] = pi + 2; ps[ 1] = pi + 3; ps[ 2] = pi + 4; ps[ 3] = pi + 5; - cs[2] = cs[0]; cs[3] = cs[1]; - cs[0] = ci; cs[1] = ci + 1; - break; - } - mesh.figures.push({ - type: 'patch', - coords: new Int32Array(ps), // making copies of ps and cs - colors: new Int32Array(cs) - }); - } - } - - function updateBounds(mesh) { - var minX = mesh.coords[0][0], minY = mesh.coords[0][1], - maxX = minX, maxY = minY; - for (var i = 1, ii = mesh.coords.length; i < ii; i++) { - var x = mesh.coords[i][0], y = mesh.coords[i][1]; - minX = minX > x ? x : minX; - minY = minY > y ? y : minY; - maxX = maxX < x ? x : maxX; - maxY = maxY < y ? y : maxY; - } - mesh.bounds = [minX, minY, maxX, maxY]; - } - - function packData(mesh) { - var i, ii, j, jj; - - var coords = mesh.coords; - var coordsPacked = new Float32Array(coords.length * 2); - for (i = 0, j = 0, ii = coords.length; i < ii; i++) { - var xy = coords[i]; - coordsPacked[j++] = xy[0]; - coordsPacked[j++] = xy[1]; - } - mesh.coords = coordsPacked; - - var colors = mesh.colors; - var colorsPacked = new Uint8Array(colors.length * 3); - for (i = 0, j = 0, ii = colors.length; i < ii; i++) { - var c = colors[i]; - colorsPacked[j++] = c[0]; - colorsPacked[j++] = c[1]; - colorsPacked[j++] = c[2]; - } - mesh.colors = colorsPacked; - - var figures = mesh.figures; - for (i = 0, ii = figures.length; i < ii; i++) { - var figure = figures[i], ps = figure.coords, cs = figure.colors; - for (j = 0, jj = ps.length; j < jj; j++) { - ps[j] *= 2; - cs[j] *= 3; - } - } - } - - function Mesh(stream, matrix, xref, res) { - assert(isStream(stream), 'Mesh data is not a stream'); - var dict = stream.dict; - this.matrix = matrix; - this.shadingType = dict.get('ShadingType'); - this.type = 'Pattern'; - this.bbox = dict.get('BBox'); - var cs = dict.get('ColorSpace', 'CS'); - cs = ColorSpace.parse(cs, xref, res); - this.cs = cs; - this.background = dict.has('Background') ? - cs.getRgb(dict.get('Background'), 0) : null; - - var fnObj = dict.get('Function'); - var fn = fnObj ? PDFFunction.parseArray(xref, fnObj) : null; - - this.coords = []; - this.colors = []; - this.figures = []; - - var decodeContext = { - bitsPerCoordinate: dict.get('BitsPerCoordinate'), - bitsPerComponent: dict.get('BitsPerComponent'), - bitsPerFlag: dict.get('BitsPerFlag'), - decode: dict.get('Decode'), - colorFn: fn, - colorSpace: cs, - numComps: fn ? 1 : cs.numComps - }; - var reader = new MeshStreamReader(stream, decodeContext); - - var patchMesh = false; - switch (this.shadingType) { - case PatternType.FREE_FORM_MESH: - decodeType4Shading(this, reader); - break; - case PatternType.LATTICE_FORM_MESH: - var verticesPerRow = dict.get('VerticesPerRow') | 0; - assert(verticesPerRow >= 2, 'Invalid VerticesPerRow'); - decodeType5Shading(this, reader, verticesPerRow); - break; - case PatternType.COONS_PATCH_MESH: - decodeType6Shading(this, reader); - patchMesh = true; - break; - case PatternType.TENSOR_PATCH_MESH: - decodeType7Shading(this, reader); - patchMesh = true; - break; - default: - error('Unsupported mesh type.'); - break; - } - - if (patchMesh) { - // dirty bounds calculation for determining, how dense shall be triangles - updateBounds(this); - for (var i = 0, ii = this.figures.length; i < ii; i++) { - buildFigureFromPatch(this, i); - } - } - // calculate bounds - updateBounds(this); - - packData(this); - } - - Mesh.prototype = { - getIR: function Mesh_getIR() { - return ['Mesh', this.shadingType, this.coords, this.colors, this.figures, - this.bounds, this.matrix, this.bbox, this.background]; - } - }; - - return Mesh; -})(); - -Shadings.Dummy = (function DummyClosure() { - function Dummy() { - this.type = 'Pattern'; - } - - Dummy.prototype = { - getIR: function Dummy_getIR() { - return ['Dummy']; - } - }; - return Dummy; -})(); - -function getTilingPatternIR(operatorList, dict, args) { - var matrix = dict.get('Matrix'); - var bbox = dict.get('BBox'); - var xstep = dict.get('XStep'); - var ystep = dict.get('YStep'); - var paintType = dict.get('PaintType'); - var tilingType = dict.get('TilingType'); - - return [ - 'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, - paintType, tilingType - ]; -} - - -var PartialEvaluator = (function PartialEvaluatorClosure() { - function PartialEvaluator(pdfManager, xref, handler, pageIndex, - uniquePrefix, idCounters, fontCache) { - this.pdfManager = pdfManager; - this.xref = xref; - this.handler = handler; - this.pageIndex = pageIndex; - this.uniquePrefix = uniquePrefix; - this.idCounters = idCounters; - this.fontCache = fontCache; - } - - // Trying to minimize Date.now() usage and check every 100 time - var TIME_SLOT_DURATION_MS = 20; - var CHECK_TIME_EVERY = 100; - function TimeSlotManager() { - this.reset(); - } - TimeSlotManager.prototype = { - check: function TimeSlotManager_check() { - if (++this.checked < CHECK_TIME_EVERY) { - return false; - } - this.checked = 0; - return this.endTime <= Date.now(); - }, - reset: function TimeSlotManager_reset() { - this.endTime = Date.now() + TIME_SLOT_DURATION_MS; - this.checked = 0; - } - }; - - var deferred = Promise.resolve(); - - var TILING_PATTERN = 1, SHADING_PATTERN = 2; - - PartialEvaluator.prototype = { - hasBlendModes: function PartialEvaluator_hasBlendModes(resources) { - if (!isDict(resources)) { - return false; - } - - var processed = Object.create(null); - if (resources.objId) { - processed[resources.objId] = true; - } - - var nodes = [resources]; - while (nodes.length) { - var key; - var node = nodes.shift(); - // First check the current resources for blend modes. - var graphicStates = node.get('ExtGState'); - if (isDict(graphicStates)) { - graphicStates = graphicStates.getAll(); - for (key in graphicStates) { - var graphicState = graphicStates[key]; - var bm = graphicState['BM']; - if (isName(bm) && bm.name !== 'Normal') { - return true; - } - } - } - // Descend into the XObjects to look for more resources and blend modes. - var xObjects = node.get('XObject'); - if (!isDict(xObjects)) { - continue; - } - xObjects = xObjects.getAll(); - for (key in xObjects) { - var xObject = xObjects[key]; - if (!isStream(xObject)) { - continue; - } - if (xObject.dict.objId) { - if (processed[xObject.dict.objId]) { - // stream has objId and is processed already - continue; - } - processed[xObject.dict.objId] = true; - } - var xResources = xObject.dict.get('Resources'); - // Checking objId to detect an infinite loop. - if (isDict(xResources) && - (!xResources.objId || !processed[xResources.objId])) { - nodes.push(xResources); - if (xResources.objId) { - processed[xResources.objId] = true; - } - } - } - } - return false; - }, - - buildFormXObject: function PartialEvaluator_buildFormXObject(resources, - xobj, smask, - operatorList, - initialState) { - var matrix = xobj.dict.get('Matrix'); - var bbox = xobj.dict.get('BBox'); - var group = xobj.dict.get('Group'); - if (group) { - var groupOptions = { - matrix: matrix, - bbox: bbox, - smask: smask, - isolated: false, - knockout: false - }; - - var groupSubtype = group.get('S'); - var colorSpace; - if (isName(groupSubtype) && groupSubtype.name === 'Transparency') { - groupOptions.isolated = (group.get('I') || false); - groupOptions.knockout = (group.get('K') || false); - colorSpace = (group.has('CS') ? - ColorSpace.parse(group.get('CS'), this.xref, resources) : null); - } - - if (smask && smask.backdrop) { - colorSpace = colorSpace || ColorSpace.singletons.rgb; - smask.backdrop = colorSpace.getRgb(smask.backdrop, 0); - } - - operatorList.addOp(OPS.beginGroup, [groupOptions]); - } - - operatorList.addOp(OPS.paintFormXObjectBegin, [matrix, bbox]); - - return this.getOperatorList(xobj, - (xobj.dict.get('Resources') || resources), operatorList, initialState). - then(function () { - operatorList.addOp(OPS.paintFormXObjectEnd, []); - - if (group) { - operatorList.addOp(OPS.endGroup, [groupOptions]); - } - }); - }, - - buildPaintImageXObject: - function PartialEvaluator_buildPaintImageXObject(resources, image, - inline, operatorList, - cacheKey, imageCache) { - var self = this; - var dict = image.dict; - var w = dict.get('Width', 'W'); - var h = dict.get('Height', 'H'); - - if (!(w && isNum(w)) || !(h && isNum(h))) { - warn('Image dimensions are missing, or not numbers.'); - return; - } - if (PDFJS.maxImageSize !== -1 && w * h > PDFJS.maxImageSize) { - warn('Image exceeded maximum allowed size and was removed.'); - return; - } - - var imageMask = (dict.get('ImageMask', 'IM') || false); - var imgData, args; - if (imageMask) { - // This depends on a tmpCanvas being filled with the - // current fillStyle, such that processing the pixel - // data can't be done here. Instead of creating a - // complete PDFImage, only read the information needed - // for later. - - var width = dict.get('Width', 'W'); - var height = dict.get('Height', 'H'); - var bitStrideLength = (width + 7) >> 3; - var imgArray = image.getBytes(bitStrideLength * height); - var decode = dict.get('Decode', 'D'); - var inverseDecode = (!!decode && decode[0] > 0); - - imgData = PDFImage.createMask(imgArray, width, height, - image instanceof DecodeStream, - inverseDecode); - imgData.cached = true; - args = [imgData]; - operatorList.addOp(OPS.paintImageMaskXObject, args); - if (cacheKey) { - imageCache[cacheKey] = { - fn: OPS.paintImageMaskXObject, - args: args - }; - } - return; - } - - var softMask = (dict.get('SMask', 'SM') || false); - var mask = (dict.get('Mask') || false); - - var SMALL_IMAGE_DIMENSIONS = 200; - // Inlining small images into the queue as RGB data - if (inline && !softMask && !mask && !(image instanceof JpegStream) && - (w + h) < SMALL_IMAGE_DIMENSIONS) { - var imageObj = new PDFImage(this.xref, resources, image, - inline, null, null); - // We force the use of RGBA_32BPP images here, because we can't handle - // any other kind. - imgData = imageObj.createImageData(/* forceRGBA = */ true); - operatorList.addOp(OPS.paintInlineImageXObject, [imgData]); - return; - } - - // If there is no imageMask, create the PDFImage and a lot - // of image processing can be done here. - var uniquePrefix = (this.uniquePrefix || ''); - var objId = 'img_' + uniquePrefix + (++this.idCounters.obj); - operatorList.addDependency(objId); - args = [objId, w, h]; - - if (!softMask && !mask && image instanceof JpegStream && - image.isNativelySupported(this.xref, resources)) { - // These JPEGs don't need any more processing so we can just send it. - operatorList.addOp(OPS.paintJpegXObject, args); - this.handler.send('obj', - [objId, this.pageIndex, 'JpegStream', image.getIR()]); - return; - } - - PDFImage.buildImage(self.handler, self.xref, resources, image, inline). - then(function(imageObj) { - var imgData = imageObj.createImageData(/* forceRGBA = */ false); - self.handler.send('obj', [objId, self.pageIndex, 'Image', imgData], - [imgData.data.buffer]); - }).then(undefined, function (reason) { - warn('Unable to decode image: ' + reason); - self.handler.send('obj', [objId, self.pageIndex, 'Image', null]); - }); - - operatorList.addOp(OPS.paintImageXObject, args); - if (cacheKey) { - imageCache[cacheKey] = { - fn: OPS.paintImageXObject, - args: args - }; - } - }, - - handleSMask: function PartialEvaluator_handleSmask(smask, resources, - operatorList, - stateManager) { - var smaskContent = smask.get('G'); - var smaskOptions = { - subtype: smask.get('S').name, - backdrop: smask.get('BC') - }; - return this.buildFormXObject(resources, smaskContent, smaskOptions, - operatorList, stateManager.state.clone()); - }, - - handleTilingType: - function PartialEvaluator_handleTilingType(fn, args, resources, - pattern, patternDict, - operatorList) { - // Create an IR of the pattern code. - var tilingOpList = new OperatorList(); - return this.getOperatorList(pattern, - (patternDict.get('Resources') || resources), tilingOpList). - then(function () { - // Add the dependencies to the parent operator list so they are - // resolved before sub operator list is executed synchronously. - operatorList.addDependencies(tilingOpList.dependencies); - operatorList.addOp(fn, getTilingPatternIR({ - fnArray: tilingOpList.fnArray, - argsArray: tilingOpList.argsArray - }, patternDict, args)); - }); - }, - - handleSetFont: - function PartialEvaluator_handleSetFont(resources, fontArgs, fontRef, - operatorList, state) { - // TODO(mack): Not needed? - var fontName; - if (fontArgs) { - fontArgs = fontArgs.slice(); - fontName = fontArgs[0].name; - } - - var self = this; - return this.loadFont(fontName, fontRef, this.xref, resources).then( - function (translated) { - if (!translated.font.isType3Font) { - return translated; - } - return translated.loadType3Data(self, resources, operatorList).then( - function () { - return translated; - }); - }).then(function (translated) { - state.font = translated.font; - translated.send(self.handler); - return translated.loadedName; - }); - }, - - handleText: function PartialEvaluator_handleText(chars, state) { - var font = state.font; - var glyphs = font.charsToGlyphs(chars); - var isAddToPathSet = !!(state.textRenderingMode & - TextRenderingMode.ADD_TO_PATH_FLAG); - if (font.data && (isAddToPathSet || PDFJS.disableFontFace)) { - var buildPath = function (fontChar) { - if (!font.renderer.hasBuiltPath(fontChar)) { - var path = font.renderer.getPathJs(fontChar); - this.handler.send('commonobj', [ - font.loadedName + '_path_' + fontChar, - 'FontPath', - path - ]); - } - }.bind(this); - - for (var i = 0, ii = glyphs.length; i < ii; i++) { - var glyph = glyphs[i]; - if (glyph === null) { - continue; - } - buildPath(glyph.fontChar); - - // If the glyph has an accent we need to build a path for its - // fontChar too, otherwise CanvasGraphics_paintChar will fail. - var accent = glyph.accent; - if (accent && accent.fontChar) { - buildPath(accent.fontChar); - } - } - } - - return glyphs; - }, - - setGState: function PartialEvaluator_setGState(resources, gState, - operatorList, xref, - stateManager) { - // This array holds the converted/processed state data. - var gStateObj = []; - var gStateMap = gState.map; - var self = this; - var promise = Promise.resolve(); - for (var key in gStateMap) { - var value = gStateMap[key]; - switch (key) { - case 'Type': - break; - case 'LW': - case 'LC': - case 'LJ': - case 'ML': - case 'D': - case 'RI': - case 'FL': - case 'CA': - case 'ca': - gStateObj.push([key, value]); - break; - case 'Font': - promise = promise.then(function () { - return self.handleSetFont(resources, null, value[0], - operatorList, stateManager.state). - then(function (loadedName) { - operatorList.addDependency(loadedName); - gStateObj.push([key, [loadedName, value[1]]]); - }); - }); - break; - case 'BM': - gStateObj.push([key, value]); - break; - case 'SMask': - if (isName(value) && value.name === 'None') { - gStateObj.push([key, false]); - break; - } - var dict = xref.fetchIfRef(value); - if (isDict(dict)) { - promise = promise.then(function () { - return self.handleSMask(dict, resources, operatorList, - stateManager); - }); - gStateObj.push([key, true]); - } else { - warn('Unsupported SMask type'); - } - - break; - // Only generate info log messages for the following since - // they are unlikely to have a big impact on the rendering. - case 'OP': - case 'op': - case 'OPM': - case 'BG': - case 'BG2': - case 'UCR': - case 'UCR2': - case 'TR': - case 'TR2': - case 'HT': - case 'SM': - case 'SA': - case 'AIS': - case 'TK': - // TODO implement these operators. - info('graphic state operator ' + key); - break; - default: - info('Unknown graphic state operator ' + key); - break; - } - } - return promise.then(function () { - if (gStateObj.length >= 0) { - operatorList.addOp(OPS.setGState, [gStateObj]); - } - }); - }, - - loadFont: function PartialEvaluator_loadFont(fontName, font, xref, - resources) { - - function errorFont() { - return Promise.resolve(new TranslatedFont('g_font_error', - new ErrorFont('Font ' + fontName + ' is not available'), font)); - } - var fontRef; - if (font) { // Loading by ref. - assert(isRef(font)); - fontRef = font; - } else { // Loading by name. - var fontRes = resources.get('Font'); - if (fontRes) { - fontRef = fontRes.getRaw(fontName); - } else { - warn('fontRes not available'); - return errorFont(); - } - } - if (!fontRef) { - warn('fontRef not available'); - return errorFont(); - } - - if (this.fontCache.has(fontRef)) { - return this.fontCache.get(fontRef); - } - - font = xref.fetchIfRef(fontRef); - if (!isDict(font)) { - return errorFont(); - } - - // We are holding font.translated references just for fontRef that are not - // dictionaries (Dict). See explanation below. - if (font.translated) { - return font.translated; - } - - var fontCapability = createPromiseCapability(); - - var preEvaluatedFont = this.preEvaluateFont(font, xref); - var descriptor = preEvaluatedFont.descriptor; - var fontID = fontRef.num + '_' + fontRef.gen; - if (isDict(descriptor)) { - if (!descriptor.fontAliases) { - descriptor.fontAliases = Object.create(null); - } - - var fontAliases = descriptor.fontAliases; - var hash = preEvaluatedFont.hash; - if (fontAliases[hash]) { - var aliasFontRef = fontAliases[hash].aliasRef; - if (aliasFontRef && this.fontCache.has(aliasFontRef)) { - this.fontCache.putAlias(fontRef, aliasFontRef); - return this.fontCache.get(fontRef); - } - } - - if (!fontAliases[hash]) { - fontAliases[hash] = { - fontID: Font.getFontID() - }; - } - - fontAliases[hash].aliasRef = fontRef; - fontID = fontAliases[hash].fontID; - } - - // Workaround for bad PDF generators that don't reference fonts - // properly, i.e. by not using an object identifier. - // Check if the fontRef is a Dict (as opposed to a standard object), - // in which case we don't cache the font and instead reference it by - // fontName in font.loadedName below. - var fontRefIsDict = isDict(fontRef); - if (!fontRefIsDict) { - this.fontCache.put(fontRef, fontCapability.promise); - } - - // Keep track of each font we translated so the caller can - // load them asynchronously before calling display on a page. - font.loadedName = 'g_font_' + (fontRefIsDict ? - fontName.replace(/\W/g, '') : fontID); - - font.translated = fontCapability.promise; - - // TODO move promises into translate font - var translatedPromise; - try { - translatedPromise = Promise.resolve( - this.translateFont(preEvaluatedFont, xref)); - } catch (e) { - translatedPromise = Promise.reject(e); - } - - translatedPromise.then(function (translatedFont) { - if (translatedFont.fontType !== undefined) { - var xrefFontStats = xref.stats.fontTypes; - xrefFontStats[translatedFont.fontType] = true; - } - - fontCapability.resolve(new TranslatedFont(font.loadedName, - translatedFont, font)); - }, function (reason) { - // TODO fontCapability.reject? - UnsupportedManager.notify(UNSUPPORTED_FEATURES.font); - - try { - // error, but it's still nice to have font type reported - var descriptor = preEvaluatedFont.descriptor; - var fontFile3 = descriptor && descriptor.get('FontFile3'); - var subtype = fontFile3 && fontFile3.get('Subtype'); - var fontType = getFontType(preEvaluatedFont.type, - subtype && subtype.name); - var xrefFontStats = xref.stats.fontTypes; - xrefFontStats[fontType] = true; - } catch (ex) { } - - fontCapability.resolve(new TranslatedFont(font.loadedName, - new ErrorFont(reason instanceof Error ? reason.message : reason), - font)); - }); - return fontCapability.promise; - }, - - buildPath: function PartialEvaluator_buildPath(operatorList, fn, args) { - var lastIndex = operatorList.length - 1; - if (!args) { - args = []; - } - if (lastIndex < 0 || - operatorList.fnArray[lastIndex] !== OPS.constructPath) { - operatorList.addOp(OPS.constructPath, [[fn], args]); - } else { - var opArgs = operatorList.argsArray[lastIndex]; - opArgs[0].push(fn); - Array.prototype.push.apply(opArgs[1], args); - } - }, - - handleColorN: function PartialEvaluator_handleColorN(operatorList, fn, args, - cs, patterns, resources, xref) { - // compile tiling patterns - var patternName = args[args.length - 1]; - // SCN/scn applies patterns along with normal colors - var pattern; - if (isName(patternName) && - (pattern = patterns.get(patternName.name))) { - var dict = (isStream(pattern) ? pattern.dict : pattern); - var typeNum = dict.get('PatternType'); - - if (typeNum === TILING_PATTERN) { - var color = cs.base ? cs.base.getRgb(args, 0) : null; - return this.handleTilingType(fn, color, resources, pattern, - dict, operatorList); - } else if (typeNum === SHADING_PATTERN) { - var shading = dict.get('Shading'); - var matrix = dict.get('Matrix'); - pattern = Pattern.parseShading(shading, matrix, xref, resources); - operatorList.addOp(fn, pattern.getIR()); - return Promise.resolve(); - } else { - return Promise.reject('Unknown PatternType: ' + typeNum); - } - } - // TODO shall we fail here? - operatorList.addOp(fn, args); - return Promise.resolve(); - }, - - getOperatorList: function PartialEvaluator_getOperatorList(stream, - resources, - operatorList, - initialState) { - - var self = this; - var xref = this.xref; - var imageCache = {}; - - assert(operatorList); - - resources = (resources || Dict.empty); - var xobjs = (resources.get('XObject') || Dict.empty); - var patterns = (resources.get('Pattern') || Dict.empty); - var stateManager = new StateManager(initialState || new EvalState()); - var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager); - var timeSlotManager = new TimeSlotManager(); - - return new Promise(function next(resolve, reject) { - timeSlotManager.reset(); - var stop, operation = {}, i, ii, cs; - while (!(stop = timeSlotManager.check())) { - // The arguments parsed by read() are used beyond this loop, so we - // cannot reuse the same array on each iteration. Therefore we pass - // in |null| as the initial value (see the comment on - // EvaluatorPreprocessor_read() for why). - operation.args = null; - if (!(preprocessor.read(operation))) { - break; - } - var args = operation.args; - var fn = operation.fn; - - switch (fn | 0) { - case OPS.paintXObject: - if (args[0].code) { - break; - } - // eagerly compile XForm objects - var name = args[0].name; - if (imageCache[name] !== undefined) { - operatorList.addOp(imageCache[name].fn, imageCache[name].args); - args = null; - continue; - } - - var xobj = xobjs.get(name); - if (xobj) { - assert(isStream(xobj), 'XObject should be a stream'); - - var type = xobj.dict.get('Subtype'); - assert(isName(type), - 'XObject should have a Name subtype'); - - if (type.name === 'Form') { - stateManager.save(); - return self.buildFormXObject(resources, xobj, null, - operatorList, - stateManager.state.clone()). - then(function () { - stateManager.restore(); - next(resolve, reject); - }, reject); - } else if (type.name === 'Image') { - self.buildPaintImageXObject(resources, xobj, false, - operatorList, name, imageCache); - args = null; - continue; - } else if (type.name === 'PS') { - // PostScript XObjects are unused when viewing documents. - // See section 4.7.1 of Adobe's PDF reference. - info('Ignored XObject subtype PS'); - continue; - } else { - error('Unhandled XObject subtype ' + type.name); - } - } - break; - case OPS.setFont: - var fontSize = args[1]; - // eagerly collect all fonts - return self.handleSetFont(resources, args, null, - operatorList, stateManager.state). - then(function (loadedName) { - operatorList.addDependency(loadedName); - operatorList.addOp(OPS.setFont, [loadedName, fontSize]); - next(resolve, reject); - }, reject); - case OPS.endInlineImage: - var cacheKey = args[0].cacheKey; - if (cacheKey) { - var cacheEntry = imageCache[cacheKey]; - if (cacheEntry !== undefined) { - operatorList.addOp(cacheEntry.fn, cacheEntry.args); - args = null; - continue; - } - } - self.buildPaintImageXObject(resources, args[0], true, - operatorList, cacheKey, imageCache); - args = null; - continue; - case OPS.showText: - args[0] = self.handleText(args[0], stateManager.state); - break; - case OPS.showSpacedText: - var arr = args[0]; - var combinedGlyphs = []; - var arrLength = arr.length; - for (i = 0; i < arrLength; ++i) { - var arrItem = arr[i]; - if (isString(arrItem)) { - Array.prototype.push.apply(combinedGlyphs, - self.handleText(arrItem, stateManager.state)); - } else if (isNum(arrItem)) { - combinedGlyphs.push(arrItem); - } - } - args[0] = combinedGlyphs; - fn = OPS.showText; - break; - case OPS.nextLineShowText: - operatorList.addOp(OPS.nextLine); - args[0] = self.handleText(args[0], stateManager.state); - fn = OPS.showText; - break; - case OPS.nextLineSetSpacingShowText: - operatorList.addOp(OPS.nextLine); - operatorList.addOp(OPS.setWordSpacing, [args.shift()]); - operatorList.addOp(OPS.setCharSpacing, [args.shift()]); - args[0] = self.handleText(args[0], stateManager.state); - fn = OPS.showText; - break; - case OPS.setTextRenderingMode: - stateManager.state.textRenderingMode = args[0]; - break; - - case OPS.setFillColorSpace: - stateManager.state.fillColorSpace = - ColorSpace.parse(args[0], xref, resources); - continue; - case OPS.setStrokeColorSpace: - stateManager.state.strokeColorSpace = - ColorSpace.parse(args[0], xref, resources); - continue; - case OPS.setFillColor: - cs = stateManager.state.fillColorSpace; - args = cs.getRgb(args, 0); - fn = OPS.setFillRGBColor; - break; - case OPS.setStrokeColor: - cs = stateManager.state.strokeColorSpace; - args = cs.getRgb(args, 0); - fn = OPS.setStrokeRGBColor; - break; - case OPS.setFillGray: - stateManager.state.fillColorSpace = ColorSpace.singletons.gray; - args = ColorSpace.singletons.gray.getRgb(args, 0); - fn = OPS.setFillRGBColor; - break; - case OPS.setStrokeGray: - stateManager.state.strokeColorSpace = ColorSpace.singletons.gray; - args = ColorSpace.singletons.gray.getRgb(args, 0); - fn = OPS.setStrokeRGBColor; - break; - case OPS.setFillCMYKColor: - stateManager.state.fillColorSpace = ColorSpace.singletons.cmyk; - args = ColorSpace.singletons.cmyk.getRgb(args, 0); - fn = OPS.setFillRGBColor; - break; - case OPS.setStrokeCMYKColor: - stateManager.state.strokeColorSpace = ColorSpace.singletons.cmyk; - args = ColorSpace.singletons.cmyk.getRgb(args, 0); - fn = OPS.setStrokeRGBColor; - break; - case OPS.setFillRGBColor: - stateManager.state.fillColorSpace = ColorSpace.singletons.rgb; - args = ColorSpace.singletons.rgb.getRgb(args, 0); - break; - case OPS.setStrokeRGBColor: - stateManager.state.strokeColorSpace = ColorSpace.singletons.rgb; - args = ColorSpace.singletons.rgb.getRgb(args, 0); - break; - case OPS.setFillColorN: - cs = stateManager.state.fillColorSpace; - if (cs.name === 'Pattern') { - return self.handleColorN(operatorList, OPS.setFillColorN, - args, cs, patterns, resources, xref).then(function() { - next(resolve, reject); - }, reject); - } - args = cs.getRgb(args, 0); - fn = OPS.setFillRGBColor; - break; - case OPS.setStrokeColorN: - cs = stateManager.state.strokeColorSpace; - if (cs.name === 'Pattern') { - return self.handleColorN(operatorList, OPS.setStrokeColorN, - args, cs, patterns, resources, xref).then(function() { - next(resolve, reject); - }, reject); - } - args = cs.getRgb(args, 0); - fn = OPS.setStrokeRGBColor; - break; - - case OPS.shadingFill: - var shadingRes = resources.get('Shading'); - if (!shadingRes) { - error('No shading resource found'); - } - - var shading = shadingRes.get(args[0].name); - if (!shading) { - error('No shading object found'); - } - - var shadingFill = Pattern.parseShading(shading, null, xref, - resources); - var patternIR = shadingFill.getIR(); - args = [patternIR]; - fn = OPS.shadingFill; - break; - case OPS.setGState: - var dictName = args[0]; - var extGState = resources.get('ExtGState'); - - if (!isDict(extGState) || !extGState.has(dictName.name)) { - break; - } - - var gState = extGState.get(dictName.name); - return self.setGState(resources, gState, operatorList, xref, - stateManager).then(function() { - next(resolve, reject); - }, reject); - case OPS.moveTo: - case OPS.lineTo: - case OPS.curveTo: - case OPS.curveTo2: - case OPS.curveTo3: - case OPS.closePath: - self.buildPath(operatorList, fn, args); - continue; - case OPS.rectangle: - self.buildPath(operatorList, fn, args); - continue; - } - operatorList.addOp(fn, args); - } - if (stop) { - deferred.then(function () { - next(resolve, reject); - }); - return; - } - // Some PDFs don't close all restores inside object/form. - // Closing those for them. - for (i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) { - operatorList.addOp(OPS.restore, []); - } - resolve(); - }); - }, - - getTextContent: function PartialEvaluator_getTextContent(stream, resources, - stateManager) { - - stateManager = (stateManager || new StateManager(new TextState())); - - var textContent = { - items: [], - styles: Object.create(null) - }; - var bidiTexts = textContent.items; - var SPACE_FACTOR = 0.3; - var MULTI_SPACE_FACTOR = 1.5; - - var self = this; - var xref = this.xref; - - resources = (xref.fetchIfRef(resources) || Dict.empty); - - // The xobj is parsed iff it's needed, e.g. if there is a `DO` cmd. - var xobjs = null; - var xobjsCache = {}; - - var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager); - - var textState; - - function newTextChunk() { - var font = textState.font; - if (!(font.loadedName in textContent.styles)) { - textContent.styles[font.loadedName] = { - fontFamily: font.fallbackName, - ascent: font.ascent, - descent: font.descent, - vertical: font.vertical - }; - } - return { - // |str| is initially an array which we push individual chars to, and - // then runBidi() overwrites it with the final string. - str: [], - dir: null, - width: 0, - height: 0, - transform: null, - fontName: font.loadedName - }; - } - - function runBidi(textChunk) { - var str = textChunk.str.join(''); - var bidiResult = PDFJS.bidi(str, -1, textState.font.vertical); - textChunk.str = bidiResult.str; - textChunk.dir = bidiResult.dir; - return textChunk; - } - - function handleSetFont(fontName, fontRef) { - return self.loadFont(fontName, fontRef, xref, resources). - then(function (translated) { - textState.font = translated.font; - textState.fontMatrix = translated.font.fontMatrix || - FONT_IDENTITY_MATRIX; - }); - } - - function buildTextGeometry(chars, textChunk) { - var font = textState.font; - textChunk = textChunk || newTextChunk(); - if (!textChunk.transform) { - // 9.4.4 Text Space Details - var tsm = [textState.fontSize * textState.textHScale, 0, - 0, textState.fontSize, - 0, textState.textRise]; - var trm = textChunk.transform = Util.transform(textState.ctm, - Util.transform(textState.textMatrix, tsm)); - if (!font.vertical) { - textChunk.height = Math.sqrt(trm[2] * trm[2] + trm[3] * trm[3]); - } else { - textChunk.width = Math.sqrt(trm[0] * trm[0] + trm[1] * trm[1]); - } - } - var width = 0; - var height = 0; - var glyphs = font.charsToGlyphs(chars); - var defaultVMetrics = font.defaultVMetrics; - for (var i = 0; i < glyphs.length; i++) { - var glyph = glyphs[i]; - if (!glyph) { // Previous glyph was a space. - width += textState.wordSpacing * textState.textHScale; - continue; - } - var vMetricX = null; - var vMetricY = null; - var glyphWidth = null; - if (font.vertical) { - if (glyph.vmetric) { - glyphWidth = glyph.vmetric[0]; - vMetricX = glyph.vmetric[1]; - vMetricY = glyph.vmetric[2]; - } else { - glyphWidth = glyph.width; - vMetricX = glyph.width * 0.5; - vMetricY = defaultVMetrics[2]; - } - } else { - glyphWidth = glyph.width; - } - - var glyphUnicode = glyph.unicode; - if (NormalizedUnicodes[glyphUnicode] !== undefined) { - glyphUnicode = NormalizedUnicodes[glyphUnicode]; - } - glyphUnicode = reverseIfRtl(glyphUnicode); - - // The following will calculate the x and y of the individual glyphs. - // if (font.vertical) { - // tsm[4] -= vMetricX * Math.abs(textState.fontSize) * - // textState.fontMatrix[0]; - // tsm[5] -= vMetricY * textState.fontSize * - // textState.fontMatrix[0]; - // } - // var trm = Util.transform(textState.textMatrix, tsm); - // var pt = Util.applyTransform([trm[4], trm[5]], textState.ctm); - // var x = pt[0]; - // var y = pt[1]; - - var tx = 0; - var ty = 0; - if (!font.vertical) { - var w0 = glyphWidth * textState.fontMatrix[0]; - tx = (w0 * textState.fontSize + textState.charSpacing) * - textState.textHScale; - width += tx; - } else { - var w1 = glyphWidth * textState.fontMatrix[0]; - ty = w1 * textState.fontSize + textState.charSpacing; - height += ty; - } - textState.translateTextMatrix(tx, ty); - - textChunk.str.push(glyphUnicode); - } - - var a = textState.textLineMatrix[0]; - var b = textState.textLineMatrix[1]; - var scaleLineX = Math.sqrt(a * a + b * b); - a = textState.ctm[0]; - b = textState.ctm[1]; - var scaleCtmX = Math.sqrt(a * a + b * b); - if (!font.vertical) { - textChunk.width += width * scaleCtmX * scaleLineX; - } else { - textChunk.height += Math.abs(height * scaleCtmX * scaleLineX); - } - return textChunk; - } - - var timeSlotManager = new TimeSlotManager(); - - return new Promise(function next(resolve, reject) { - timeSlotManager.reset(); - var stop, operation = {}, args = []; - while (!(stop = timeSlotManager.check())) { - // The arguments parsed by read() are not used beyond this loop, so - // we can reuse the same array on every iteration, thus avoiding - // unnecessary allocations. - args.length = 0; - operation.args = args; - if (!(preprocessor.read(operation))) { - break; - } - textState = stateManager.state; - var fn = operation.fn; - args = operation.args; - - switch (fn | 0) { - case OPS.setFont: - textState.fontSize = args[1]; - return handleSetFont(args[0].name).then(function() { - next(resolve, reject); - }, reject); - case OPS.setTextRise: - textState.textRise = args[0]; - break; - case OPS.setHScale: - textState.textHScale = args[0] / 100; - break; - case OPS.setLeading: - textState.leading = args[0]; - break; - case OPS.moveText: - textState.translateTextLineMatrix(args[0], args[1]); - textState.textMatrix = textState.textLineMatrix.slice(); - break; - case OPS.setLeadingMoveText: - textState.leading = -args[1]; - textState.translateTextLineMatrix(args[0], args[1]); - textState.textMatrix = textState.textLineMatrix.slice(); - break; - case OPS.nextLine: - textState.carriageReturn(); - break; - case OPS.setTextMatrix: - textState.setTextMatrix(args[0], args[1], args[2], args[3], - args[4], args[5]); - textState.setTextLineMatrix(args[0], args[1], args[2], args[3], - args[4], args[5]); - break; - case OPS.setCharSpacing: - textState.charSpacing = args[0]; - break; - case OPS.setWordSpacing: - textState.wordSpacing = args[0]; - break; - case OPS.beginText: - textState.textMatrix = IDENTITY_MATRIX.slice(); - textState.textLineMatrix = IDENTITY_MATRIX.slice(); - break; - case OPS.showSpacedText: - var items = args[0]; - var textChunk = newTextChunk(); - var offset; - for (var j = 0, jj = items.length; j < jj; j++) { - if (typeof items[j] === 'string') { - buildTextGeometry(items[j], textChunk); - } else { - var val = items[j] / 1000; - if (!textState.font.vertical) { - offset = -val * textState.fontSize * textState.textHScale * - textState.textMatrix[0]; - textState.translateTextMatrix(offset, 0); - textChunk.width += offset; - } else { - offset = -val * textState.fontSize * - textState.textMatrix[3]; - textState.translateTextMatrix(0, offset); - textChunk.height += offset; - } - if (items[j] < 0 && textState.font.spaceWidth > 0) { - var fakeSpaces = -items[j] / textState.font.spaceWidth; - if (fakeSpaces > MULTI_SPACE_FACTOR) { - fakeSpaces = Math.round(fakeSpaces); - while (fakeSpaces--) { - textChunk.str.push(' '); - } - } else if (fakeSpaces > SPACE_FACTOR) { - textChunk.str.push(' '); - } - } - } - } - bidiTexts.push(runBidi(textChunk)); - break; - case OPS.showText: - bidiTexts.push(runBidi(buildTextGeometry(args[0]))); - break; - case OPS.nextLineShowText: - textState.carriageReturn(); - bidiTexts.push(runBidi(buildTextGeometry(args[0]))); - break; - case OPS.nextLineSetSpacingShowText: - textState.wordSpacing = args[0]; - textState.charSpacing = args[1]; - textState.carriageReturn(); - bidiTexts.push(runBidi(buildTextGeometry(args[2]))); - break; - case OPS.paintXObject: - if (args[0].code) { - break; - } - - if (!xobjs) { - xobjs = (resources.get('XObject') || Dict.empty); - } - - var name = args[0].name; - if (xobjsCache.key === name) { - if (xobjsCache.texts) { - Util.appendToArray(bidiTexts, xobjsCache.texts.items); - Util.extendObj(textContent.styles, xobjsCache.texts.styles); - } - break; - } - - var xobj = xobjs.get(name); - if (!xobj) { - break; - } - assert(isStream(xobj), 'XObject should be a stream'); - - var type = xobj.dict.get('Subtype'); - assert(isName(type), - 'XObject should have a Name subtype'); - - if ('Form' !== type.name) { - xobjsCache.key = name; - xobjsCache.texts = null; - break; - } - - stateManager.save(); - var matrix = xobj.dict.get('Matrix'); - if (isArray(matrix) && matrix.length === 6) { - stateManager.transform(matrix); - } - - return self.getTextContent(xobj, - xobj.dict.get('Resources') || resources, stateManager). - then(function (formTextContent) { - Util.appendToArray(bidiTexts, formTextContent.items); - Util.extendObj(textContent.styles, formTextContent.styles); - stateManager.restore(); - - xobjsCache.key = name; - xobjsCache.texts = formTextContent; - - next(resolve, reject); - }, reject); - case OPS.setGState: - var dictName = args[0]; - var extGState = resources.get('ExtGState'); - - if (!isDict(extGState) || !extGState.has(dictName.name)) { - break; - } - - var gsStateMap = extGState.get(dictName.name); - var gsStateFont = null; - for (var key in gsStateMap) { - if (key === 'Font') { - assert(!gsStateFont); - gsStateFont = gsStateMap[key]; - } - } - if (gsStateFont) { - textState.fontSize = gsStateFont[1]; - return handleSetFont(gsStateFont[0]).then(function() { - next(resolve, reject); - }, reject); - } - break; - } // switch - } // while - if (stop) { - deferred.then(function () { - next(resolve, reject); - }); - return; - } - resolve(textContent); - }); - }, - - extractDataStructures: function - partialEvaluatorExtractDataStructures(dict, baseDict, - xref, properties) { - // 9.10.2 - var toUnicode = (dict.get('ToUnicode') || baseDict.get('ToUnicode')); - if (toUnicode) { - properties.toUnicode = this.readToUnicode(toUnicode); - } - if (properties.composite) { - // CIDSystemInfo helps to match CID to glyphs - var cidSystemInfo = dict.get('CIDSystemInfo'); - if (isDict(cidSystemInfo)) { - properties.cidSystemInfo = { - registry: cidSystemInfo.get('Registry'), - ordering: cidSystemInfo.get('Ordering'), - supplement: cidSystemInfo.get('Supplement') - }; - } - - var cidToGidMap = dict.get('CIDToGIDMap'); - if (isStream(cidToGidMap)) { - properties.cidToGidMap = this.readCidToGidMap(cidToGidMap); - } - } - - // Based on 9.6.6 of the spec the encoding can come from multiple places - // and depends on the font type. The base encoding and differences are - // read here, but the encoding that is actually used is chosen during - // glyph mapping in the font. - // TODO: Loading the built in encoding in the font would allow the - // differences to be merged in here not require us to hold on to it. - var differences = []; - var baseEncodingName = null; - var encoding; - if (dict.has('Encoding')) { - encoding = dict.get('Encoding'); - if (isDict(encoding)) { - baseEncodingName = encoding.get('BaseEncoding'); - baseEncodingName = (isName(baseEncodingName) ? - baseEncodingName.name : null); - // Load the differences between the base and original - if (encoding.has('Differences')) { - var diffEncoding = encoding.get('Differences'); - var index = 0; - for (var j = 0, jj = diffEncoding.length; j < jj; j++) { - var data = diffEncoding[j]; - if (isNum(data)) { - index = data; - } else { - differences[index++] = data.name; - } - } - } - } else if (isName(encoding)) { - baseEncodingName = encoding.name; - } else { - error('Encoding is not a Name nor a Dict'); - } - // According to table 114 if the encoding is a named encoding it must be - // one of these predefined encodings. - if ((baseEncodingName !== 'MacRomanEncoding' && - baseEncodingName !== 'MacExpertEncoding' && - baseEncodingName !== 'WinAnsiEncoding')) { - baseEncodingName = null; - } - } - - if (baseEncodingName) { - properties.defaultEncoding = Encodings[baseEncodingName].slice(); - } else { - encoding = (properties.type === 'TrueType' ? - Encodings.WinAnsiEncoding : Encodings.StandardEncoding); - // The Symbolic attribute can be misused for regular fonts - // Heuristic: we have to check if the font is a standard one also - if (!!(properties.flags & FontFlags.Symbolic)) { - encoding = Encodings.MacRomanEncoding; - if (!properties.file) { - if (/Symbol/i.test(properties.name)) { - encoding = Encodings.SymbolSetEncoding; - } else if (/Dingbats/i.test(properties.name)) { - encoding = Encodings.ZapfDingbatsEncoding; - } - } - } - properties.defaultEncoding = encoding; - } - - properties.differences = differences; - properties.baseEncodingName = baseEncodingName; - properties.dict = dict; - }, - - readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) { - var cmap, cmapObj = toUnicode; - if (isName(cmapObj)) { - cmap = CMapFactory.create(cmapObj, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); - if (cmap instanceof IdentityCMap) { - return new IdentityToUnicodeMap(0, 0xFFFF); - } - return new ToUnicodeMap(cmap.getMap()); - } else if (isStream(cmapObj)) { - cmap = CMapFactory.create(cmapObj, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); - if (cmap instanceof IdentityCMap) { - return new IdentityToUnicodeMap(0, 0xFFFF); - } - cmap = cmap.getMap(); - // Convert UTF-16BE - // NOTE: cmap can be a sparse array, so use forEach instead of for(;;) - // to iterate over all keys. - cmap.forEach(function(token, i) { - var str = []; - for (var k = 0; k < token.length; k += 2) { - var w1 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1); - if ((w1 & 0xF800) !== 0xD800) { // w1 < 0xD800 || w1 > 0xDFFF - str.push(w1); - continue; - } - k += 2; - var w2 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1); - str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000); - } - cmap[i] = String.fromCharCode.apply(String, str); - }); - return new ToUnicodeMap(cmap); - } - return null; - }, - - readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) { - // Extract the encoding from the CIDToGIDMap - var glyphsData = cidToGidStream.getBytes(); - - // Set encoding 0 to later verify the font has an encoding - var result = []; - for (var j = 0, jj = glyphsData.length; j < jj; j++) { - var glyphID = (glyphsData[j++] << 8) | glyphsData[j]; - if (glyphID === 0) { - continue; - } - var code = j >> 1; - result[code] = glyphID; - } - return result; - }, - - extractWidths: function PartialEvaluator_extractWidths(dict, xref, - descriptor, - properties) { - var glyphsWidths = []; - var defaultWidth = 0; - var glyphsVMetrics = []; - var defaultVMetrics; - var i, ii, j, jj, start, code, widths; - if (properties.composite) { - defaultWidth = dict.get('DW') || 1000; - - widths = dict.get('W'); - if (widths) { - for (i = 0, ii = widths.length; i < ii; i++) { - start = widths[i++]; - code = xref.fetchIfRef(widths[i]); - if (isArray(code)) { - for (j = 0, jj = code.length; j < jj; j++) { - glyphsWidths[start++] = code[j]; - } - } else { - var width = widths[++i]; - for (j = start; j <= code; j++) { - glyphsWidths[j] = width; - } - } - } - } - - if (properties.vertical) { - var vmetrics = (dict.get('DW2') || [880, -1000]); - defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]]; - vmetrics = dict.get('W2'); - if (vmetrics) { - for (i = 0, ii = vmetrics.length; i < ii; i++) { - start = vmetrics[i++]; - code = xref.fetchIfRef(vmetrics[i]); - if (isArray(code)) { - for (j = 0, jj = code.length; j < jj; j++) { - glyphsVMetrics[start++] = [code[j++], code[j++], code[j]]; - } - } else { - var vmetric = [vmetrics[++i], vmetrics[++i], vmetrics[++i]]; - for (j = start; j <= code; j++) { - glyphsVMetrics[j] = vmetric; - } - } - } - } - } - } else { - var firstChar = properties.firstChar; - widths = dict.get('Widths'); - if (widths) { - j = firstChar; - for (i = 0, ii = widths.length; i < ii; i++) { - glyphsWidths[j++] = widths[i]; - } - defaultWidth = (parseFloat(descriptor.get('MissingWidth')) || 0); - } else { - // Trying get the BaseFont metrics (see comment above). - var baseFontName = dict.get('BaseFont'); - if (isName(baseFontName)) { - var metrics = this.getBaseFontMetrics(baseFontName.name); - - glyphsWidths = this.buildCharCodeToWidth(metrics.widths, - properties); - defaultWidth = metrics.defaultWidth; - } - } - } - - // Heuristic: detection of monospace font by checking all non-zero widths - var isMonospace = true; - var firstWidth = defaultWidth; - for (var glyph in glyphsWidths) { - var glyphWidth = glyphsWidths[glyph]; - if (!glyphWidth) { - continue; - } - if (!firstWidth) { - firstWidth = glyphWidth; - continue; - } - if (firstWidth !== glyphWidth) { - isMonospace = false; - break; - } - } - if (isMonospace) { - properties.flags |= FontFlags.FixedPitch; - } - - properties.defaultWidth = defaultWidth; - properties.widths = glyphsWidths; - properties.defaultVMetrics = defaultVMetrics; - properties.vmetrics = glyphsVMetrics; - }, - - isSerifFont: function PartialEvaluator_isSerifFont(baseFontName) { - // Simulating descriptor flags attribute - var fontNameWoStyle = baseFontName.split('-')[0]; - return (fontNameWoStyle in serifFonts) || - (fontNameWoStyle.search(/serif/gi) !== -1); - }, - - getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) { - var defaultWidth = 0; - var widths = []; - var monospace = false; - var lookupName = (stdFontMap[name] || name); - - if (!(lookupName in Metrics)) { - // Use default fonts for looking up font metrics if the passed - // font is not a base font - if (this.isSerifFont(name)) { - lookupName = 'Times-Roman'; - } else { - lookupName = 'Helvetica'; - } - } - var glyphWidths = Metrics[lookupName]; - - if (isNum(glyphWidths)) { - defaultWidth = glyphWidths; - monospace = true; - } else { - widths = glyphWidths; - } - - return { - defaultWidth: defaultWidth, - monospace: monospace, - widths: widths - }; - }, - - buildCharCodeToWidth: - function PartialEvaluator_bulildCharCodeToWidth(widthsByGlyphName, - properties) { - var widths = Object.create(null); - var differences = properties.differences; - var encoding = properties.defaultEncoding; - for (var charCode = 0; charCode < 256; charCode++) { - if (charCode in differences && - widthsByGlyphName[differences[charCode]]) { - widths[charCode] = widthsByGlyphName[differences[charCode]]; - continue; - } - if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) { - widths[charCode] = widthsByGlyphName[encoding[charCode]]; - continue; - } - } - return widths; - }, - - preEvaluateFont: function PartialEvaluator_preEvaluateFont(dict, xref) { - var baseDict = dict; - var type = dict.get('Subtype'); - assert(isName(type), 'invalid font Subtype'); - - var composite = false; - var uint8array; - if (type.name === 'Type0') { - // If font is a composite - // - get the descendant font - // - set the type according to the descendant font - // - get the FontDescriptor from the descendant font - var df = dict.get('DescendantFonts'); - if (!df) { - error('Descendant fonts are not specified'); - } - dict = (isArray(df) ? xref.fetchIfRef(df[0]) : df); - - type = dict.get('Subtype'); - assert(isName(type), 'invalid font Subtype'); - composite = true; - } - - var descriptor = dict.get('FontDescriptor'); - if (descriptor) { - var hash = new MurmurHash3_64(); - var encoding = baseDict.getRaw('Encoding'); - if (isName(encoding)) { - hash.update(encoding.name); - } else if (isRef(encoding)) { - hash.update(encoding.num + '_' + encoding.gen); - } else if (isDict(encoding)) { - var keys = encoding.getKeys(); - for (var i = 0, ii = keys.length; i < ii; i++) { - var entry = encoding.getRaw(keys[i]); - if (isName(entry)) { - hash.update(entry.name); - } else if (isRef(entry)) { - hash.update(entry.num + '_' + entry.gen); - } else if (isArray(entry)) { // 'Differences' entry. - // Ideally we should check the contents of the array, but to avoid - // parsing it here and then again in |extractDataStructures|, - // we only use the array length for now (fixes bug1157493.pdf). - hash.update(entry.length.toString()); - } - } - } - - var toUnicode = dict.get('ToUnicode') || baseDict.get('ToUnicode'); - if (isStream(toUnicode)) { - var stream = toUnicode.str || toUnicode; - uint8array = stream.buffer ? - new Uint8Array(stream.buffer.buffer, 0, stream.bufferLength) : - new Uint8Array(stream.bytes.buffer, - stream.start, stream.end - stream.start); - hash.update(uint8array); - - } else if (isName(toUnicode)) { - hash.update(toUnicode.name); - } - - var widths = dict.get('Widths') || baseDict.get('Widths'); - if (widths) { - uint8array = new Uint8Array(new Uint32Array(widths).buffer); - hash.update(uint8array); - } - } - - return { - descriptor: descriptor, - dict: dict, - baseDict: baseDict, - composite: composite, - type: type.name, - hash: hash ? hash.hexdigest() : '' - }; - }, - - translateFont: function PartialEvaluator_translateFont(preEvaluatedFont, - xref) { - var baseDict = preEvaluatedFont.baseDict; - var dict = preEvaluatedFont.dict; - var composite = preEvaluatedFont.composite; - var descriptor = preEvaluatedFont.descriptor; - var type = preEvaluatedFont.type; - var maxCharIndex = (composite ? 0xFFFF : 0xFF); - var properties; - - if (!descriptor) { - if (type === 'Type3') { - // FontDescriptor is only required for Type3 fonts when the document - // is a tagged pdf. Create a barbebones one to get by. - descriptor = new Dict(null); - descriptor.set('FontName', Name.get(type)); - } else { - // Before PDF 1.5 if the font was one of the base 14 fonts, having a - // FontDescriptor was not required. - // This case is here for compatibility. - var baseFontName = dict.get('BaseFont'); - if (!isName(baseFontName)) { - error('Base font is not specified'); - } - - // Using base font name as a font name. - baseFontName = baseFontName.name.replace(/[,_]/g, '-'); - var metrics = this.getBaseFontMetrics(baseFontName); - - // Simulating descriptor flags attribute - var fontNameWoStyle = baseFontName.split('-')[0]; - var flags = - (this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) | - (metrics.monospace ? FontFlags.FixedPitch : 0) | - (symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic : - FontFlags.Nonsymbolic); - - properties = { - type: type, - name: baseFontName, - widths: metrics.widths, - defaultWidth: metrics.defaultWidth, - flags: flags, - firstChar: 0, - lastChar: maxCharIndex - }; - this.extractDataStructures(dict, dict, xref, properties); - properties.widths = this.buildCharCodeToWidth(metrics.widths, - properties); - return new Font(baseFontName, null, properties); - } - } - - // According to the spec if 'FontDescriptor' is declared, 'FirstChar', - // 'LastChar' and 'Widths' should exist too, but some PDF encoders seem - // to ignore this rule when a variant of a standart font is used. - // TODO Fill the width array depending on which of the base font this is - // a variant. - var firstChar = (dict.get('FirstChar') || 0); - var lastChar = (dict.get('LastChar') || maxCharIndex); - - var fontName = descriptor.get('FontName'); - var baseFont = dict.get('BaseFont'); - // Some bad PDFs have a string as the font name. - if (isString(fontName)) { - fontName = Name.get(fontName); - } - if (isString(baseFont)) { - baseFont = Name.get(baseFont); - } - - if (type !== 'Type3') { - var fontNameStr = fontName && fontName.name; - var baseFontStr = baseFont && baseFont.name; - if (fontNameStr !== baseFontStr) { - info('The FontDescriptor\'s FontName is "' + fontNameStr + - '" but should be the same as the Font\'s BaseFont "' + - baseFontStr + '"'); - // Workaround for cases where e.g. fontNameStr = 'Arial' and - // baseFontStr = 'Arial,Bold' (needed when no font file is embedded). - if (fontNameStr && baseFontStr && - baseFontStr.indexOf(fontNameStr) === 0) { - fontName = baseFont; - } - } - } - fontName = (fontName || baseFont); - - assert(isName(fontName), 'invalid font name'); - - var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3'); - if (fontFile) { - if (fontFile.dict) { - var subtype = fontFile.dict.get('Subtype'); - if (subtype) { - subtype = subtype.name; - } - var length1 = fontFile.dict.get('Length1'); - var length2 = fontFile.dict.get('Length2'); - } - } - - properties = { - type: type, - name: fontName.name, - subtype: subtype, - file: fontFile, - length1: length1, - length2: length2, - loadedName: baseDict.loadedName, - composite: composite, - wideChars: composite, - fixedPitch: false, - fontMatrix: (dict.get('FontMatrix') || FONT_IDENTITY_MATRIX), - firstChar: firstChar || 0, - lastChar: (lastChar || maxCharIndex), - bbox: descriptor.get('FontBBox'), - ascent: descriptor.get('Ascent'), - descent: descriptor.get('Descent'), - xHeight: descriptor.get('XHeight'), - capHeight: descriptor.get('CapHeight'), - flags: descriptor.get('Flags'), - italicAngle: descriptor.get('ItalicAngle'), - coded: false - }; - - if (composite) { - var cidEncoding = baseDict.get('Encoding'); - if (isName(cidEncoding)) { - properties.cidEncoding = cidEncoding.name; - } - properties.cMap = CMapFactory.create(cidEncoding, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); - properties.vertical = properties.cMap.vertical; - } - this.extractDataStructures(dict, baseDict, xref, properties); - this.extractWidths(dict, xref, descriptor, properties); - - if (type === 'Type3') { - properties.isType3Font = true; - } - - return new Font(fontName.name, fontFile, properties); - } - }; - - return PartialEvaluator; -})(); - -var TranslatedFont = (function TranslatedFontClosure() { - function TranslatedFont(loadedName, font, dict) { - this.loadedName = loadedName; - this.font = font; - this.dict = dict; - this.type3Loaded = null; - this.sent = false; - } - TranslatedFont.prototype = { - send: function (handler) { - if (this.sent) { - return; - } - var fontData = this.font.exportData(); - handler.send('commonobj', [ - this.loadedName, - 'Font', - fontData - ]); - this.sent = true; - }, - loadType3Data: function (evaluator, resources, parentOperatorList) { - assert(this.font.isType3Font); - - if (this.type3Loaded) { - return this.type3Loaded; - } - - var translatedFont = this.font; - var loadCharProcsPromise = Promise.resolve(); - var charProcs = this.dict.get('CharProcs').getAll(); - var fontResources = this.dict.get('Resources') || resources; - var charProcKeys = Object.keys(charProcs); - var charProcOperatorList = {}; - for (var i = 0, n = charProcKeys.length; i < n; ++i) { - loadCharProcsPromise = loadCharProcsPromise.then(function (key) { - var glyphStream = charProcs[key]; - var operatorList = new OperatorList(); - return evaluator.getOperatorList(glyphStream, fontResources, - operatorList).then(function () { - charProcOperatorList[key] = operatorList.getIR(); - - // Add the dependencies to the parent operator list so they are - // resolved before sub operator list is executed synchronously. - parentOperatorList.addDependencies(operatorList.dependencies); - }, function (reason) { - warn('Type3 font resource \"' + key + '\" is not available'); - var operatorList = new OperatorList(); - charProcOperatorList[key] = operatorList.getIR(); - }); - }.bind(this, charProcKeys[i])); - } - this.type3Loaded = loadCharProcsPromise.then(function () { - translatedFont.charProcOperatorList = charProcOperatorList; - }); - return this.type3Loaded; - } - }; - return TranslatedFont; -})(); - -var OperatorList = (function OperatorListClosure() { - var CHUNK_SIZE = 1000; - var CHUNK_SIZE_ABOUT = CHUNK_SIZE - 5; // close to chunk size - - function getTransfers(queue) { - var transfers = []; - var fnArray = queue.fnArray, argsArray = queue.argsArray; - for (var i = 0, ii = queue.length; i < ii; i++) { - switch (fnArray[i]) { - case OPS.paintInlineImageXObject: - case OPS.paintInlineImageXObjectGroup: - case OPS.paintImageMaskXObject: - var arg = argsArray[i][0]; // first param in imgData - if (!arg.cached) { - transfers.push(arg.data.buffer); - } - break; - } - } - return transfers; - } - - function OperatorList(intent, messageHandler, pageIndex) { - this.messageHandler = messageHandler; - this.fnArray = []; - this.argsArray = []; - this.dependencies = {}; - this.pageIndex = pageIndex; - this.intent = intent; - } - - OperatorList.prototype = { - get length() { - return this.argsArray.length; - }, - - addOp: function(fn, args) { - this.fnArray.push(fn); - this.argsArray.push(args); - if (this.messageHandler) { - if (this.fnArray.length >= CHUNK_SIZE) { - this.flush(); - } else if (this.fnArray.length >= CHUNK_SIZE_ABOUT && - (fn === OPS.restore || fn === OPS.endText)) { - // heuristic to flush on boundary of restore or endText - this.flush(); - } - } - }, - - addDependency: function(dependency) { - if (dependency in this.dependencies) { - return; - } - this.dependencies[dependency] = true; - this.addOp(OPS.dependency, [dependency]); - }, - - addDependencies: function(dependencies) { - for (var key in dependencies) { - this.addDependency(key); - } - }, - - addOpList: function(opList) { - Util.extendObj(this.dependencies, opList.dependencies); - for (var i = 0, ii = opList.length; i < ii; i++) { - this.addOp(opList.fnArray[i], opList.argsArray[i]); - } - }, - - getIR: function() { - return { - fnArray: this.fnArray, - argsArray: this.argsArray, - length: this.length - }; - }, - - flush: function(lastChunk) { - if (this.intent !== 'oplist') { - new QueueOptimizer().optimize(this); - } - var transfers = getTransfers(this); - this.messageHandler.send('RenderPageChunk', { - operatorList: { - fnArray: this.fnArray, - argsArray: this.argsArray, - lastChunk: lastChunk, - length: this.length - }, - pageIndex: this.pageIndex, - intent: this.intent - }, transfers); - this.dependencies = {}; - this.fnArray.length = 0; - this.argsArray.length = 0; - } - }; - - return OperatorList; -})(); - -var StateManager = (function StateManagerClosure() { - function StateManager(initialState) { - this.state = initialState; - this.stateStack = []; - } - StateManager.prototype = { - save: function () { - var old = this.state; - this.stateStack.push(this.state); - this.state = old.clone(); - }, - restore: function () { - var prev = this.stateStack.pop(); - if (prev) { - this.state = prev; - } - }, - transform: function (args) { - this.state.ctm = Util.transform(this.state.ctm, args); - } - }; - return StateManager; -})(); - -var TextState = (function TextStateClosure() { - function TextState() { - this.ctm = new Float32Array(IDENTITY_MATRIX); - this.fontSize = 0; - this.font = null; - this.fontMatrix = FONT_IDENTITY_MATRIX; - this.textMatrix = IDENTITY_MATRIX.slice(); - this.textLineMatrix = IDENTITY_MATRIX.slice(); - this.charSpacing = 0; - this.wordSpacing = 0; - this.leading = 0; - this.textHScale = 1; - this.textRise = 0; - } - - TextState.prototype = { - setTextMatrix: function TextState_setTextMatrix(a, b, c, d, e, f) { - var m = this.textMatrix; - m[0] = a; m[1] = b; m[2] = c; m[3] = d; m[4] = e; m[5] = f; - }, - setTextLineMatrix: function TextState_setTextMatrix(a, b, c, d, e, f) { - var m = this.textLineMatrix; - m[0] = a; m[1] = b; m[2] = c; m[3] = d; m[4] = e; m[5] = f; - }, - translateTextMatrix: function TextState_translateTextMatrix(x, y) { - var m = this.textMatrix; - m[4] = m[0] * x + m[2] * y + m[4]; - m[5] = m[1] * x + m[3] * y + m[5]; - }, - translateTextLineMatrix: function TextState_translateTextMatrix(x, y) { - var m = this.textLineMatrix; - m[4] = m[0] * x + m[2] * y + m[4]; - m[5] = m[1] * x + m[3] * y + m[5]; - }, - calcRenderMatrix: function TextState_calcRendeMatrix(ctm) { - // 9.4.4 Text Space Details - var tsm = [this.fontSize * this.textHScale, 0, - 0, this.fontSize, - 0, this.textRise]; - return Util.transform(ctm, Util.transform(this.textMatrix, tsm)); - }, - carriageReturn: function TextState_carriageReturn() { - this.translateTextLineMatrix(0, -this.leading); - this.textMatrix = this.textLineMatrix.slice(); - }, - clone: function TextState_clone() { - var clone = Object.create(this); - clone.textMatrix = this.textMatrix.slice(); - clone.textLineMatrix = this.textLineMatrix.slice(); - clone.fontMatrix = this.fontMatrix.slice(); - return clone; - } - }; - return TextState; -})(); - -var EvalState = (function EvalStateClosure() { - function EvalState() { - this.ctm = new Float32Array(IDENTITY_MATRIX); - this.font = null; - this.textRenderingMode = TextRenderingMode.FILL; - this.fillColorSpace = ColorSpace.singletons.gray; - this.strokeColorSpace = ColorSpace.singletons.gray; - } - EvalState.prototype = { - clone: function CanvasExtraState_clone() { - return Object.create(this); - }, - }; - return EvalState; -})(); - -var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() { - // Specifies properties for each command - // - // If variableArgs === true: [0, `numArgs`] expected - // If variableArgs === false: exactly `numArgs` expected - var OP_MAP = { - // Graphic state - w: { id: OPS.setLineWidth, numArgs: 1, variableArgs: false }, - J: { id: OPS.setLineCap, numArgs: 1, variableArgs: false }, - j: { id: OPS.setLineJoin, numArgs: 1, variableArgs: false }, - M: { id: OPS.setMiterLimit, numArgs: 1, variableArgs: false }, - d: { id: OPS.setDash, numArgs: 2, variableArgs: false }, - ri: { id: OPS.setRenderingIntent, numArgs: 1, variableArgs: false }, - i: { id: OPS.setFlatness, numArgs: 1, variableArgs: false }, - gs: { id: OPS.setGState, numArgs: 1, variableArgs: false }, - q: { id: OPS.save, numArgs: 0, variableArgs: false }, - Q: { id: OPS.restore, numArgs: 0, variableArgs: false }, - cm: { id: OPS.transform, numArgs: 6, variableArgs: false }, - - // Path - m: { id: OPS.moveTo, numArgs: 2, variableArgs: false }, - l: { id: OPS.lineTo, numArgs: 2, variableArgs: false }, - c: { id: OPS.curveTo, numArgs: 6, variableArgs: false }, - v: { id: OPS.curveTo2, numArgs: 4, variableArgs: false }, - y: { id: OPS.curveTo3, numArgs: 4, variableArgs: false }, - h: { id: OPS.closePath, numArgs: 0, variableArgs: false }, - re: { id: OPS.rectangle, numArgs: 4, variableArgs: false }, - S: { id: OPS.stroke, numArgs: 0, variableArgs: false }, - s: { id: OPS.closeStroke, numArgs: 0, variableArgs: false }, - f: { id: OPS.fill, numArgs: 0, variableArgs: false }, - F: { id: OPS.fill, numArgs: 0, variableArgs: false }, - 'f*': { id: OPS.eoFill, numArgs: 0, variableArgs: false }, - B: { id: OPS.fillStroke, numArgs: 0, variableArgs: false }, - 'B*': { id: OPS.eoFillStroke, numArgs: 0, variableArgs: false }, - b: { id: OPS.closeFillStroke, numArgs: 0, variableArgs: false }, - 'b*': { id: OPS.closeEOFillStroke, numArgs: 0, variableArgs: false }, - n: { id: OPS.endPath, numArgs: 0, variableArgs: false }, - - // Clipping - W: { id: OPS.clip, numArgs: 0, variableArgs: false }, - 'W*': { id: OPS.eoClip, numArgs: 0, variableArgs: false }, - - // Text - BT: { id: OPS.beginText, numArgs: 0, variableArgs: false }, - ET: { id: OPS.endText, numArgs: 0, variableArgs: false }, - Tc: { id: OPS.setCharSpacing, numArgs: 1, variableArgs: false }, - Tw: { id: OPS.setWordSpacing, numArgs: 1, variableArgs: false }, - Tz: { id: OPS.setHScale, numArgs: 1, variableArgs: false }, - TL: { id: OPS.setLeading, numArgs: 1, variableArgs: false }, - Tf: { id: OPS.setFont, numArgs: 2, variableArgs: false }, - Tr: { id: OPS.setTextRenderingMode, numArgs: 1, variableArgs: false }, - Ts: { id: OPS.setTextRise, numArgs: 1, variableArgs: false }, - Td: { id: OPS.moveText, numArgs: 2, variableArgs: false }, - TD: { id: OPS.setLeadingMoveText, numArgs: 2, variableArgs: false }, - Tm: { id: OPS.setTextMatrix, numArgs: 6, variableArgs: false }, - 'T*': { id: OPS.nextLine, numArgs: 0, variableArgs: false }, - Tj: { id: OPS.showText, numArgs: 1, variableArgs: false }, - TJ: { id: OPS.showSpacedText, numArgs: 1, variableArgs: false }, - '\'': { id: OPS.nextLineShowText, numArgs: 1, variableArgs: false }, - '"': { id: OPS.nextLineSetSpacingShowText, numArgs: 3, - variableArgs: false }, - - // Type3 fonts - d0: { id: OPS.setCharWidth, numArgs: 2, variableArgs: false }, - d1: { id: OPS.setCharWidthAndBounds, numArgs: 6, variableArgs: false }, - - // Color - CS: { id: OPS.setStrokeColorSpace, numArgs: 1, variableArgs: false }, - cs: { id: OPS.setFillColorSpace, numArgs: 1, variableArgs: false }, - SC: { id: OPS.setStrokeColor, numArgs: 4, variableArgs: true }, - SCN: { id: OPS.setStrokeColorN, numArgs: 33, variableArgs: true }, - sc: { id: OPS.setFillColor, numArgs: 4, variableArgs: true }, - scn: { id: OPS.setFillColorN, numArgs: 33, variableArgs: true }, - G: { id: OPS.setStrokeGray, numArgs: 1, variableArgs: false }, - g: { id: OPS.setFillGray, numArgs: 1, variableArgs: false }, - RG: { id: OPS.setStrokeRGBColor, numArgs: 3, variableArgs: false }, - rg: { id: OPS.setFillRGBColor, numArgs: 3, variableArgs: false }, - K: { id: OPS.setStrokeCMYKColor, numArgs: 4, variableArgs: false }, - k: { id: OPS.setFillCMYKColor, numArgs: 4, variableArgs: false }, - - // Shading - sh: { id: OPS.shadingFill, numArgs: 1, variableArgs: false }, - - // Images - BI: { id: OPS.beginInlineImage, numArgs: 0, variableArgs: false }, - ID: { id: OPS.beginImageData, numArgs: 0, variableArgs: false }, - EI: { id: OPS.endInlineImage, numArgs: 1, variableArgs: false }, - - // XObjects - Do: { id: OPS.paintXObject, numArgs: 1, variableArgs: false }, - MP: { id: OPS.markPoint, numArgs: 1, variableArgs: false }, - DP: { id: OPS.markPointProps, numArgs: 2, variableArgs: false }, - BMC: { id: OPS.beginMarkedContent, numArgs: 1, variableArgs: false }, - BDC: { id: OPS.beginMarkedContentProps, numArgs: 2, - variableArgs: false }, - EMC: { id: OPS.endMarkedContent, numArgs: 0, variableArgs: false }, - - // Compatibility - BX: { id: OPS.beginCompat, numArgs: 0, variableArgs: false }, - EX: { id: OPS.endCompat, numArgs: 0, variableArgs: false }, - - // (reserved partial commands for the lexer) - BM: null, - BD: null, - 'true': null, - fa: null, - fal: null, - fals: null, - 'false': null, - nu: null, - nul: null, - 'null': null - }; - - function EvaluatorPreprocessor(stream, xref, stateManager) { - // TODO(mduan): pass array of knownCommands rather than OP_MAP - // dictionary - this.parser = new Parser(new Lexer(stream, OP_MAP), false, xref); - this.stateManager = stateManager; - this.nonProcessedArgs = []; - } - - EvaluatorPreprocessor.prototype = { - get savedStatesDepth() { - return this.stateManager.stateStack.length; - }, - - // |operation| is an object with two fields: - // - // - |fn| is an out param. - // - // - |args| is an inout param. On entry, it should have one of two values. - // - // - An empty array. This indicates that the caller is providing the - // array in which the args will be stored in. The caller should use - // this value if it can reuse a single array for each call to read(). - // - // - |null|. This indicates that the caller needs this function to create - // the array in which any args are stored in. If there are zero args, - // this function will leave |operation.args| as |null| (thus avoiding - // allocations that would occur if we used an empty array to represent - // zero arguments). Otherwise, it will replace |null| with a new array - // containing the arguments. The caller should use this value if it - // cannot reuse an array for each call to read(). - // - // These two modes are present because this function is very hot and so - // avoiding allocations where possible is worthwhile. - // - read: function EvaluatorPreprocessor_read(operation) { - var args = operation.args; - while (true) { - var obj = this.parser.getObj(); - if (isCmd(obj)) { - var cmd = obj.cmd; - // Check that the command is valid - var opSpec = OP_MAP[cmd]; - if (!opSpec) { - warn('Unknown command "' + cmd + '"'); - continue; - } - - var fn = opSpec.id; - var numArgs = opSpec.numArgs; - var argsLength = args !== null ? args.length : 0; - - if (!opSpec.variableArgs) { - // Postscript commands can be nested, e.g. /F2 /GS2 gs 5.711 Tf - if (argsLength !== numArgs) { - var nonProcessedArgs = this.nonProcessedArgs; - while (argsLength > numArgs) { - nonProcessedArgs.push(args.shift()); - argsLength--; - } - while (argsLength < numArgs && nonProcessedArgs.length !== 0) { - if (!args) { - args = []; - } - args.unshift(nonProcessedArgs.pop()); - argsLength++; - } - } - - if (argsLength < numArgs) { - // If we receive too few args, it's not possible to possible - // to execute the command, so skip the command - info('Command ' + fn + ': because expected ' + - numArgs + ' args, but received ' + argsLength + - ' args; skipping'); - args = null; - continue; - } - } else if (argsLength > numArgs) { - info('Command ' + fn + ': expected [0,' + numArgs + - '] args, but received ' + argsLength + ' args'); - } - - // TODO figure out how to type-check vararg functions - this.preprocessCommand(fn, args); - - operation.fn = fn; - operation.args = args; - return true; - } else { - if (isEOF(obj)) { - return false; // no more commands - } - // argument - if (obj !== null) { - if (!args) { - args = []; - } - args.push((obj instanceof Dict ? obj.getAll() : obj)); - assert(args.length <= 33, 'Too many arguments'); - } - } - } - }, - - preprocessCommand: - function EvaluatorPreprocessor_preprocessCommand(fn, args) { - switch (fn | 0) { - case OPS.save: - this.stateManager.save(); - break; - case OPS.restore: - this.stateManager.restore(); - break; - case OPS.transform: - this.stateManager.transform(args); - break; - } - } - }; - return EvaluatorPreprocessor; -})(); - -var QueueOptimizer = (function QueueOptimizerClosure() { - function addState(parentState, pattern, fn) { - var state = parentState; - for (var i = 0, ii = pattern.length - 1; i < ii; i++) { - var item = pattern[i]; - state = (state[item] || (state[item] = [])); - } - state[pattern[pattern.length - 1]] = fn; - } - - function handlePaintSolidColorImageMask(iFirstSave, count, fnArray, - argsArray) { - // Handles special case of mainly LaTeX documents which use image masks to - // draw lines with the current fill style. - // 'count' groups of (save, transform, paintImageMaskXObject, restore)+ - // have been found at iFirstSave. - var iFirstPIMXO = iFirstSave + 2; - for (var i = 0; i < count; i++) { - var arg = argsArray[iFirstPIMXO + 4 * i]; - var imageMask = arg.length === 1 && arg[0]; - if (imageMask && imageMask.width === 1 && imageMask.height === 1 && - (!imageMask.data.length || - (imageMask.data.length === 1 && imageMask.data[0] === 0))) { - fnArray[iFirstPIMXO + 4 * i] = OPS.paintSolidColorImageMask; - continue; - } - break; - } - return count - i; - } - - var InitialState = []; - - // This replaces (save, transform, paintInlineImageXObject, restore)+ - // sequences with one |paintInlineImageXObjectGroup| operation. - addState(InitialState, - [OPS.save, OPS.transform, OPS.paintInlineImageXObject, OPS.restore], - function foundInlineImageGroup(context) { - var MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10; - var MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200; - var MAX_WIDTH = 1000; - var IMAGE_PADDING = 1; - - var fnArray = context.fnArray, argsArray = context.argsArray; - var curr = context.iCurr; - var iFirstSave = curr - 3; - var iFirstTransform = curr - 2; - var iFirstPIIXO = curr - 1; - - // Look for the quartets. - var i = iFirstSave + 4; - var ii = fnArray.length; - while (i + 3 < ii) { - if (fnArray[i] !== OPS.save || - fnArray[i + 1] !== OPS.transform || - fnArray[i + 2] !== OPS.paintInlineImageXObject || - fnArray[i + 3] !== OPS.restore) { - break; // ops don't match - } - i += 4; - } - - // At this point, i is the index of the first op past the last valid - // quartet. - var count = Math.min((i - iFirstSave) / 4, - MAX_IMAGES_IN_INLINE_IMAGES_BLOCK); - if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) { - return i; - } - - // assuming that heights of those image is too small (~1 pixel) - // packing as much as possible by lines - var maxX = 0; - var map = [], maxLineHeight = 0; - var currentX = IMAGE_PADDING, currentY = IMAGE_PADDING; - var q; - for (q = 0; q < count; q++) { - var transform = argsArray[iFirstTransform + (q << 2)]; - var img = argsArray[iFirstPIIXO + (q << 2)][0]; - if (currentX + img.width > MAX_WIDTH) { - // starting new line - maxX = Math.max(maxX, currentX); - currentY += maxLineHeight + 2 * IMAGE_PADDING; - currentX = 0; - maxLineHeight = 0; - } - map.push({ - transform: transform, - x: currentX, y: currentY, - w: img.width, h: img.height - }); - currentX += img.width + 2 * IMAGE_PADDING; - maxLineHeight = Math.max(maxLineHeight, img.height); - } - var imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING; - var imgHeight = currentY + maxLineHeight + IMAGE_PADDING; - var imgData = new Uint8Array(imgWidth * imgHeight * 4); - var imgRowSize = imgWidth << 2; - for (q = 0; q < count; q++) { - var data = argsArray[iFirstPIIXO + (q << 2)][0].data; - // Copy image by lines and extends pixels into padding. - var rowSize = map[q].w << 2; - var dataOffset = 0; - var offset = (map[q].x + map[q].y * imgWidth) << 2; - imgData.set(data.subarray(0, rowSize), offset - imgRowSize); - for (var k = 0, kk = map[q].h; k < kk; k++) { - imgData.set(data.subarray(dataOffset, dataOffset + rowSize), offset); - dataOffset += rowSize; - offset += imgRowSize; - } - imgData.set(data.subarray(dataOffset - rowSize, dataOffset), offset); - while (offset >= 0) { - data[offset - 4] = data[offset]; - data[offset - 3] = data[offset + 1]; - data[offset - 2] = data[offset + 2]; - data[offset - 1] = data[offset + 3]; - data[offset + rowSize] = data[offset + rowSize - 4]; - data[offset + rowSize + 1] = data[offset + rowSize - 3]; - data[offset + rowSize + 2] = data[offset + rowSize - 2]; - data[offset + rowSize + 3] = data[offset + rowSize - 1]; - offset -= imgRowSize; - } - } - - // Replace queue items. - fnArray.splice(iFirstSave, count * 4, OPS.paintInlineImageXObjectGroup); - argsArray.splice(iFirstSave, count * 4, - [{ width: imgWidth, height: imgHeight, kind: ImageKind.RGBA_32BPP, - data: imgData }, map]); - - return iFirstSave + 1; - }); - - // This replaces (save, transform, paintImageMaskXObject, restore)+ - // sequences with one |paintImageMaskXObjectGroup| or one - // |paintImageMaskXObjectRepeat| operation. - addState(InitialState, - [OPS.save, OPS.transform, OPS.paintImageMaskXObject, OPS.restore], - function foundImageMaskGroup(context) { - var MIN_IMAGES_IN_MASKS_BLOCK = 10; - var MAX_IMAGES_IN_MASKS_BLOCK = 100; - var MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000; - - var fnArray = context.fnArray, argsArray = context.argsArray; - var curr = context.iCurr; - var iFirstSave = curr - 3; - var iFirstTransform = curr - 2; - var iFirstPIMXO = curr - 1; - - // Look for the quartets. - var i = iFirstSave + 4; - var ii = fnArray.length; - while (i + 3 < ii) { - if (fnArray[i] !== OPS.save || - fnArray[i + 1] !== OPS.transform || - fnArray[i + 2] !== OPS.paintImageMaskXObject || - fnArray[i + 3] !== OPS.restore) { - break; // ops don't match - } - i += 4; - } - - // At this point, i is the index of the first op past the last valid - // quartet. - var count = (i - iFirstSave) / 4; - count = handlePaintSolidColorImageMask(iFirstSave, count, fnArray, - argsArray); - if (count < MIN_IMAGES_IN_MASKS_BLOCK) { - return i; - } - - var q; - var isSameImage = false; - var iTransform, transformArgs; - var firstPIMXOArg0 = argsArray[iFirstPIMXO][0]; - if (argsArray[iFirstTransform][1] === 0 && - argsArray[iFirstTransform][2] === 0) { - isSameImage = true; - var firstTransformArg0 = argsArray[iFirstTransform][0]; - var firstTransformArg3 = argsArray[iFirstTransform][3]; - iTransform = iFirstTransform + 4; - var iPIMXO = iFirstPIMXO + 4; - for (q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) { - transformArgs = argsArray[iTransform]; - if (argsArray[iPIMXO][0] !== firstPIMXOArg0 || - transformArgs[0] !== firstTransformArg0 || - transformArgs[1] !== 0 || - transformArgs[2] !== 0 || - transformArgs[3] !== firstTransformArg3) { - if (q < MIN_IMAGES_IN_MASKS_BLOCK) { - isSameImage = false; - } else { - count = q; - } - break; // different image or transform - } - } - } - - if (isSameImage) { - count = Math.min(count, MAX_SAME_IMAGES_IN_MASKS_BLOCK); - var positions = new Float32Array(count * 2); - iTransform = iFirstTransform; - for (q = 0; q < count; q++, iTransform += 4) { - transformArgs = argsArray[iTransform]; - positions[(q << 1)] = transformArgs[4]; - positions[(q << 1) + 1] = transformArgs[5]; - } - - // Replace queue items. - fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectRepeat); - argsArray.splice(iFirstSave, count * 4, - [firstPIMXOArg0, firstTransformArg0, firstTransformArg3, positions]); - } else { - count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK); - var images = []; - for (q = 0; q < count; q++) { - transformArgs = argsArray[iFirstTransform + (q << 2)]; - var maskParams = argsArray[iFirstPIMXO + (q << 2)][0]; - images.push({ data: maskParams.data, width: maskParams.width, - height: maskParams.height, - transform: transformArgs }); - } - - // Replace queue items. - fnArray.splice(iFirstSave, count * 4, OPS.paintImageMaskXObjectGroup); - argsArray.splice(iFirstSave, count * 4, [images]); - } - - return iFirstSave + 1; - }); - - // This replaces (save, transform, paintImageXObject, restore)+ sequences - // with one paintImageXObjectRepeat operation, if the |transform| and - // |paintImageXObjectRepeat| ops are appropriate. - addState(InitialState, - [OPS.save, OPS.transform, OPS.paintImageXObject, OPS.restore], - function (context) { - var MIN_IMAGES_IN_BLOCK = 3; - var MAX_IMAGES_IN_BLOCK = 1000; - - var fnArray = context.fnArray, argsArray = context.argsArray; - var curr = context.iCurr; - var iFirstSave = curr - 3; - var iFirstTransform = curr - 2; - var iFirstPIXO = curr - 1; - var iFirstRestore = curr; - - if (argsArray[iFirstTransform][1] !== 0 || - argsArray[iFirstTransform][2] !== 0) { - return iFirstRestore + 1; // transform has the wrong form - } - - // Look for the quartets. - var firstPIXOArg0 = argsArray[iFirstPIXO][0]; - var firstTransformArg0 = argsArray[iFirstTransform][0]; - var firstTransformArg3 = argsArray[iFirstTransform][3]; - var i = iFirstSave + 4; - var ii = fnArray.length; - while (i + 3 < ii) { - if (fnArray[i] !== OPS.save || - fnArray[i + 1] !== OPS.transform || - fnArray[i + 2] !== OPS.paintImageXObject || - fnArray[i + 3] !== OPS.restore) { - break; // ops don't match - } - if (argsArray[i + 1][0] !== firstTransformArg0 || - argsArray[i + 1][1] !== 0 || - argsArray[i + 1][2] !== 0 || - argsArray[i + 1][3] !== firstTransformArg3) { - break; // transforms don't match - } - if (argsArray[i + 2][0] !== firstPIXOArg0) { - break; // images don't match - } - i += 4; - } - - // At this point, i is the index of the first op past the last valid - // quartet. - var count = Math.min((i - iFirstSave) / 4, MAX_IMAGES_IN_BLOCK); - if (count < MIN_IMAGES_IN_BLOCK) { - return i; - } - - // Extract the (x,y) positions from all of the matching transforms. - var positions = new Float32Array(count * 2); - var iTransform = iFirstTransform; - for (var q = 0; q < count; q++, iTransform += 4) { - var transformArgs = argsArray[iTransform]; - positions[(q << 1)] = transformArgs[4]; - positions[(q << 1) + 1] = transformArgs[5]; - } - - // Replace queue items. - var args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, - positions]; - fnArray.splice(iFirstSave, count * 4, OPS.paintImageXObjectRepeat); - argsArray.splice(iFirstSave, count * 4, args); - - return iFirstSave + 1; - }); - - // This replaces (beginText, setFont, setTextMatrix, showText, endText)+ - // sequences with (beginText, setFont, (setTextMatrix, showText)+, endText)+ - // sequences, if the font for each one is the same. - addState(InitialState, - [OPS.beginText, OPS.setFont, OPS.setTextMatrix, OPS.showText, OPS.endText], - function (context) { - var MIN_CHARS_IN_BLOCK = 3; - var MAX_CHARS_IN_BLOCK = 1000; - - var fnArray = context.fnArray, argsArray = context.argsArray; - var curr = context.iCurr; - var iFirstBeginText = curr - 4; - var iFirstSetFont = curr - 3; - var iFirstSetTextMatrix = curr - 2; - var iFirstShowText = curr - 1; - var iFirstEndText = curr; - - // Look for the quintets. - var firstSetFontArg0 = argsArray[iFirstSetFont][0]; - var firstSetFontArg1 = argsArray[iFirstSetFont][1]; - var i = iFirstBeginText + 5; - var ii = fnArray.length; - while (i + 4 < ii) { - if (fnArray[i] !== OPS.beginText || - fnArray[i + 1] !== OPS.setFont || - fnArray[i + 2] !== OPS.setTextMatrix || - fnArray[i + 3] !== OPS.showText || - fnArray[i + 4] !== OPS.endText) { - break; // ops don't match - } - if (argsArray[i + 1][0] !== firstSetFontArg0 || - argsArray[i + 1][1] !== firstSetFontArg1) { - break; // fonts don't match - } - i += 5; - } - - // At this point, i is the index of the first op past the last valid - // quintet. - var count = Math.min(((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK); - if (count < MIN_CHARS_IN_BLOCK) { - return i; - } - - // If the preceding quintet is (, setFont, setTextMatrix, - // showText, endText), include that as well. (E.g. might be - // |dependency|.) - var iFirst = iFirstBeginText; - if (iFirstBeginText >= 4 && - fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] && - fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] && - fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] && - fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] && - argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 && - argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) { - count++; - iFirst -= 5; - } - - // Remove (endText, beginText, setFont) trios. - var iEndText = iFirst + 4; - for (var q = 1; q < count; q++) { - fnArray.splice(iEndText, 3); - argsArray.splice(iEndText, 3); - iEndText += 2; - } - - return iEndText + 1; - }); - - function QueueOptimizer() {} - - QueueOptimizer.prototype = { - optimize: function QueueOptimizer_optimize(queue) { - var fnArray = queue.fnArray, argsArray = queue.argsArray; - var context = { - iCurr: 0, - fnArray: fnArray, - argsArray: argsArray - }; - var state; - var i = 0, ii = fnArray.length; - while (i < ii) { - state = (state || InitialState)[fnArray[i]]; - if (typeof state === 'function') { // we found some handler - context.iCurr = i; - // state() returns the index of the first non-matching op (if we - // didn't match) or the first op past the modified ops (if we did - // match and replace). - i = state(context); - state = undefined; // reset the state machine - ii = context.fnArray.length; - } else { - i++; - } - } - } - }; - return QueueOptimizer; -})(); - - -var BUILT_IN_CMAPS = [ -// << Start unicode maps. -'Adobe-GB1-UCS2', -'Adobe-CNS1-UCS2', -'Adobe-Japan1-UCS2', -'Adobe-Korea1-UCS2', -// >> End unicode maps. -'78-EUC-H', -'78-EUC-V', -'78-H', -'78-RKSJ-H', -'78-RKSJ-V', -'78-V', -'78ms-RKSJ-H', -'78ms-RKSJ-V', -'83pv-RKSJ-H', -'90ms-RKSJ-H', -'90ms-RKSJ-V', -'90msp-RKSJ-H', -'90msp-RKSJ-V', -'90pv-RKSJ-H', -'90pv-RKSJ-V', -'Add-H', -'Add-RKSJ-H', -'Add-RKSJ-V', -'Add-V', -'Adobe-CNS1-0', -'Adobe-CNS1-1', -'Adobe-CNS1-2', -'Adobe-CNS1-3', -'Adobe-CNS1-4', -'Adobe-CNS1-5', -'Adobe-CNS1-6', -'Adobe-GB1-0', -'Adobe-GB1-1', -'Adobe-GB1-2', -'Adobe-GB1-3', -'Adobe-GB1-4', -'Adobe-GB1-5', -'Adobe-Japan1-0', -'Adobe-Japan1-1', -'Adobe-Japan1-2', -'Adobe-Japan1-3', -'Adobe-Japan1-4', -'Adobe-Japan1-5', -'Adobe-Japan1-6', -'Adobe-Korea1-0', -'Adobe-Korea1-1', -'Adobe-Korea1-2', -'B5-H', -'B5-V', -'B5pc-H', -'B5pc-V', -'CNS-EUC-H', -'CNS-EUC-V', -'CNS1-H', -'CNS1-V', -'CNS2-H', -'CNS2-V', -'ETHK-B5-H', -'ETHK-B5-V', -'ETen-B5-H', -'ETen-B5-V', -'ETenms-B5-H', -'ETenms-B5-V', -'EUC-H', -'EUC-V', -'Ext-H', -'Ext-RKSJ-H', -'Ext-RKSJ-V', -'Ext-V', -'GB-EUC-H', -'GB-EUC-V', -'GB-H', -'GB-V', -'GBK-EUC-H', -'GBK-EUC-V', -'GBK2K-H', -'GBK2K-V', -'GBKp-EUC-H', -'GBKp-EUC-V', -'GBT-EUC-H', -'GBT-EUC-V', -'GBT-H', -'GBT-V', -'GBTpc-EUC-H', -'GBTpc-EUC-V', -'GBpc-EUC-H', -'GBpc-EUC-V', -'H', -'HKdla-B5-H', -'HKdla-B5-V', -'HKdlb-B5-H', -'HKdlb-B5-V', -'HKgccs-B5-H', -'HKgccs-B5-V', -'HKm314-B5-H', -'HKm314-B5-V', -'HKm471-B5-H', -'HKm471-B5-V', -'HKscs-B5-H', -'HKscs-B5-V', -'Hankaku', -'Hiragana', -'KSC-EUC-H', -'KSC-EUC-V', -'KSC-H', -'KSC-Johab-H', -'KSC-Johab-V', -'KSC-V', -'KSCms-UHC-H', -'KSCms-UHC-HW-H', -'KSCms-UHC-HW-V', -'KSCms-UHC-V', -'KSCpc-EUC-H', -'KSCpc-EUC-V', -'Katakana', -'NWP-H', -'NWP-V', -'RKSJ-H', -'RKSJ-V', -'Roman', -'UniCNS-UCS2-H', -'UniCNS-UCS2-V', -'UniCNS-UTF16-H', -'UniCNS-UTF16-V', -'UniCNS-UTF32-H', -'UniCNS-UTF32-V', -'UniCNS-UTF8-H', -'UniCNS-UTF8-V', -'UniGB-UCS2-H', -'UniGB-UCS2-V', -'UniGB-UTF16-H', -'UniGB-UTF16-V', -'UniGB-UTF32-H', -'UniGB-UTF32-V', -'UniGB-UTF8-H', -'UniGB-UTF8-V', -'UniJIS-UCS2-H', -'UniJIS-UCS2-HW-H', -'UniJIS-UCS2-HW-V', -'UniJIS-UCS2-V', -'UniJIS-UTF16-H', -'UniJIS-UTF16-V', -'UniJIS-UTF32-H', -'UniJIS-UTF32-V', -'UniJIS-UTF8-H', -'UniJIS-UTF8-V', -'UniJIS2004-UTF16-H', -'UniJIS2004-UTF16-V', -'UniJIS2004-UTF32-H', -'UniJIS2004-UTF32-V', -'UniJIS2004-UTF8-H', -'UniJIS2004-UTF8-V', -'UniJISPro-UCS2-HW-V', -'UniJISPro-UCS2-V', -'UniJISPro-UTF8-V', -'UniJISX0213-UTF32-H', -'UniJISX0213-UTF32-V', -'UniJISX02132004-UTF32-H', -'UniJISX02132004-UTF32-V', -'UniKS-UCS2-H', -'UniKS-UCS2-V', -'UniKS-UTF16-H', -'UniKS-UTF16-V', -'UniKS-UTF32-H', -'UniKS-UTF32-V', -'UniKS-UTF8-H', -'UniKS-UTF8-V', -'V', -'WP-Symbol']; - -// CMap, not to be confused with TrueType's cmap. -var CMap = (function CMapClosure() { - function CMap(builtInCMap) { - // Codespace ranges are stored as follows: - // [[1BytePairs], [2BytePairs], [3BytePairs], [4BytePairs]] - // where nBytePairs are ranges e.g. [low1, high1, low2, high2, ...] - this.codespaceRanges = [[], [], [], []]; - this.numCodespaceRanges = 0; - // Map entries have one of two forms. - // - cid chars are 16-bit unsigned integers, stored as integers. - // - bf chars are variable-length byte sequences, stored as strings, with - // one byte per character. - this._map = []; - this.name = ''; - this.vertical = false; - this.useCMap = null; - this.builtInCMap = builtInCMap; - } - CMap.prototype = { - addCodespaceRange: function(n, low, high) { - this.codespaceRanges[n - 1].push(low, high); - this.numCodespaceRanges++; - }, - - mapCidRange: function(low, high, dstLow) { - while (low <= high) { - this._map[low++] = dstLow++; - } - }, - - mapBfRange: function(low, high, dstLow) { - var lastByte = dstLow.length - 1; - while (low <= high) { - this._map[low++] = dstLow; - // Only the last byte has to be incremented. - dstLow = dstLow.substr(0, lastByte) + - String.fromCharCode(dstLow.charCodeAt(lastByte) + 1); - } - }, - - mapBfRangeToArray: function(low, high, array) { - var i = 0, ii = array.length; - while (low <= high && i < ii) { - this._map[low] = array[i++]; - ++low; - } - }, - - // This is used for both bf and cid chars. - mapOne: function(src, dst) { - this._map[src] = dst; - }, - - lookup: function(code) { - return this._map[code]; - }, - - contains: function(code) { - return this._map[code] !== undefined; - }, - - forEach: function(callback) { - // Most maps have fewer than 65536 entries, and for those we use normal - // array iteration. But really sparse tables are possible -- e.g. with - // indices in the *billions*. For such tables we use for..in, which isn't - // ideal because it stringifies the indices for all present elements, but - // it does avoid iterating over every undefined entry. - var map = this._map; - var length = map.length; - var i; - if (length <= 0x10000) { - for (i = 0; i < length; i++) { - if (map[i] !== undefined) { - callback(i, map[i]); - } - } - } else { - for (i in this._map) { - callback(i, map[i]); - } - } - }, - - charCodeOf: function(value) { - return this._map.indexOf(value); - }, - - getMap: function() { - return this._map; - }, - - readCharCode: function(str, offset, out) { - var c = 0; - var codespaceRanges = this.codespaceRanges; - var codespaceRangesLen = this.codespaceRanges.length; - // 9.7.6.2 CMap Mapping - // The code length is at most 4. - for (var n = 0; n < codespaceRangesLen; n++) { - c = ((c << 8) | str.charCodeAt(offset + n)) >>> 0; - // Check each codespace range to see if it falls within. - var codespaceRange = codespaceRanges[n]; - for (var k = 0, kk = codespaceRange.length; k < kk;) { - var low = codespaceRange[k++]; - var high = codespaceRange[k++]; - if (c >= low && c <= high) { - out.charcode = c; - out.length = n + 1; - return; - } - } - } - out.charcode = 0; - out.length = 1; - }, - - get isIdentityCMap() { - if (!(this.name === 'Identity-H' || this.name === 'Identity-V')) { - return false; - } - if (this._map.length !== 0x10000) { - return false; - } - for (var i = 0; i < 0x10000; i++) { - if (this._map[i] !== i) { - return false; - } - } - return true; - } - }; - return CMap; -})(); - -// A special case of CMap, where the _map array implicitly has a length of -// 65536 and each element is equal to its index. -var IdentityCMap = (function IdentityCMapClosure() { - function IdentityCMap(vertical, n) { - CMap.call(this); - this.vertical = vertical; - this.addCodespaceRange(n, 0, 0xffff); - } - Util.inherit(IdentityCMap, CMap, {}); - - IdentityCMap.prototype = { - addCodespaceRange: CMap.prototype.addCodespaceRange, - - mapCidRange: function(low, high, dstLow) { - error('should not call mapCidRange'); - }, - - mapBfRange: function(low, high, dstLow) { - error('should not call mapBfRange'); - }, - - mapBfRangeToArray: function(low, high, array) { - error('should not call mapBfRangeToArray'); - }, - - mapOne: function(src, dst) { - error('should not call mapCidOne'); - }, - - lookup: function(code) { - return (isInt(code) && code <= 0xffff) ? code : undefined; - }, - - contains: function(code) { - return isInt(code) && code <= 0xffff; - }, - - forEach: function(callback) { - for (var i = 0; i <= 0xffff; i++) { - callback(i, i); - } - }, - - charCodeOf: function(value) { - return (isInt(value) && value <= 0xffff) ? value : -1; - }, - - getMap: function() { - // Sometimes identity maps must be instantiated, but it's rare. - var map = new Array(0x10000); - for (var i = 0; i <= 0xffff; i++) { - map[i] = i; - } - return map; - }, - - readCharCode: CMap.prototype.readCharCode, - - get isIdentityCMap() { - error('should not access .isIdentityCMap'); - } - }; - - return IdentityCMap; -})(); - -var BinaryCMapReader = (function BinaryCMapReaderClosure() { - function fetchBinaryData(url) { - var nonBinaryRequest = PDFJS.disableWorker; - var request = new XMLHttpRequest(); - request.open('GET', url, false); - if (!nonBinaryRequest) { - try { - request.responseType = 'arraybuffer'; - nonBinaryRequest = request.responseType !== 'arraybuffer'; - } catch (e) { - nonBinaryRequest = true; - } - } - if (nonBinaryRequest && request.overrideMimeType) { - request.overrideMimeType('text/plain; charset=x-user-defined'); - } - request.send(null); - if (nonBinaryRequest ? !request.responseText : !request.response) { - error('Unable to get binary cMap at: ' + url); - } - if (nonBinaryRequest) { - var data = Array.prototype.map.call(request.responseText, function (ch) { - return ch.charCodeAt(0) & 255; - }); - return new Uint8Array(data); - } - return new Uint8Array(request.response); - } - - function hexToInt(a, size) { - var n = 0; - for (var i = 0; i <= size; i++) { - n = (n << 8) | a[i]; - } - return n >>> 0; - } - - function hexToStr(a, size) { - // This code is hot. Special-case some common values to avoid creating an - // object with subarray(). - if (size === 1) { - return String.fromCharCode(a[0], a[1]); - } - if (size === 3) { - return String.fromCharCode(a[0], a[1], a[2], a[3]); - } - return String.fromCharCode.apply(null, a.subarray(0, size + 1)); - } - - function addHex(a, b, size) { - var c = 0; - for (var i = size; i >= 0; i--) { - c += a[i] + b[i]; - a[i] = c & 255; - c >>= 8; - } - } - - function incHex(a, size) { - var c = 1; - for (var i = size; i >= 0 && c > 0; i--) { - c += a[i]; - a[i] = c & 255; - c >>= 8; - } - } - - var MAX_NUM_SIZE = 16; - var MAX_ENCODED_NUM_SIZE = 19; // ceil(MAX_NUM_SIZE * 7 / 8) - - function BinaryCMapStream(data) { - this.buffer = data; - this.pos = 0; - this.end = data.length; - this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE); - } - - BinaryCMapStream.prototype = { - readByte: function () { - if (this.pos >= this.end) { - return -1; - } - return this.buffer[this.pos++]; - }, - readNumber: function () { - var n = 0; - var last; - do { - var b = this.readByte(); - if (b < 0) { - error('unexpected EOF in bcmap'); - } - last = !(b & 0x80); - n = (n << 7) | (b & 0x7F); - } while (!last); - return n; - }, - readSigned: function () { - var n = this.readNumber(); - return (n & 1) ? ~(n >>> 1) : n >>> 1; - }, - readHex: function (num, size) { - num.set(this.buffer.subarray(this.pos, - this.pos + size + 1)); - this.pos += size + 1; - }, - readHexNumber: function (num, size) { - var last; - var stack = this.tmpBuf, sp = 0; - do { - var b = this.readByte(); - if (b < 0) { - error('unexpected EOF in bcmap'); - } - last = !(b & 0x80); - stack[sp++] = b & 0x7F; - } while (!last); - var i = size, buffer = 0, bufferSize = 0; - while (i >= 0) { - while (bufferSize < 8 && stack.length > 0) { - buffer = (stack[--sp] << bufferSize) | buffer; - bufferSize += 7; - } - num[i] = buffer & 255; - i--; - buffer >>= 8; - bufferSize -= 8; - } - }, - readHexSigned: function (num, size) { - this.readHexNumber(num, size); - var sign = num[size] & 1 ? 255 : 0; - var c = 0; - for (var i = 0; i <= size; i++) { - c = ((c & 1) << 8) | num[i]; - num[i] = (c >> 1) ^ sign; - } - }, - readString: function () { - var len = this.readNumber(); - var s = ''; - for (var i = 0; i < len; i++) { - s += String.fromCharCode(this.readNumber()); - } - return s; - } - }; - - function processBinaryCMap(url, cMap, extend) { - var data = fetchBinaryData(url); - var stream = new BinaryCMapStream(data); - - var header = stream.readByte(); - cMap.vertical = !!(header & 1); - - var useCMap = null; - var start = new Uint8Array(MAX_NUM_SIZE); - var end = new Uint8Array(MAX_NUM_SIZE); - var char = new Uint8Array(MAX_NUM_SIZE); - var charCode = new Uint8Array(MAX_NUM_SIZE); - var tmp = new Uint8Array(MAX_NUM_SIZE); - var code; - - var b; - while ((b = stream.readByte()) >= 0) { - var type = b >> 5; - if (type === 7) { // metadata, e.g. comment or usecmap - switch (b & 0x1F) { - case 0: - stream.readString(); // skipping comment - break; - case 1: - useCMap = stream.readString(); - break; - } - continue; - } - var sequence = !!(b & 0x10); - var dataSize = b & 15; - - assert(dataSize + 1 <= MAX_NUM_SIZE); - - var ucs2DataSize = 1; - var subitemsCount = stream.readNumber(); - var i; - switch (type) { - case 0: // codespacerange - stream.readHex(start, dataSize); - stream.readHexNumber(end, dataSize); - addHex(end, start, dataSize); - cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), - hexToInt(end, dataSize)); - for (i = 1; i < subitemsCount; i++) { - incHex(end, dataSize); - stream.readHexNumber(start, dataSize); - addHex(start, end, dataSize); - stream.readHexNumber(end, dataSize); - addHex(end, start, dataSize); - cMap.addCodespaceRange(dataSize + 1, hexToInt(start, dataSize), - hexToInt(end, dataSize)); - } - break; - case 1: // notdefrange - stream.readHex(start, dataSize); - stream.readHexNumber(end, dataSize); - addHex(end, start, dataSize); - code = stream.readNumber(); - // undefined range, skipping - for (i = 1; i < subitemsCount; i++) { - incHex(end, dataSize); - stream.readHexNumber(start, dataSize); - addHex(start, end, dataSize); - stream.readHexNumber(end, dataSize); - addHex(end, start, dataSize); - code = stream.readNumber(); - // nop - } - break; - case 2: // cidchar - stream.readHex(char, dataSize); - code = stream.readNumber(); - cMap.mapOne(hexToInt(char, dataSize), code); - for (i = 1; i < subitemsCount; i++) { - incHex(char, dataSize); - if (!sequence) { - stream.readHexNumber(tmp, dataSize); - addHex(char, tmp, dataSize); - } - code = stream.readSigned() + (code + 1); - cMap.mapOne(hexToInt(char, dataSize), code); - } - break; - case 3: // cidrange - stream.readHex(start, dataSize); - stream.readHexNumber(end, dataSize); - addHex(end, start, dataSize); - code = stream.readNumber(); - cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), - code); - for (i = 1; i < subitemsCount; i++) { - incHex(end, dataSize); - if (!sequence) { - stream.readHexNumber(start, dataSize); - addHex(start, end, dataSize); - } else { - start.set(end); - } - stream.readHexNumber(end, dataSize); - addHex(end, start, dataSize); - code = stream.readNumber(); - cMap.mapCidRange(hexToInt(start, dataSize), hexToInt(end, dataSize), - code); - } - break; - case 4: // bfchar - stream.readHex(char, ucs2DataSize); - stream.readHex(charCode, dataSize); - cMap.mapOne(hexToInt(char, ucs2DataSize), - hexToStr(charCode, dataSize)); - for (i = 1; i < subitemsCount; i++) { - incHex(char, ucs2DataSize); - if (!sequence) { - stream.readHexNumber(tmp, ucs2DataSize); - addHex(char, tmp, ucs2DataSize); - } - incHex(charCode, dataSize); - stream.readHexSigned(tmp, dataSize); - addHex(charCode, tmp, dataSize); - cMap.mapOne(hexToInt(char, ucs2DataSize), - hexToStr(charCode, dataSize)); - } - break; - case 5: // bfrange - stream.readHex(start, ucs2DataSize); - stream.readHexNumber(end, ucs2DataSize); - addHex(end, start, ucs2DataSize); - stream.readHex(charCode, dataSize); - cMap.mapBfRange(hexToInt(start, ucs2DataSize), - hexToInt(end, ucs2DataSize), - hexToStr(charCode, dataSize)); - for (i = 1; i < subitemsCount; i++) { - incHex(end, ucs2DataSize); - if (!sequence) { - stream.readHexNumber(start, ucs2DataSize); - addHex(start, end, ucs2DataSize); - } else { - start.set(end); - } - stream.readHexNumber(end, ucs2DataSize); - addHex(end, start, ucs2DataSize); - stream.readHex(charCode, dataSize); - cMap.mapBfRange(hexToInt(start, ucs2DataSize), - hexToInt(end, ucs2DataSize), - hexToStr(charCode, dataSize)); - } - break; - default: - error('Unknown type: ' + type); - break; - } - } - - if (useCMap) { - extend(useCMap); - } - return cMap; - } - - function BinaryCMapReader() {} - - BinaryCMapReader.prototype = { - read: processBinaryCMap - }; - - return BinaryCMapReader; -})(); - -var CMapFactory = (function CMapFactoryClosure() { - function strToInt(str) { - var a = 0; - for (var i = 0; i < str.length; i++) { - a = (a << 8) | str.charCodeAt(i); - } - return a >>> 0; - } - - function expectString(obj) { - if (!isString(obj)) { - error('Malformed CMap: expected string.'); - } - } - - function expectInt(obj) { - if (!isInt(obj)) { - error('Malformed CMap: expected int.'); - } - } - - function parseBfChar(cMap, lexer) { - while (true) { - var obj = lexer.getObj(); - if (isEOF(obj)) { - break; - } - if (isCmd(obj, 'endbfchar')) { - return; - } - expectString(obj); - var src = strToInt(obj); - obj = lexer.getObj(); - // TODO are /dstName used? - expectString(obj); - var dst = obj; - cMap.mapOne(src, dst); - } - } - - function parseBfRange(cMap, lexer) { - while (true) { - var obj = lexer.getObj(); - if (isEOF(obj)) { - break; - } - if (isCmd(obj, 'endbfrange')) { - return; - } - expectString(obj); - var low = strToInt(obj); - obj = lexer.getObj(); - expectString(obj); - var high = strToInt(obj); - obj = lexer.getObj(); - if (isInt(obj) || isString(obj)) { - var dstLow = isInt(obj) ? String.fromCharCode(obj) : obj; - cMap.mapBfRange(low, high, dstLow); - } else if (isCmd(obj, '[')) { - obj = lexer.getObj(); - var array = []; - while (!isCmd(obj, ']') && !isEOF(obj)) { - array.push(obj); - obj = lexer.getObj(); - } - cMap.mapBfRangeToArray(low, high, array); - } else { - break; - } - } - error('Invalid bf range.'); - } - - function parseCidChar(cMap, lexer) { - while (true) { - var obj = lexer.getObj(); - if (isEOF(obj)) { - break; - } - if (isCmd(obj, 'endcidchar')) { - return; - } - expectString(obj); - var src = strToInt(obj); - obj = lexer.getObj(); - expectInt(obj); - var dst = obj; - cMap.mapOne(src, dst); - } - } - - function parseCidRange(cMap, lexer) { - while (true) { - var obj = lexer.getObj(); - if (isEOF(obj)) { - break; - } - if (isCmd(obj, 'endcidrange')) { - return; - } - expectString(obj); - var low = strToInt(obj); - obj = lexer.getObj(); - expectString(obj); - var high = strToInt(obj); - obj = lexer.getObj(); - expectInt(obj); - var dstLow = obj; - cMap.mapCidRange(low, high, dstLow); - } - } - - function parseCodespaceRange(cMap, lexer) { - while (true) { - var obj = lexer.getObj(); - if (isEOF(obj)) { - break; - } - if (isCmd(obj, 'endcodespacerange')) { - return; - } - if (!isString(obj)) { - break; - } - var low = strToInt(obj); - obj = lexer.getObj(); - if (!isString(obj)) { - break; - } - var high = strToInt(obj); - cMap.addCodespaceRange(obj.length, low, high); - } - error('Invalid codespace range.'); - } - - function parseWMode(cMap, lexer) { - var obj = lexer.getObj(); - if (isInt(obj)) { - cMap.vertical = !!obj; - } - } - - function parseCMapName(cMap, lexer) { - var obj = lexer.getObj(); - if (isName(obj) && isString(obj.name)) { - cMap.name = obj.name; - } - } - - function parseCMap(cMap, lexer, builtInCMapParams, useCMap) { - var previous; - var embededUseCMap; - objLoop: while (true) { - var obj = lexer.getObj(); - if (isEOF(obj)) { - break; - } else if (isName(obj)) { - if (obj.name === 'WMode') { - parseWMode(cMap, lexer); - } else if (obj.name === 'CMapName') { - parseCMapName(cMap, lexer); - } - previous = obj; - } else if (isCmd(obj)) { - switch (obj.cmd) { - case 'endcmap': - break objLoop; - case 'usecmap': - if (isName(previous)) { - embededUseCMap = previous.name; - } - break; - case 'begincodespacerange': - parseCodespaceRange(cMap, lexer); - break; - case 'beginbfchar': - parseBfChar(cMap, lexer); - break; - case 'begincidchar': - parseCidChar(cMap, lexer); - break; - case 'beginbfrange': - parseBfRange(cMap, lexer); - break; - case 'begincidrange': - parseCidRange(cMap, lexer); - break; - } - } - } - - if (!useCMap && embededUseCMap) { - // Load the usecmap definition from the file only if there wasn't one - // specified. - useCMap = embededUseCMap; - } - if (useCMap) { - extendCMap(cMap, builtInCMapParams, useCMap); - } - } - - function extendCMap(cMap, builtInCMapParams, useCMap) { - cMap.useCMap = createBuiltInCMap(useCMap, builtInCMapParams); - // If there aren't any code space ranges defined clone all the parent ones - // into this cMap. - if (cMap.numCodespaceRanges === 0) { - var useCodespaceRanges = cMap.useCMap.codespaceRanges; - for (var i = 0; i < useCodespaceRanges.length; i++) { - cMap.codespaceRanges[i] = useCodespaceRanges[i].slice(); - } - cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges; - } - // Merge the map into the current one, making sure not to override - // any previously defined entries. - cMap.useCMap.forEach(function(key, value) { - if (!cMap.contains(key)) { - cMap.mapOne(key, cMap.useCMap.lookup(key)); - } - }); - } - - function parseBinaryCMap(name, builtInCMapParams) { - var url = builtInCMapParams.url + name + '.bcmap'; - var cMap = new CMap(true); - new BinaryCMapReader().read(url, cMap, function (useCMap) { - extendCMap(cMap, builtInCMapParams, useCMap); - }); - return cMap; - } - - function createBuiltInCMap(name, builtInCMapParams) { - if (name === 'Identity-H') { - return new IdentityCMap(false, 2); - } else if (name === 'Identity-V') { - return new IdentityCMap(true, 2); - } - if (BUILT_IN_CMAPS.indexOf(name) === -1) { - error('Unknown cMap name: ' + name); - } - assert(builtInCMapParams, 'built-in cMap parameters are not provided'); - - if (builtInCMapParams.packed) { - return parseBinaryCMap(name, builtInCMapParams); - } - - var request = new XMLHttpRequest(); - var url = builtInCMapParams.url + name; - request.open('GET', url, false); - request.send(null); - if (!request.responseText) { - error('Unable to get cMap at: ' + url); - } - var cMap = new CMap(true); - var lexer = new Lexer(new StringStream(request.responseText)); - parseCMap(cMap, lexer, builtInCMapParams, null); - return cMap; - } - - return { - create: function (encoding, builtInCMapParams, useCMap) { - if (isName(encoding)) { - return createBuiltInCMap(encoding.name, builtInCMapParams); - } else if (isStream(encoding)) { - var cMap = new CMap(); - var lexer = new Lexer(encoding); - try { - parseCMap(cMap, lexer, builtInCMapParams, useCMap); - } catch (e) { - warn('Invalid CMap data. ' + e); - } - if (cMap.isIdentityCMap) { - return createBuiltInCMap(cMap.name, builtInCMapParams); - } - return cMap; - } - error('Encoding required.'); - } - }; -})(); - - -// Unicode Private Use Area -var PRIVATE_USE_OFFSET_START = 0xE000; -var PRIVATE_USE_OFFSET_END = 0xF8FF; -var SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = false; - -// PDF Glyph Space Units are one Thousandth of a TextSpace Unit -// except for Type 3 fonts -var PDF_GLYPH_SPACE_UNITS = 1000; - -// Hinting is currently disabled due to unknown problems on windows -// in tracemonkey and various other pdfs with type1 fonts. -var HINTING_ENABLED = false; - -// Accented charactars are not displayed properly on windows, using this flag -// to control analysis of seac charstrings. -var SEAC_ANALYSIS_ENABLED = false; - -var FontFlags = { - FixedPitch: 1, - Serif: 2, - Symbolic: 4, - Script: 8, - Nonsymbolic: 32, - Italic: 64, - AllCap: 65536, - SmallCap: 131072, - ForceBold: 262144 -}; - -var Encodings = { - ExpertEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclamsmall', 'Hungarumlautsmall', '', 'dollaroldstyle', - 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', - 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', - 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', - 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', - 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'colon', - 'semicolon', 'commasuperior', 'threequartersemdash', 'periodsuperior', - 'questionsmall', '', 'asuperior', 'bsuperior', 'centsuperior', 'dsuperior', - 'esuperior', '', '', 'isuperior', '', '', 'lsuperior', 'msuperior', - 'nsuperior', 'osuperior', '', '', 'rsuperior', 'ssuperior', 'tsuperior', - '', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', '', - 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', - 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', - 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', - 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', - 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', - 'onefitted', 'rupiah', 'Tildesmall', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', 'exclamdownsmall', 'centoldstyle', 'Lslashsmall', - '', '', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall', - 'Caronsmall', '', 'Dotaccentsmall', '', '', 'Macronsmall', '', '', - 'figuredash', 'hypheninferior', '', '', 'Ogoneksmall', 'Ringsmall', - 'Cedillasmall', '', '', '', 'onequarter', 'onehalf', 'threequarters', - 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', '', '', 'zerosuperior', - 'onesuperior', 'twosuperior', 'threesuperior', 'foursuperior', - 'fivesuperior', 'sixsuperior', 'sevensuperior', 'eightsuperior', - 'ninesuperior', 'zeroinferior', 'oneinferior', 'twoinferior', - 'threeinferior', 'fourinferior', 'fiveinferior', 'sixinferior', - 'seveninferior', 'eightinferior', 'nineinferior', 'centinferior', - 'dollarinferior', 'periodinferior', 'commainferior', 'Agravesmall', - 'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', - 'Aringsmall', 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', - 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', - 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', - 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', - 'Ydieresissmall'], - MacExpertEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclamsmall', 'Hungarumlautsmall', 'centoldstyle', - 'dollaroldstyle', 'dollarsuperior', 'ampersandsmall', 'Acutesmall', - 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', - 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', 'zerooldstyle', - 'oneoldstyle', 'twooldstyle', 'threeoldstyle', 'fouroldstyle', - 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', - 'nineoldstyle', 'colon', 'semicolon', '', 'threequartersemdash', '', - 'questionsmall', '', '', '', '', 'Ethsmall', '', '', 'onequarter', - 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', - 'seveneighths', 'onethird', 'twothirds', '', '', '', '', '', '', 'ff', - 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', '', 'parenrightinferior', - 'Circumflexsmall', 'hypheninferior', 'Gravesmall', 'Asmall', 'Bsmall', - 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall', - 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', 'Osmall', 'Psmall', - 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall', - 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', - 'Tildesmall', '', '', 'asuperior', 'centsuperior', '', '', '', '', - 'Aacutesmall', 'Agravesmall', 'Acircumflexsmall', 'Adieresissmall', - 'Atildesmall', 'Aringsmall', 'Ccedillasmall', 'Eacutesmall', 'Egravesmall', - 'Ecircumflexsmall', 'Edieresissmall', 'Iacutesmall', 'Igravesmall', - 'Icircumflexsmall', 'Idieresissmall', 'Ntildesmall', 'Oacutesmall', - 'Ogravesmall', 'Ocircumflexsmall', 'Odieresissmall', 'Otildesmall', - 'Uacutesmall', 'Ugravesmall', 'Ucircumflexsmall', 'Udieresissmall', '', - 'eightsuperior', 'fourinferior', 'threeinferior', 'sixinferior', - 'eightinferior', 'seveninferior', 'Scaronsmall', '', 'centinferior', - 'twoinferior', '', 'Dieresissmall', '', 'Caronsmall', 'osuperior', - 'fiveinferior', '', 'commainferior', 'periodinferior', 'Yacutesmall', '', - 'dollarinferior', '', 'Thornsmall', '', 'nineinferior', 'zeroinferior', - 'Zcaronsmall', 'AEsmall', 'Oslashsmall', 'questiondownsmall', - 'oneinferior', 'Lslashsmall', '', '', '', '', '', '', 'Cedillasmall', '', - '', '', '', '', 'OEsmall', 'figuredash', 'hyphensuperior', '', '', '', '', - 'exclamdownsmall', '', 'Ydieresissmall', '', 'onesuperior', 'twosuperior', - 'threesuperior', 'foursuperior', 'fivesuperior', 'sixsuperior', - 'sevensuperior', 'ninesuperior', 'zerosuperior', '', 'esuperior', - 'rsuperior', 'tsuperior', '', '', 'isuperior', 'ssuperior', 'dsuperior', - '', '', '', '', '', 'lsuperior', 'Ogoneksmall', 'Brevesmall', - 'Macronsmall', 'bsuperior', 'nsuperior', 'msuperior', 'commasuperior', - 'periodsuperior', 'Dotaccentsmall', 'Ringsmall'], - MacRomanEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', - 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', - 'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', - 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', '', - 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 'Odieresis', - 'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', 'atilde', - 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', - 'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', - 'ograve', 'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave', - 'ucircumflex', 'udieresis', 'dagger', 'degree', 'cent', 'sterling', - 'section', 'bullet', 'paragraph', 'germandbls', 'registered', 'copyright', - 'trademark', 'acute', 'dieresis', 'notequal', 'AE', 'Oslash', 'infinity', - 'plusminus', 'lessequal', 'greaterequal', 'yen', 'mu', 'partialdiff', - 'summation', 'product', 'pi', 'integral', 'ordfeminine', 'ordmasculine', - 'Omega', 'ae', 'oslash', 'questiondown', 'exclamdown', 'logicalnot', - 'radical', 'florin', 'approxequal', 'Delta', 'guillemotleft', - 'guillemotright', 'ellipsis', 'space', 'Agrave', 'Atilde', 'Otilde', 'OE', - 'oe', 'endash', 'emdash', 'quotedblleft', 'quotedblright', 'quoteleft', - 'quoteright', 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', - 'currency', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', - 'periodcentered', 'quotesinglbase', 'quotedblbase', 'perthousand', - 'Acircumflex', 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', - 'Icircumflex', 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', - 'Ograve', 'Uacute', 'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex', - 'tilde', 'macron', 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', - 'ogonek', 'caron'], - StandardEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', - 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', - 'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', - 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', - 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'exclamdown', - 'cent', 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', - 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', - 'guilsinglright', 'fi', 'fl', '', 'endash', 'dagger', 'daggerdbl', - 'periodcentered', '', 'paragraph', 'bullet', 'quotesinglbase', - 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', - 'perthousand', '', 'questiondown', '', 'grave', 'acute', 'circumflex', - 'tilde', 'macron', 'breve', 'dotaccent', 'dieresis', '', 'ring', 'cedilla', - '', 'hungarumlaut', 'ogonek', 'caron', 'emdash', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', 'AE', '', 'ordfeminine', '', '', - '', '', 'Lslash', 'Oslash', 'OE', 'ordmasculine', '', '', '', '', '', 'ae', - '', '', '', 'dotlessi', '', '', 'lslash', 'oslash', 'oe', 'germandbls'], - WinAnsiEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', - 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', - 'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', - 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', - 'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', - 'bullet', 'Euro', 'bullet', 'quotesinglbase', 'florin', 'quotedblbase', - 'ellipsis', 'dagger', 'daggerdbl', 'circumflex', 'perthousand', 'Scaron', - 'guilsinglleft', 'OE', 'bullet', 'Zcaron', 'bullet', 'bullet', 'quoteleft', - 'quoteright', 'quotedblleft', 'quotedblright', 'bullet', 'endash', - 'emdash', 'tilde', 'trademark', 'scaron', 'guilsinglright', 'oe', 'bullet', - 'zcaron', 'Ydieresis', 'space', 'exclamdown', 'cent', 'sterling', - 'currency', 'yen', 'brokenbar', 'section', 'dieresis', 'copyright', - 'ordfeminine', 'guillemotleft', 'logicalnot', 'hyphen', 'registered', - 'macron', 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute', - 'mu', 'paragraph', 'periodcentered', 'cedilla', 'onesuperior', - 'ordmasculine', 'guillemotright', 'onequarter', 'onehalf', 'threequarters', - 'questiondown', 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', 'Adieresis', - 'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', - 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Eth', 'Ntilde', 'Ograve', - 'Oacute', 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', 'Oslash', - 'Ugrave', 'Uacute', 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn', - 'germandbls', 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis', - 'aring', 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis', - 'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde', 'ograve', - 'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', 'oslash', - 'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', 'thorn', - 'ydieresis'], - SymbolSetEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'exclam', 'universal', 'numbersign', 'existential', 'percent', - 'ampersand', 'suchthat', 'parenleft', 'parenright', 'asteriskmath', 'plus', - 'comma', 'minus', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', - 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', - 'equal', 'greater', 'question', 'congruent', 'Alpha', 'Beta', 'Chi', - 'Delta', 'Epsilon', 'Phi', 'Gamma', 'Eta', 'Iota', 'theta1', 'Kappa', - 'Lambda', 'Mu', 'Nu', 'Omicron', 'Pi', 'Theta', 'Rho', 'Sigma', 'Tau', - 'Upsilon', 'sigma1', 'Omega', 'Xi', 'Psi', 'Zeta', 'bracketleft', - 'therefore', 'bracketright', 'perpendicular', 'underscore', 'radicalex', - 'alpha', 'beta', 'chi', 'delta', 'epsilon', 'phi', 'gamma', 'eta', 'iota', - 'phi1', 'kappa', 'lambda', 'mu', 'nu', 'omicron', 'pi', 'theta', 'rho', - 'sigma', 'tau', 'upsilon', 'omega1', 'omega', 'xi', 'psi', 'zeta', - 'braceleft', 'bar', 'braceright', 'similar', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', 'Euro', 'Upsilon1', 'minute', 'lessequal', - 'fraction', 'infinity', 'florin', 'club', 'diamond', 'heart', 'spade', - 'arrowboth', 'arrowleft', 'arrowup', 'arrowright', 'arrowdown', 'degree', - 'plusminus', 'second', 'greaterequal', 'multiply', 'proportional', - 'partialdiff', 'bullet', 'divide', 'notequal', 'equivalence', - 'approxequal', 'ellipsis', 'arrowvertex', 'arrowhorizex', 'carriagereturn', - 'aleph', 'Ifraktur', 'Rfraktur', 'weierstrass', 'circlemultiply', - 'circleplus', 'emptyset', 'intersection', 'union', 'propersuperset', - 'reflexsuperset', 'notsubset', 'propersubset', 'reflexsubset', 'element', - 'notelement', 'angle', 'gradient', 'registerserif', 'copyrightserif', - 'trademarkserif', 'product', 'radical', 'dotmath', 'logicalnot', - 'logicaland', 'logicalor', 'arrowdblboth', 'arrowdblleft', 'arrowdblup', - 'arrowdblright', 'arrowdbldown', 'lozenge', 'angleleft', 'registersans', - 'copyrightsans', 'trademarksans', 'summation', 'parenlefttp', - 'parenleftex', 'parenleftbt', 'bracketlefttp', 'bracketleftex', - 'bracketleftbt', 'bracelefttp', 'braceleftmid', 'braceleftbt', 'braceex', - '', 'angleright', 'integral', 'integraltp', 'integralex', 'integralbt', - 'parenrighttp', 'parenrightex', 'parenrightbt', 'bracketrighttp', - 'bracketrightex', 'bracketrightbt', 'bracerighttp', 'bracerightmid', - 'bracerightbt'], - ZapfDingbatsEncoding: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', - 'space', 'a1', 'a2', 'a202', 'a3', 'a4', 'a5', 'a119', 'a118', 'a117', - 'a11', 'a12', 'a13', 'a14', 'a15', 'a16', 'a105', 'a17', 'a18', 'a19', - 'a20', 'a21', 'a22', 'a23', 'a24', 'a25', 'a26', 'a27', 'a28', 'a6', 'a7', - 'a8', 'a9', 'a10', 'a29', 'a30', 'a31', 'a32', 'a33', 'a34', 'a35', 'a36', - 'a37', 'a38', 'a39', 'a40', 'a41', 'a42', 'a43', 'a44', 'a45', 'a46', - 'a47', 'a48', 'a49', 'a50', 'a51', 'a52', 'a53', 'a54', 'a55', 'a56', - 'a57', 'a58', 'a59', 'a60', 'a61', 'a62', 'a63', 'a64', 'a65', 'a66', - 'a67', 'a68', 'a69', 'a70', 'a71', 'a72', 'a73', 'a74', 'a203', 'a75', - 'a204', 'a76', 'a77', 'a78', 'a79', 'a81', 'a82', 'a83', 'a84', 'a97', - 'a98', 'a99', 'a100', '', 'a89', 'a90', 'a93', 'a94', 'a91', 'a92', 'a205', - 'a85', 'a206', 'a86', 'a87', 'a88', 'a95', 'a96', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', 'a101', 'a102', 'a103', - 'a104', 'a106', 'a107', 'a108', 'a112', 'a111', 'a110', 'a109', 'a120', - 'a121', 'a122', 'a123', 'a124', 'a125', 'a126', 'a127', 'a128', 'a129', - 'a130', 'a131', 'a132', 'a133', 'a134', 'a135', 'a136', 'a137', 'a138', - 'a139', 'a140', 'a141', 'a142', 'a143', 'a144', 'a145', 'a146', 'a147', - 'a148', 'a149', 'a150', 'a151', 'a152', 'a153', 'a154', 'a155', 'a156', - 'a157', 'a158', 'a159', 'a160', 'a161', 'a163', 'a164', 'a196', 'a165', - 'a192', 'a166', 'a167', 'a168', 'a169', 'a170', 'a171', 'a172', 'a173', - 'a162', 'a174', 'a175', 'a176', 'a177', 'a178', 'a179', 'a193', 'a180', - 'a199', 'a181', 'a200', 'a182', '', 'a201', 'a183', 'a184', 'a197', 'a185', - 'a194', 'a198', 'a186', 'a195', 'a187', 'a188', 'a189', 'a190', 'a191'] -}; - -/** - * Hold a map of decoded fonts and of the standard fourteen Type1 - * fonts and their acronyms. - */ -var stdFontMap = { - 'ArialNarrow': 'Helvetica', - 'ArialNarrow-Bold': 'Helvetica-Bold', - 'ArialNarrow-BoldItalic': 'Helvetica-BoldOblique', - 'ArialNarrow-Italic': 'Helvetica-Oblique', - 'ArialBlack': 'Helvetica', - 'ArialBlack-Bold': 'Helvetica-Bold', - 'ArialBlack-BoldItalic': 'Helvetica-BoldOblique', - 'ArialBlack-Italic': 'Helvetica-Oblique', - 'Arial': 'Helvetica', - 'Arial-Bold': 'Helvetica-Bold', - 'Arial-BoldItalic': 'Helvetica-BoldOblique', - 'Arial-Italic': 'Helvetica-Oblique', - 'Arial-BoldItalicMT': 'Helvetica-BoldOblique', - 'Arial-BoldMT': 'Helvetica-Bold', - 'Arial-ItalicMT': 'Helvetica-Oblique', - 'ArialMT': 'Helvetica', - 'Courier-Bold': 'Courier-Bold', - 'Courier-BoldItalic': 'Courier-BoldOblique', - 'Courier-Italic': 'Courier-Oblique', - 'CourierNew': 'Courier', - 'CourierNew-Bold': 'Courier-Bold', - 'CourierNew-BoldItalic': 'Courier-BoldOblique', - 'CourierNew-Italic': 'Courier-Oblique', - 'CourierNewPS-BoldItalicMT': 'Courier-BoldOblique', - 'CourierNewPS-BoldMT': 'Courier-Bold', - 'CourierNewPS-ItalicMT': 'Courier-Oblique', - 'CourierNewPSMT': 'Courier', - 'Helvetica': 'Helvetica', - 'Helvetica-Bold': 'Helvetica-Bold', - 'Helvetica-BoldItalic': 'Helvetica-BoldOblique', - 'Helvetica-BoldOblique': 'Helvetica-BoldOblique', - 'Helvetica-Italic': 'Helvetica-Oblique', - 'Helvetica-Oblique':'Helvetica-Oblique', - 'Symbol-Bold': 'Symbol', - 'Symbol-BoldItalic': 'Symbol', - 'Symbol-Italic': 'Symbol', - 'TimesNewRoman': 'Times-Roman', - 'TimesNewRoman-Bold': 'Times-Bold', - 'TimesNewRoman-BoldItalic': 'Times-BoldItalic', - 'TimesNewRoman-Italic': 'Times-Italic', - 'TimesNewRomanPS': 'Times-Roman', - 'TimesNewRomanPS-Bold': 'Times-Bold', - 'TimesNewRomanPS-BoldItalic': 'Times-BoldItalic', - 'TimesNewRomanPS-BoldItalicMT': 'Times-BoldItalic', - 'TimesNewRomanPS-BoldMT': 'Times-Bold', - 'TimesNewRomanPS-Italic': 'Times-Italic', - 'TimesNewRomanPS-ItalicMT': 'Times-Italic', - 'TimesNewRomanPSMT': 'Times-Roman', - 'TimesNewRomanPSMT-Bold': 'Times-Bold', - 'TimesNewRomanPSMT-BoldItalic': 'Times-BoldItalic', - 'TimesNewRomanPSMT-Italic': 'Times-Italic' -}; - -/** - * Holds the map of the non-standard fonts that might be included as a standard - * fonts without glyph data. - */ -var nonStdFontMap = { - 'CenturyGothic': 'Helvetica', - 'CenturyGothic-Bold': 'Helvetica-Bold', - 'CenturyGothic-BoldItalic': 'Helvetica-BoldOblique', - 'CenturyGothic-Italic': 'Helvetica-Oblique', - 'ComicSansMS': 'Comic Sans MS', - 'ComicSansMS-Bold': 'Comic Sans MS-Bold', - 'ComicSansMS-BoldItalic': 'Comic Sans MS-BoldItalic', - 'ComicSansMS-Italic': 'Comic Sans MS-Italic', - 'LucidaConsole': 'Courier', - 'LucidaConsole-Bold': 'Courier-Bold', - 'LucidaConsole-BoldItalic': 'Courier-BoldOblique', - 'LucidaConsole-Italic': 'Courier-Oblique', - 'MS-Gothic': 'MS Gothic', - 'MS-Gothic-Bold': 'MS Gothic-Bold', - 'MS-Gothic-BoldItalic': 'MS Gothic-BoldItalic', - 'MS-Gothic-Italic': 'MS Gothic-Italic', - 'MS-Mincho': 'MS Mincho', - 'MS-Mincho-Bold': 'MS Mincho-Bold', - 'MS-Mincho-BoldItalic': 'MS Mincho-BoldItalic', - 'MS-Mincho-Italic': 'MS Mincho-Italic', - 'MS-PGothic': 'MS PGothic', - 'MS-PGothic-Bold': 'MS PGothic-Bold', - 'MS-PGothic-BoldItalic': 'MS PGothic-BoldItalic', - 'MS-PGothic-Italic': 'MS PGothic-Italic', - 'MS-PMincho': 'MS PMincho', - 'MS-PMincho-Bold': 'MS PMincho-Bold', - 'MS-PMincho-BoldItalic': 'MS PMincho-BoldItalic', - 'MS-PMincho-Italic': 'MS PMincho-Italic', - 'Wingdings': 'ZapfDingbats' -}; - -var serifFonts = { - 'Adobe Jenson': true, 'Adobe Text': true, 'Albertus': true, - 'Aldus': true, 'Alexandria': true, 'Algerian': true, - 'American Typewriter': true, 'Antiqua': true, 'Apex': true, - 'Arno': true, 'Aster': true, 'Aurora': true, - 'Baskerville': true, 'Bell': true, 'Bembo': true, - 'Bembo Schoolbook': true, 'Benguiat': true, 'Berkeley Old Style': true, - 'Bernhard Modern': true, 'Berthold City': true, 'Bodoni': true, - 'Bauer Bodoni': true, 'Book Antiqua': true, 'Bookman': true, - 'Bordeaux Roman': true, 'Californian FB': true, 'Calisto': true, - 'Calvert': true, 'Capitals': true, 'Cambria': true, - 'Cartier': true, 'Caslon': true, 'Catull': true, - 'Centaur': true, 'Century Old Style': true, 'Century Schoolbook': true, - 'Chaparral': true, 'Charis SIL': true, 'Cheltenham': true, - 'Cholla Slab': true, 'Clarendon': true, 'Clearface': true, - 'Cochin': true, 'Colonna': true, 'Computer Modern': true, - 'Concrete Roman': true, 'Constantia': true, 'Cooper Black': true, - 'Corona': true, 'Ecotype': true, 'Egyptienne': true, - 'Elephant': true, 'Excelsior': true, 'Fairfield': true, - 'FF Scala': true, 'Folkard': true, 'Footlight': true, - 'FreeSerif': true, 'Friz Quadrata': true, 'Garamond': true, - 'Gentium': true, 'Georgia': true, 'Gloucester': true, - 'Goudy Old Style': true, 'Goudy Schoolbook': true, 'Goudy Pro Font': true, - 'Granjon': true, 'Guardian Egyptian': true, 'Heather': true, - 'Hercules': true, 'High Tower Text': true, 'Hiroshige': true, - 'Hoefler Text': true, 'Humana Serif': true, 'Imprint': true, - 'Ionic No. 5': true, 'Janson': true, 'Joanna': true, - 'Korinna': true, 'Lexicon': true, 'Liberation Serif': true, - 'Linux Libertine': true, 'Literaturnaya': true, 'Lucida': true, - 'Lucida Bright': true, 'Melior': true, 'Memphis': true, - 'Miller': true, 'Minion': true, 'Modern': true, - 'Mona Lisa': true, 'Mrs Eaves': true, 'MS Serif': true, - 'Museo Slab': true, 'New York': true, 'Nimbus Roman': true, - 'NPS Rawlinson Roadway': true, 'Palatino': true, 'Perpetua': true, - 'Plantin': true, 'Plantin Schoolbook': true, 'Playbill': true, - 'Poor Richard': true, 'Rawlinson Roadway': true, 'Renault': true, - 'Requiem': true, 'Rockwell': true, 'Roman': true, - 'Rotis Serif': true, 'Sabon': true, 'Scala': true, - 'Seagull': true, 'Sistina': true, 'Souvenir': true, - 'STIX': true, 'Stone Informal': true, 'Stone Serif': true, - 'Sylfaen': true, 'Times': true, 'Trajan': true, - 'Trinité': true, 'Trump Mediaeval': true, 'Utopia': true, - 'Vale Type': true, 'Bitstream Vera': true, 'Vera Serif': true, - 'Versailles': true, 'Wanted': true, 'Weiss': true, - 'Wide Latin': true, 'Windsor': true, 'XITS': true -}; - -var symbolsFonts = { - 'Dingbats': true, 'Symbol': true, 'ZapfDingbats': true -}; - -// Glyph map for well-known standard fonts. Sometimes Ghostscript uses CID fonts -// but does not embed the CID to GID mapping. The mapping is incomplete for all -// glyphs, but common for some set of the standard fonts. -var GlyphMapForStandardFonts = { - '2': 10, '3': 32, '4': 33, '5': 34, '6': 35, '7': 36, '8': 37, '9': 38, - '10': 39, '11': 40, '12': 41, '13': 42, '14': 43, '15': 44, '16': 45, - '17': 46, '18': 47, '19': 48, '20': 49, '21': 50, '22': 51, '23': 52, - '24': 53, '25': 54, '26': 55, '27': 56, '28': 57, '29': 58, '30': 894, - '31': 60, '32': 61, '33': 62, '34': 63, '35': 64, '36': 65, '37': 66, - '38': 67, '39': 68, '40': 69, '41': 70, '42': 71, '43': 72, '44': 73, - '45': 74, '46': 75, '47': 76, '48': 77, '49': 78, '50': 79, '51': 80, - '52': 81, '53': 82, '54': 83, '55': 84, '56': 85, '57': 86, '58': 87, - '59': 88, '60': 89, '61': 90, '62': 91, '63': 92, '64': 93, '65': 94, - '66': 95, '67': 96, '68': 97, '69': 98, '70': 99, '71': 100, '72': 101, - '73': 102, '74': 103, '75': 104, '76': 105, '77': 106, '78': 107, '79': 108, - '80': 109, '81': 110, '82': 111, '83': 112, '84': 113, '85': 114, '86': 115, - '87': 116, '88': 117, '89': 118, '90': 119, '91': 120, '92': 121, '93': 122, - '94': 123, '95': 124, '96': 125, '97': 126, '98': 196, '99': 197, '100': 199, - '101': 201, '102': 209, '103': 214, '104': 220, '105': 225, '106': 224, - '107': 226, '108': 228, '109': 227, '110': 229, '111': 231, '112': 233, - '113': 232, '114': 234, '115': 235, '116': 237, '117': 236, '118': 238, - '119': 239, '120': 241, '121': 243, '122': 242, '123': 244, '124': 246, - '125': 245, '126': 250, '127': 249, '128': 251, '129': 252, '130': 8224, - '131': 176, '132': 162, '133': 163, '134': 167, '135': 8226, '136': 182, - '137': 223, '138': 174, '139': 169, '140': 8482, '141': 180, '142': 168, - '143': 8800, '144': 198, '145': 216, '146': 8734, '147': 177, '148': 8804, - '149': 8805, '150': 165, '151': 181, '152': 8706, '153': 8721, '154': 8719, - '156': 8747, '157': 170, '158': 186, '159': 8486, '160': 230, '161': 248, - '162': 191, '163': 161, '164': 172, '165': 8730, '166': 402, '167': 8776, - '168': 8710, '169': 171, '170': 187, '171': 8230, '210': 218, '223': 711, - '224': 321, '225': 322, '227': 353, '229': 382, '234': 253, '252': 263, - '253': 268, '254': 269, '258': 258, '260': 260, '261': 261, '265': 280, - '266': 281, '268': 283, '269': 313, '275': 323, '276': 324, '278': 328, - '284': 345, '285': 346, '286': 347, '292': 367, '295': 377, '296': 378, - '298': 380, '305': 963, - '306': 964, '307': 966, '308': 8215, '309': 8252, '310': 8319, '311': 8359, - '312': 8592, '313': 8593, '337': 9552, '493': 1039, '494': 1040, '705': 1524, - '706': 8362, '710': 64288, '711': 64298, '759': 1617, '761': 1776, - '763': 1778, '775': 1652, '777': 1764, '778': 1780, '779': 1781, '780': 1782, - '782': 771, '783': 64726, '786': 8363, '788': 8532, '790': 768, '791': 769, - '792': 768, '795': 803, '797': 64336, '798': 64337, '799': 64342, - '800': 64343, '801': 64344, '802': 64345, '803': 64362, '804': 64363, - '805': 64364, '2424': 7821, '2425': 7822, '2426': 7823, '2427': 7824, - '2428': 7825, '2429': 7826, '2430': 7827, '2433': 7682, '2678': 8045, - '2679': 8046, '2830': 1552, '2838': 686, '2840': 751, '2842': 753, - '2843': 754, '2844': 755, '2846': 757, '2856': 767, '2857': 848, '2858': 849, - '2862': 853, '2863': 854, '2864': 855, '2865': 861, '2866': 862, '2906': 7460, - '2908': 7462, '2909': 7463, '2910': 7464, '2912': 7466, '2913': 7467, - '2914': 7468, '2916': 7470, '2917': 7471, '2918': 7472, '2920': 7474, - '2921': 7475, '2922': 7476, '2924': 7478, '2925': 7479, '2926': 7480, - '2928': 7482, '2929': 7483, '2930': 7484, '2932': 7486, '2933': 7487, - '2934': 7488, '2936': 7490, '2937': 7491, '2938': 7492, '2940': 7494, - '2941': 7495, '2942': 7496, '2944': 7498, '2946': 7500, '2948': 7502, - '2950': 7504, '2951': 7505, '2952': 7506, '2954': 7508, '2955': 7509, - '2956': 7510, '2958': 7512, '2959': 7513, '2960': 7514, '2962': 7516, - '2963': 7517, '2964': 7518, '2966': 7520, '2967': 7521, '2968': 7522, - '2970': 7524, '2971': 7525, '2972': 7526, '2974': 7528, '2975': 7529, - '2976': 7530, '2978': 1537, '2979': 1538, '2980': 1539, '2982': 1549, - '2983': 1551, '2984': 1552, '2986': 1554, '2987': 1555, '2988': 1556, - '2990': 1623, '2991': 1624, '2995': 1775, '2999': 1791, '3002': 64290, - '3003': 64291, '3004': 64292, '3006': 64294, '3007': 64295, '3008': 64296, - '3011': 1900, '3014': 8223, '3015': 8244, '3017': 7532, '3018': 7533, - '3019': 7534, '3075': 7590, '3076': 7591, '3079': 7594, '3080': 7595, - '3083': 7598, '3084': 7599, '3087': 7602, '3088': 7603, '3091': 7606, - '3092': 7607, '3095': 7610, '3096': 7611, '3099': 7614, '3100': 7615, - '3103': 7618, '3104': 7619, '3107': 8337, '3108': 8338, '3116': 1884, - '3119': 1885, '3120': 1885, '3123': 1886, '3124': 1886, '3127': 1887, - '3128': 1887, '3131': 1888, '3132': 1888, '3135': 1889, '3136': 1889, - '3139': 1890, '3140': 1890, '3143': 1891, '3144': 1891, '3147': 1892, - '3148': 1892, '3153': 580, '3154': 581, '3157': 584, '3158': 585, '3161': 588, - '3162': 589, '3165': 891, '3166': 892, '3169': 1274, '3170': 1275, - '3173': 1278, '3174': 1279, '3181': 7622, '3182': 7623, '3282': 11799, - '3316': 578, '3379': 42785, '3393': 1159, '3416': 8377 -}; - -// Some characters, e.g. copyrightserif, are mapped to the private use area and -// might not be displayed using standard fonts. Mapping/hacking well-known chars -// to the similar equivalents in the normal characters range. -var SpecialPUASymbols = { - '63721': 0x00A9, // copyrightsans (0xF8E9) => copyright - '63193': 0x00A9, // copyrightserif (0xF6D9) => copyright - '63720': 0x00AE, // registersans (0xF8E8) => registered - '63194': 0x00AE, // registerserif (0xF6DA) => registered - '63722': 0x2122, // trademarksans (0xF8EA) => trademark - '63195': 0x2122, // trademarkserif (0xF6DB) => trademark - '63729': 0x23A7, // bracelefttp (0xF8F1) - '63730': 0x23A8, // braceleftmid (0xF8F2) - '63731': 0x23A9, // braceleftbt (0xF8F3) - '63740': 0x23AB, // bracerighttp (0xF8FC) - '63741': 0x23AC, // bracerightmid (0xF8FD) - '63742': 0x23AD, // bracerightbt (0xF8FE) - '63726': 0x23A1, // bracketlefttp (0xF8EE) - '63727': 0x23A2, // bracketleftex (0xF8EF) - '63728': 0x23A3, // bracketleftbt (0xF8F0) - '63737': 0x23A4, // bracketrighttp (0xF8F9) - '63738': 0x23A5, // bracketrightex (0xF8FA) - '63739': 0x23A6, // bracketrightbt (0xF8FB) - '63723': 0x239B, // parenlefttp (0xF8EB) - '63724': 0x239C, // parenleftex (0xF8EC) - '63725': 0x239D, // parenleftbt (0xF8ED) - '63734': 0x239E, // parenrighttp (0xF8F6) - '63735': 0x239F, // parenrightex (0xF8F7) - '63736': 0x23A0, // parenrightbt (0xF8F8) -}; -function mapSpecialUnicodeValues(code) { - if (code >= 0xFFF0 && code <= 0xFFFF) { // Specials unicode block. - return 0; - } else if (code >= 0xF600 && code <= 0xF8FF) { - return (SpecialPUASymbols[code] || code); - } - return code; -} - -var UnicodeRanges = [ - { 'begin': 0x0000, 'end': 0x007F }, // Basic Latin - { 'begin': 0x0080, 'end': 0x00FF }, // Latin-1 Supplement - { 'begin': 0x0100, 'end': 0x017F }, // Latin Extended-A - { 'begin': 0x0180, 'end': 0x024F }, // Latin Extended-B - { 'begin': 0x0250, 'end': 0x02AF }, // IPA Extensions - { 'begin': 0x02B0, 'end': 0x02FF }, // Spacing Modifier Letters - { 'begin': 0x0300, 'end': 0x036F }, // Combining Diacritical Marks - { 'begin': 0x0370, 'end': 0x03FF }, // Greek and Coptic - { 'begin': 0x2C80, 'end': 0x2CFF }, // Coptic - { 'begin': 0x0400, 'end': 0x04FF }, // Cyrillic - { 'begin': 0x0530, 'end': 0x058F }, // Armenian - { 'begin': 0x0590, 'end': 0x05FF }, // Hebrew - { 'begin': 0xA500, 'end': 0xA63F }, // Vai - { 'begin': 0x0600, 'end': 0x06FF }, // Arabic - { 'begin': 0x07C0, 'end': 0x07FF }, // NKo - { 'begin': 0x0900, 'end': 0x097F }, // Devanagari - { 'begin': 0x0980, 'end': 0x09FF }, // Bengali - { 'begin': 0x0A00, 'end': 0x0A7F }, // Gurmukhi - { 'begin': 0x0A80, 'end': 0x0AFF }, // Gujarati - { 'begin': 0x0B00, 'end': 0x0B7F }, // Oriya - { 'begin': 0x0B80, 'end': 0x0BFF }, // Tamil - { 'begin': 0x0C00, 'end': 0x0C7F }, // Telugu - { 'begin': 0x0C80, 'end': 0x0CFF }, // Kannada - { 'begin': 0x0D00, 'end': 0x0D7F }, // Malayalam - { 'begin': 0x0E00, 'end': 0x0E7F }, // Thai - { 'begin': 0x0E80, 'end': 0x0EFF }, // Lao - { 'begin': 0x10A0, 'end': 0x10FF }, // Georgian - { 'begin': 0x1B00, 'end': 0x1B7F }, // Balinese - { 'begin': 0x1100, 'end': 0x11FF }, // Hangul Jamo - { 'begin': 0x1E00, 'end': 0x1EFF }, // Latin Extended Additional - { 'begin': 0x1F00, 'end': 0x1FFF }, // Greek Extended - { 'begin': 0x2000, 'end': 0x206F }, // General Punctuation - { 'begin': 0x2070, 'end': 0x209F }, // Superscripts And Subscripts - { 'begin': 0x20A0, 'end': 0x20CF }, // Currency Symbol - { 'begin': 0x20D0, 'end': 0x20FF }, // Combining Diacritical Marks For Symbols - { 'begin': 0x2100, 'end': 0x214F }, // Letterlike Symbols - { 'begin': 0x2150, 'end': 0x218F }, // Number Forms - { 'begin': 0x2190, 'end': 0x21FF }, // Arrows - { 'begin': 0x2200, 'end': 0x22FF }, // Mathematical Operators - { 'begin': 0x2300, 'end': 0x23FF }, // Miscellaneous Technical - { 'begin': 0x2400, 'end': 0x243F }, // Control Pictures - { 'begin': 0x2440, 'end': 0x245F }, // Optical Character Recognition - { 'begin': 0x2460, 'end': 0x24FF }, // Enclosed Alphanumerics - { 'begin': 0x2500, 'end': 0x257F }, // Box Drawing - { 'begin': 0x2580, 'end': 0x259F }, // Block Elements - { 'begin': 0x25A0, 'end': 0x25FF }, // Geometric Shapes - { 'begin': 0x2600, 'end': 0x26FF }, // Miscellaneous Symbols - { 'begin': 0x2700, 'end': 0x27BF }, // Dingbats - { 'begin': 0x3000, 'end': 0x303F }, // CJK Symbols And Punctuation - { 'begin': 0x3040, 'end': 0x309F }, // Hiragana - { 'begin': 0x30A0, 'end': 0x30FF }, // Katakana - { 'begin': 0x3100, 'end': 0x312F }, // Bopomofo - { 'begin': 0x3130, 'end': 0x318F }, // Hangul Compatibility Jamo - { 'begin': 0xA840, 'end': 0xA87F }, // Phags-pa - { 'begin': 0x3200, 'end': 0x32FF }, // Enclosed CJK Letters And Months - { 'begin': 0x3300, 'end': 0x33FF }, // CJK Compatibility - { 'begin': 0xAC00, 'end': 0xD7AF }, // Hangul Syllables - { 'begin': 0xD800, 'end': 0xDFFF }, // Non-Plane 0 * - { 'begin': 0x10900, 'end': 0x1091F }, // Phoenicia - { 'begin': 0x4E00, 'end': 0x9FFF }, // CJK Unified Ideographs - { 'begin': 0xE000, 'end': 0xF8FF }, // Private Use Area (plane 0) - { 'begin': 0x31C0, 'end': 0x31EF }, // CJK Strokes - { 'begin': 0xFB00, 'end': 0xFB4F }, // Alphabetic Presentation Forms - { 'begin': 0xFB50, 'end': 0xFDFF }, // Arabic Presentation Forms-A - { 'begin': 0xFE20, 'end': 0xFE2F }, // Combining Half Marks - { 'begin': 0xFE10, 'end': 0xFE1F }, // Vertical Forms - { 'begin': 0xFE50, 'end': 0xFE6F }, // Small Form Variants - { 'begin': 0xFE70, 'end': 0xFEFF }, // Arabic Presentation Forms-B - { 'begin': 0xFF00, 'end': 0xFFEF }, // Halfwidth And Fullwidth Forms - { 'begin': 0xFFF0, 'end': 0xFFFF }, // Specials - { 'begin': 0x0F00, 'end': 0x0FFF }, // Tibetan - { 'begin': 0x0700, 'end': 0x074F }, // Syriac - { 'begin': 0x0780, 'end': 0x07BF }, // Thaana - { 'begin': 0x0D80, 'end': 0x0DFF }, // Sinhala - { 'begin': 0x1000, 'end': 0x109F }, // Myanmar - { 'begin': 0x1200, 'end': 0x137F }, // Ethiopic - { 'begin': 0x13A0, 'end': 0x13FF }, // Cherokee - { 'begin': 0x1400, 'end': 0x167F }, // Unified Canadian Aboriginal Syllabics - { 'begin': 0x1680, 'end': 0x169F }, // Ogham - { 'begin': 0x16A0, 'end': 0x16FF }, // Runic - { 'begin': 0x1780, 'end': 0x17FF }, // Khmer - { 'begin': 0x1800, 'end': 0x18AF }, // Mongolian - { 'begin': 0x2800, 'end': 0x28FF }, // Braille Patterns - { 'begin': 0xA000, 'end': 0xA48F }, // Yi Syllables - { 'begin': 0x1700, 'end': 0x171F }, // Tagalog - { 'begin': 0x10300, 'end': 0x1032F }, // Old Italic - { 'begin': 0x10330, 'end': 0x1034F }, // Gothic - { 'begin': 0x10400, 'end': 0x1044F }, // Deseret - { 'begin': 0x1D000, 'end': 0x1D0FF }, // Byzantine Musical Symbols - { 'begin': 0x1D400, 'end': 0x1D7FF }, // Mathematical Alphanumeric Symbols - { 'begin': 0xFF000, 'end': 0xFFFFD }, // Private Use (plane 15) - { 'begin': 0xFE00, 'end': 0xFE0F }, // Variation Selectors - { 'begin': 0xE0000, 'end': 0xE007F }, // Tags - { 'begin': 0x1900, 'end': 0x194F }, // Limbu - { 'begin': 0x1950, 'end': 0x197F }, // Tai Le - { 'begin': 0x1980, 'end': 0x19DF }, // New Tai Lue - { 'begin': 0x1A00, 'end': 0x1A1F }, // Buginese - { 'begin': 0x2C00, 'end': 0x2C5F }, // Glagolitic - { 'begin': 0x2D30, 'end': 0x2D7F }, // Tifinagh - { 'begin': 0x4DC0, 'end': 0x4DFF }, // Yijing Hexagram Symbols - { 'begin': 0xA800, 'end': 0xA82F }, // Syloti Nagri - { 'begin': 0x10000, 'end': 0x1007F }, // Linear B Syllabary - { 'begin': 0x10140, 'end': 0x1018F }, // Ancient Greek Numbers - { 'begin': 0x10380, 'end': 0x1039F }, // Ugaritic - { 'begin': 0x103A0, 'end': 0x103DF }, // Old Persian - { 'begin': 0x10450, 'end': 0x1047F }, // Shavian - { 'begin': 0x10480, 'end': 0x104AF }, // Osmanya - { 'begin': 0x10800, 'end': 0x1083F }, // Cypriot Syllabary - { 'begin': 0x10A00, 'end': 0x10A5F }, // Kharoshthi - { 'begin': 0x1D300, 'end': 0x1D35F }, // Tai Xuan Jing Symbols - { 'begin': 0x12000, 'end': 0x123FF }, // Cuneiform - { 'begin': 0x1D360, 'end': 0x1D37F }, // Counting Rod Numerals - { 'begin': 0x1B80, 'end': 0x1BBF }, // Sundanese - { 'begin': 0x1C00, 'end': 0x1C4F }, // Lepcha - { 'begin': 0x1C50, 'end': 0x1C7F }, // Ol Chiki - { 'begin': 0xA880, 'end': 0xA8DF }, // Saurashtra - { 'begin': 0xA900, 'end': 0xA92F }, // Kayah Li - { 'begin': 0xA930, 'end': 0xA95F }, // Rejang - { 'begin': 0xAA00, 'end': 0xAA5F }, // Cham - { 'begin': 0x10190, 'end': 0x101CF }, // Ancient Symbols - { 'begin': 0x101D0, 'end': 0x101FF }, // Phaistos Disc - { 'begin': 0x102A0, 'end': 0x102DF }, // Carian - { 'begin': 0x1F030, 'end': 0x1F09F } // Domino Tiles -]; - -var MacStandardGlyphOrdering = [ - '.notdef', '.null', 'nonmarkingreturn', 'space', 'exclam', 'quotedbl', - 'numbersign', 'dollar', 'percent', 'ampersand', 'quotesingle', 'parenleft', - 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', - 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', - 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 'at', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', - 'backslash', 'bracketright', 'asciicircum', 'underscore', 'grave', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', - 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', - 'asciitilde', 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', - 'Odieresis', 'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', - 'atilde', 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', - 'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', 'ograve', - 'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave', 'ucircumflex', - 'udieresis', 'dagger', 'degree', 'cent', 'sterling', 'section', 'bullet', - 'paragraph', 'germandbls', 'registered', 'copyright', 'trademark', 'acute', - 'dieresis', 'notequal', 'AE', 'Oslash', 'infinity', 'plusminus', 'lessequal', - 'greaterequal', 'yen', 'mu', 'partialdiff', 'summation', 'product', 'pi', - 'integral', 'ordfeminine', 'ordmasculine', 'Omega', 'ae', 'oslash', - 'questiondown', 'exclamdown', 'logicalnot', 'radical', 'florin', - 'approxequal', 'Delta', 'guillemotleft', 'guillemotright', 'ellipsis', - 'nonbreakingspace', 'Agrave', 'Atilde', 'Otilde', 'OE', 'oe', 'endash', - 'emdash', 'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright', - 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', 'currency', - 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', 'periodcentered', - 'quotesinglbase', 'quotedblbase', 'perthousand', 'Acircumflex', - 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', - 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', 'Ograve', 'Uacute', - 'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex', 'tilde', 'macron', - 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', 'ogonek', 'caron', - 'Lslash', 'lslash', 'Scaron', 'scaron', 'Zcaron', 'zcaron', 'brokenbar', - 'Eth', 'eth', 'Yacute', 'yacute', 'Thorn', 'thorn', 'minus', 'multiply', - 'onesuperior', 'twosuperior', 'threesuperior', 'onehalf', 'onequarter', - 'threequarters', 'franc', 'Gbreve', 'gbreve', 'Idotaccent', 'Scedilla', - 'scedilla', 'Cacute', 'cacute', 'Ccaron', 'ccaron', 'dcroat']; - -function getUnicodeRangeFor(value) { - for (var i = 0, ii = UnicodeRanges.length; i < ii; i++) { - var range = UnicodeRanges[i]; - if (value >= range.begin && value < range.end) { - return i; - } - } - return -1; -} - -function isRTLRangeFor(value) { - var range = UnicodeRanges[13]; - if (value >= range.begin && value < range.end) { - return true; - } - range = UnicodeRanges[11]; - if (value >= range.begin && value < range.end) { - return true; - } - return false; -} - -// The normalization table is obtained by filtering the Unicode characters -// database with entries. -var NormalizedUnicodes = { - '\u00A8': '\u0020\u0308', - '\u00AF': '\u0020\u0304', - '\u00B4': '\u0020\u0301', - '\u00B5': '\u03BC', - '\u00B8': '\u0020\u0327', - '\u0132': '\u0049\u004A', - '\u0133': '\u0069\u006A', - '\u013F': '\u004C\u00B7', - '\u0140': '\u006C\u00B7', - '\u0149': '\u02BC\u006E', - '\u017F': '\u0073', - '\u01C4': '\u0044\u017D', - '\u01C5': '\u0044\u017E', - '\u01C6': '\u0064\u017E', - '\u01C7': '\u004C\u004A', - '\u01C8': '\u004C\u006A', - '\u01C9': '\u006C\u006A', - '\u01CA': '\u004E\u004A', - '\u01CB': '\u004E\u006A', - '\u01CC': '\u006E\u006A', - '\u01F1': '\u0044\u005A', - '\u01F2': '\u0044\u007A', - '\u01F3': '\u0064\u007A', - '\u02D8': '\u0020\u0306', - '\u02D9': '\u0020\u0307', - '\u02DA': '\u0020\u030A', - '\u02DB': '\u0020\u0328', - '\u02DC': '\u0020\u0303', - '\u02DD': '\u0020\u030B', - '\u037A': '\u0020\u0345', - '\u0384': '\u0020\u0301', - '\u03D0': '\u03B2', - '\u03D1': '\u03B8', - '\u03D2': '\u03A5', - '\u03D5': '\u03C6', - '\u03D6': '\u03C0', - '\u03F0': '\u03BA', - '\u03F1': '\u03C1', - '\u03F2': '\u03C2', - '\u03F4': '\u0398', - '\u03F5': '\u03B5', - '\u03F9': '\u03A3', - '\u0587': '\u0565\u0582', - '\u0675': '\u0627\u0674', - '\u0676': '\u0648\u0674', - '\u0677': '\u06C7\u0674', - '\u0678': '\u064A\u0674', - '\u0E33': '\u0E4D\u0E32', - '\u0EB3': '\u0ECD\u0EB2', - '\u0EDC': '\u0EAB\u0E99', - '\u0EDD': '\u0EAB\u0EA1', - '\u0F77': '\u0FB2\u0F81', - '\u0F79': '\u0FB3\u0F81', - '\u1E9A': '\u0061\u02BE', - '\u1FBD': '\u0020\u0313', - '\u1FBF': '\u0020\u0313', - '\u1FC0': '\u0020\u0342', - '\u1FFE': '\u0020\u0314', - '\u2002': '\u0020', - '\u2003': '\u0020', - '\u2004': '\u0020', - '\u2005': '\u0020', - '\u2006': '\u0020', - '\u2008': '\u0020', - '\u2009': '\u0020', - '\u200A': '\u0020', - '\u2017': '\u0020\u0333', - '\u2024': '\u002E', - '\u2025': '\u002E\u002E', - '\u2026': '\u002E\u002E\u002E', - '\u2033': '\u2032\u2032', - '\u2034': '\u2032\u2032\u2032', - '\u2036': '\u2035\u2035', - '\u2037': '\u2035\u2035\u2035', - '\u203C': '\u0021\u0021', - '\u203E': '\u0020\u0305', - '\u2047': '\u003F\u003F', - '\u2048': '\u003F\u0021', - '\u2049': '\u0021\u003F', - '\u2057': '\u2032\u2032\u2032\u2032', - '\u205F': '\u0020', - '\u20A8': '\u0052\u0073', - '\u2100': '\u0061\u002F\u0063', - '\u2101': '\u0061\u002F\u0073', - '\u2103': '\u00B0\u0043', - '\u2105': '\u0063\u002F\u006F', - '\u2106': '\u0063\u002F\u0075', - '\u2107': '\u0190', - '\u2109': '\u00B0\u0046', - '\u2116': '\u004E\u006F', - '\u2121': '\u0054\u0045\u004C', - '\u2135': '\u05D0', - '\u2136': '\u05D1', - '\u2137': '\u05D2', - '\u2138': '\u05D3', - '\u213B': '\u0046\u0041\u0058', - '\u2160': '\u0049', - '\u2161': '\u0049\u0049', - '\u2162': '\u0049\u0049\u0049', - '\u2163': '\u0049\u0056', - '\u2164': '\u0056', - '\u2165': '\u0056\u0049', - '\u2166': '\u0056\u0049\u0049', - '\u2167': '\u0056\u0049\u0049\u0049', - '\u2168': '\u0049\u0058', - '\u2169': '\u0058', - '\u216A': '\u0058\u0049', - '\u216B': '\u0058\u0049\u0049', - '\u216C': '\u004C', - '\u216D': '\u0043', - '\u216E': '\u0044', - '\u216F': '\u004D', - '\u2170': '\u0069', - '\u2171': '\u0069\u0069', - '\u2172': '\u0069\u0069\u0069', - '\u2173': '\u0069\u0076', - '\u2174': '\u0076', - '\u2175': '\u0076\u0069', - '\u2176': '\u0076\u0069\u0069', - '\u2177': '\u0076\u0069\u0069\u0069', - '\u2178': '\u0069\u0078', - '\u2179': '\u0078', - '\u217A': '\u0078\u0069', - '\u217B': '\u0078\u0069\u0069', - '\u217C': '\u006C', - '\u217D': '\u0063', - '\u217E': '\u0064', - '\u217F': '\u006D', - '\u222C': '\u222B\u222B', - '\u222D': '\u222B\u222B\u222B', - '\u222F': '\u222E\u222E', - '\u2230': '\u222E\u222E\u222E', - '\u2474': '\u0028\u0031\u0029', - '\u2475': '\u0028\u0032\u0029', - '\u2476': '\u0028\u0033\u0029', - '\u2477': '\u0028\u0034\u0029', - '\u2478': '\u0028\u0035\u0029', - '\u2479': '\u0028\u0036\u0029', - '\u247A': '\u0028\u0037\u0029', - '\u247B': '\u0028\u0038\u0029', - '\u247C': '\u0028\u0039\u0029', - '\u247D': '\u0028\u0031\u0030\u0029', - '\u247E': '\u0028\u0031\u0031\u0029', - '\u247F': '\u0028\u0031\u0032\u0029', - '\u2480': '\u0028\u0031\u0033\u0029', - '\u2481': '\u0028\u0031\u0034\u0029', - '\u2482': '\u0028\u0031\u0035\u0029', - '\u2483': '\u0028\u0031\u0036\u0029', - '\u2484': '\u0028\u0031\u0037\u0029', - '\u2485': '\u0028\u0031\u0038\u0029', - '\u2486': '\u0028\u0031\u0039\u0029', - '\u2487': '\u0028\u0032\u0030\u0029', - '\u2488': '\u0031\u002E', - '\u2489': '\u0032\u002E', - '\u248A': '\u0033\u002E', - '\u248B': '\u0034\u002E', - '\u248C': '\u0035\u002E', - '\u248D': '\u0036\u002E', - '\u248E': '\u0037\u002E', - '\u248F': '\u0038\u002E', - '\u2490': '\u0039\u002E', - '\u2491': '\u0031\u0030\u002E', - '\u2492': '\u0031\u0031\u002E', - '\u2493': '\u0031\u0032\u002E', - '\u2494': '\u0031\u0033\u002E', - '\u2495': '\u0031\u0034\u002E', - '\u2496': '\u0031\u0035\u002E', - '\u2497': '\u0031\u0036\u002E', - '\u2498': '\u0031\u0037\u002E', - '\u2499': '\u0031\u0038\u002E', - '\u249A': '\u0031\u0039\u002E', - '\u249B': '\u0032\u0030\u002E', - '\u249C': '\u0028\u0061\u0029', - '\u249D': '\u0028\u0062\u0029', - '\u249E': '\u0028\u0063\u0029', - '\u249F': '\u0028\u0064\u0029', - '\u24A0': '\u0028\u0065\u0029', - '\u24A1': '\u0028\u0066\u0029', - '\u24A2': '\u0028\u0067\u0029', - '\u24A3': '\u0028\u0068\u0029', - '\u24A4': '\u0028\u0069\u0029', - '\u24A5': '\u0028\u006A\u0029', - '\u24A6': '\u0028\u006B\u0029', - '\u24A7': '\u0028\u006C\u0029', - '\u24A8': '\u0028\u006D\u0029', - '\u24A9': '\u0028\u006E\u0029', - '\u24AA': '\u0028\u006F\u0029', - '\u24AB': '\u0028\u0070\u0029', - '\u24AC': '\u0028\u0071\u0029', - '\u24AD': '\u0028\u0072\u0029', - '\u24AE': '\u0028\u0073\u0029', - '\u24AF': '\u0028\u0074\u0029', - '\u24B0': '\u0028\u0075\u0029', - '\u24B1': '\u0028\u0076\u0029', - '\u24B2': '\u0028\u0077\u0029', - '\u24B3': '\u0028\u0078\u0029', - '\u24B4': '\u0028\u0079\u0029', - '\u24B5': '\u0028\u007A\u0029', - '\u2A0C': '\u222B\u222B\u222B\u222B', - '\u2A74': '\u003A\u003A\u003D', - '\u2A75': '\u003D\u003D', - '\u2A76': '\u003D\u003D\u003D', - '\u2E9F': '\u6BCD', - '\u2EF3': '\u9F9F', - '\u2F00': '\u4E00', - '\u2F01': '\u4E28', - '\u2F02': '\u4E36', - '\u2F03': '\u4E3F', - '\u2F04': '\u4E59', - '\u2F05': '\u4E85', - '\u2F06': '\u4E8C', - '\u2F07': '\u4EA0', - '\u2F08': '\u4EBA', - '\u2F09': '\u513F', - '\u2F0A': '\u5165', - '\u2F0B': '\u516B', - '\u2F0C': '\u5182', - '\u2F0D': '\u5196', - '\u2F0E': '\u51AB', - '\u2F0F': '\u51E0', - '\u2F10': '\u51F5', - '\u2F11': '\u5200', - '\u2F12': '\u529B', - '\u2F13': '\u52F9', - '\u2F14': '\u5315', - '\u2F15': '\u531A', - '\u2F16': '\u5338', - '\u2F17': '\u5341', - '\u2F18': '\u535C', - '\u2F19': '\u5369', - '\u2F1A': '\u5382', - '\u2F1B': '\u53B6', - '\u2F1C': '\u53C8', - '\u2F1D': '\u53E3', - '\u2F1E': '\u56D7', - '\u2F1F': '\u571F', - '\u2F20': '\u58EB', - '\u2F21': '\u5902', - '\u2F22': '\u590A', - '\u2F23': '\u5915', - '\u2F24': '\u5927', - '\u2F25': '\u5973', - '\u2F26': '\u5B50', - '\u2F27': '\u5B80', - '\u2F28': '\u5BF8', - '\u2F29': '\u5C0F', - '\u2F2A': '\u5C22', - '\u2F2B': '\u5C38', - '\u2F2C': '\u5C6E', - '\u2F2D': '\u5C71', - '\u2F2E': '\u5DDB', - '\u2F2F': '\u5DE5', - '\u2F30': '\u5DF1', - '\u2F31': '\u5DFE', - '\u2F32': '\u5E72', - '\u2F33': '\u5E7A', - '\u2F34': '\u5E7F', - '\u2F35': '\u5EF4', - '\u2F36': '\u5EFE', - '\u2F37': '\u5F0B', - '\u2F38': '\u5F13', - '\u2F39': '\u5F50', - '\u2F3A': '\u5F61', - '\u2F3B': '\u5F73', - '\u2F3C': '\u5FC3', - '\u2F3D': '\u6208', - '\u2F3E': '\u6236', - '\u2F3F': '\u624B', - '\u2F40': '\u652F', - '\u2F41': '\u6534', - '\u2F42': '\u6587', - '\u2F43': '\u6597', - '\u2F44': '\u65A4', - '\u2F45': '\u65B9', - '\u2F46': '\u65E0', - '\u2F47': '\u65E5', - '\u2F48': '\u66F0', - '\u2F49': '\u6708', - '\u2F4A': '\u6728', - '\u2F4B': '\u6B20', - '\u2F4C': '\u6B62', - '\u2F4D': '\u6B79', - '\u2F4E': '\u6BB3', - '\u2F4F': '\u6BCB', - '\u2F50': '\u6BD4', - '\u2F51': '\u6BDB', - '\u2F52': '\u6C0F', - '\u2F53': '\u6C14', - '\u2F54': '\u6C34', - '\u2F55': '\u706B', - '\u2F56': '\u722A', - '\u2F57': '\u7236', - '\u2F58': '\u723B', - '\u2F59': '\u723F', - '\u2F5A': '\u7247', - '\u2F5B': '\u7259', - '\u2F5C': '\u725B', - '\u2F5D': '\u72AC', - '\u2F5E': '\u7384', - '\u2F5F': '\u7389', - '\u2F60': '\u74DC', - '\u2F61': '\u74E6', - '\u2F62': '\u7518', - '\u2F63': '\u751F', - '\u2F64': '\u7528', - '\u2F65': '\u7530', - '\u2F66': '\u758B', - '\u2F67': '\u7592', - '\u2F68': '\u7676', - '\u2F69': '\u767D', - '\u2F6A': '\u76AE', - '\u2F6B': '\u76BF', - '\u2F6C': '\u76EE', - '\u2F6D': '\u77DB', - '\u2F6E': '\u77E2', - '\u2F6F': '\u77F3', - '\u2F70': '\u793A', - '\u2F71': '\u79B8', - '\u2F72': '\u79BE', - '\u2F73': '\u7A74', - '\u2F74': '\u7ACB', - '\u2F75': '\u7AF9', - '\u2F76': '\u7C73', - '\u2F77': '\u7CF8', - '\u2F78': '\u7F36', - '\u2F79': '\u7F51', - '\u2F7A': '\u7F8A', - '\u2F7B': '\u7FBD', - '\u2F7C': '\u8001', - '\u2F7D': '\u800C', - '\u2F7E': '\u8012', - '\u2F7F': '\u8033', - '\u2F80': '\u807F', - '\u2F81': '\u8089', - '\u2F82': '\u81E3', - '\u2F83': '\u81EA', - '\u2F84': '\u81F3', - '\u2F85': '\u81FC', - '\u2F86': '\u820C', - '\u2F87': '\u821B', - '\u2F88': '\u821F', - '\u2F89': '\u826E', - '\u2F8A': '\u8272', - '\u2F8B': '\u8278', - '\u2F8C': '\u864D', - '\u2F8D': '\u866B', - '\u2F8E': '\u8840', - '\u2F8F': '\u884C', - '\u2F90': '\u8863', - '\u2F91': '\u897E', - '\u2F92': '\u898B', - '\u2F93': '\u89D2', - '\u2F94': '\u8A00', - '\u2F95': '\u8C37', - '\u2F96': '\u8C46', - '\u2F97': '\u8C55', - '\u2F98': '\u8C78', - '\u2F99': '\u8C9D', - '\u2F9A': '\u8D64', - '\u2F9B': '\u8D70', - '\u2F9C': '\u8DB3', - '\u2F9D': '\u8EAB', - '\u2F9E': '\u8ECA', - '\u2F9F': '\u8F9B', - '\u2FA0': '\u8FB0', - '\u2FA1': '\u8FB5', - '\u2FA2': '\u9091', - '\u2FA3': '\u9149', - '\u2FA4': '\u91C6', - '\u2FA5': '\u91CC', - '\u2FA6': '\u91D1', - '\u2FA7': '\u9577', - '\u2FA8': '\u9580', - '\u2FA9': '\u961C', - '\u2FAA': '\u96B6', - '\u2FAB': '\u96B9', - '\u2FAC': '\u96E8', - '\u2FAD': '\u9751', - '\u2FAE': '\u975E', - '\u2FAF': '\u9762', - '\u2FB0': '\u9769', - '\u2FB1': '\u97CB', - '\u2FB2': '\u97ED', - '\u2FB3': '\u97F3', - '\u2FB4': '\u9801', - '\u2FB5': '\u98A8', - '\u2FB6': '\u98DB', - '\u2FB7': '\u98DF', - '\u2FB8': '\u9996', - '\u2FB9': '\u9999', - '\u2FBA': '\u99AC', - '\u2FBB': '\u9AA8', - '\u2FBC': '\u9AD8', - '\u2FBD': '\u9ADF', - '\u2FBE': '\u9B25', - '\u2FBF': '\u9B2F', - '\u2FC0': '\u9B32', - '\u2FC1': '\u9B3C', - '\u2FC2': '\u9B5A', - '\u2FC3': '\u9CE5', - '\u2FC4': '\u9E75', - '\u2FC5': '\u9E7F', - '\u2FC6': '\u9EA5', - '\u2FC7': '\u9EBB', - '\u2FC8': '\u9EC3', - '\u2FC9': '\u9ECD', - '\u2FCA': '\u9ED1', - '\u2FCB': '\u9EF9', - '\u2FCC': '\u9EFD', - '\u2FCD': '\u9F0E', - '\u2FCE': '\u9F13', - '\u2FCF': '\u9F20', - '\u2FD0': '\u9F3B', - '\u2FD1': '\u9F4A', - '\u2FD2': '\u9F52', - '\u2FD3': '\u9F8D', - '\u2FD4': '\u9F9C', - '\u2FD5': '\u9FA0', - '\u3036': '\u3012', - '\u3038': '\u5341', - '\u3039': '\u5344', - '\u303A': '\u5345', - '\u309B': '\u0020\u3099', - '\u309C': '\u0020\u309A', - '\u3131': '\u1100', - '\u3132': '\u1101', - '\u3133': '\u11AA', - '\u3134': '\u1102', - '\u3135': '\u11AC', - '\u3136': '\u11AD', - '\u3137': '\u1103', - '\u3138': '\u1104', - '\u3139': '\u1105', - '\u313A': '\u11B0', - '\u313B': '\u11B1', - '\u313C': '\u11B2', - '\u313D': '\u11B3', - '\u313E': '\u11B4', - '\u313F': '\u11B5', - '\u3140': '\u111A', - '\u3141': '\u1106', - '\u3142': '\u1107', - '\u3143': '\u1108', - '\u3144': '\u1121', - '\u3145': '\u1109', - '\u3146': '\u110A', - '\u3147': '\u110B', - '\u3148': '\u110C', - '\u3149': '\u110D', - '\u314A': '\u110E', - '\u314B': '\u110F', - '\u314C': '\u1110', - '\u314D': '\u1111', - '\u314E': '\u1112', - '\u314F': '\u1161', - '\u3150': '\u1162', - '\u3151': '\u1163', - '\u3152': '\u1164', - '\u3153': '\u1165', - '\u3154': '\u1166', - '\u3155': '\u1167', - '\u3156': '\u1168', - '\u3157': '\u1169', - '\u3158': '\u116A', - '\u3159': '\u116B', - '\u315A': '\u116C', - '\u315B': '\u116D', - '\u315C': '\u116E', - '\u315D': '\u116F', - '\u315E': '\u1170', - '\u315F': '\u1171', - '\u3160': '\u1172', - '\u3161': '\u1173', - '\u3162': '\u1174', - '\u3163': '\u1175', - '\u3164': '\u1160', - '\u3165': '\u1114', - '\u3166': '\u1115', - '\u3167': '\u11C7', - '\u3168': '\u11C8', - '\u3169': '\u11CC', - '\u316A': '\u11CE', - '\u316B': '\u11D3', - '\u316C': '\u11D7', - '\u316D': '\u11D9', - '\u316E': '\u111C', - '\u316F': '\u11DD', - '\u3170': '\u11DF', - '\u3171': '\u111D', - '\u3172': '\u111E', - '\u3173': '\u1120', - '\u3174': '\u1122', - '\u3175': '\u1123', - '\u3176': '\u1127', - '\u3177': '\u1129', - '\u3178': '\u112B', - '\u3179': '\u112C', - '\u317A': '\u112D', - '\u317B': '\u112E', - '\u317C': '\u112F', - '\u317D': '\u1132', - '\u317E': '\u1136', - '\u317F': '\u1140', - '\u3180': '\u1147', - '\u3181': '\u114C', - '\u3182': '\u11F1', - '\u3183': '\u11F2', - '\u3184': '\u1157', - '\u3185': '\u1158', - '\u3186': '\u1159', - '\u3187': '\u1184', - '\u3188': '\u1185', - '\u3189': '\u1188', - '\u318A': '\u1191', - '\u318B': '\u1192', - '\u318C': '\u1194', - '\u318D': '\u119E', - '\u318E': '\u11A1', - '\u3200': '\u0028\u1100\u0029', - '\u3201': '\u0028\u1102\u0029', - '\u3202': '\u0028\u1103\u0029', - '\u3203': '\u0028\u1105\u0029', - '\u3204': '\u0028\u1106\u0029', - '\u3205': '\u0028\u1107\u0029', - '\u3206': '\u0028\u1109\u0029', - '\u3207': '\u0028\u110B\u0029', - '\u3208': '\u0028\u110C\u0029', - '\u3209': '\u0028\u110E\u0029', - '\u320A': '\u0028\u110F\u0029', - '\u320B': '\u0028\u1110\u0029', - '\u320C': '\u0028\u1111\u0029', - '\u320D': '\u0028\u1112\u0029', - '\u320E': '\u0028\u1100\u1161\u0029', - '\u320F': '\u0028\u1102\u1161\u0029', - '\u3210': '\u0028\u1103\u1161\u0029', - '\u3211': '\u0028\u1105\u1161\u0029', - '\u3212': '\u0028\u1106\u1161\u0029', - '\u3213': '\u0028\u1107\u1161\u0029', - '\u3214': '\u0028\u1109\u1161\u0029', - '\u3215': '\u0028\u110B\u1161\u0029', - '\u3216': '\u0028\u110C\u1161\u0029', - '\u3217': '\u0028\u110E\u1161\u0029', - '\u3218': '\u0028\u110F\u1161\u0029', - '\u3219': '\u0028\u1110\u1161\u0029', - '\u321A': '\u0028\u1111\u1161\u0029', - '\u321B': '\u0028\u1112\u1161\u0029', - '\u321C': '\u0028\u110C\u116E\u0029', - '\u321D': '\u0028\u110B\u1169\u110C\u1165\u11AB\u0029', - '\u321E': '\u0028\u110B\u1169\u1112\u116E\u0029', - '\u3220': '\u0028\u4E00\u0029', - '\u3221': '\u0028\u4E8C\u0029', - '\u3222': '\u0028\u4E09\u0029', - '\u3223': '\u0028\u56DB\u0029', - '\u3224': '\u0028\u4E94\u0029', - '\u3225': '\u0028\u516D\u0029', - '\u3226': '\u0028\u4E03\u0029', - '\u3227': '\u0028\u516B\u0029', - '\u3228': '\u0028\u4E5D\u0029', - '\u3229': '\u0028\u5341\u0029', - '\u322A': '\u0028\u6708\u0029', - '\u322B': '\u0028\u706B\u0029', - '\u322C': '\u0028\u6C34\u0029', - '\u322D': '\u0028\u6728\u0029', - '\u322E': '\u0028\u91D1\u0029', - '\u322F': '\u0028\u571F\u0029', - '\u3230': '\u0028\u65E5\u0029', - '\u3231': '\u0028\u682A\u0029', - '\u3232': '\u0028\u6709\u0029', - '\u3233': '\u0028\u793E\u0029', - '\u3234': '\u0028\u540D\u0029', - '\u3235': '\u0028\u7279\u0029', - '\u3236': '\u0028\u8CA1\u0029', - '\u3237': '\u0028\u795D\u0029', - '\u3238': '\u0028\u52B4\u0029', - '\u3239': '\u0028\u4EE3\u0029', - '\u323A': '\u0028\u547C\u0029', - '\u323B': '\u0028\u5B66\u0029', - '\u323C': '\u0028\u76E3\u0029', - '\u323D': '\u0028\u4F01\u0029', - '\u323E': '\u0028\u8CC7\u0029', - '\u323F': '\u0028\u5354\u0029', - '\u3240': '\u0028\u796D\u0029', - '\u3241': '\u0028\u4F11\u0029', - '\u3242': '\u0028\u81EA\u0029', - '\u3243': '\u0028\u81F3\u0029', - '\u32C0': '\u0031\u6708', - '\u32C1': '\u0032\u6708', - '\u32C2': '\u0033\u6708', - '\u32C3': '\u0034\u6708', - '\u32C4': '\u0035\u6708', - '\u32C5': '\u0036\u6708', - '\u32C6': '\u0037\u6708', - '\u32C7': '\u0038\u6708', - '\u32C8': '\u0039\u6708', - '\u32C9': '\u0031\u0030\u6708', - '\u32CA': '\u0031\u0031\u6708', - '\u32CB': '\u0031\u0032\u6708', - '\u3358': '\u0030\u70B9', - '\u3359': '\u0031\u70B9', - '\u335A': '\u0032\u70B9', - '\u335B': '\u0033\u70B9', - '\u335C': '\u0034\u70B9', - '\u335D': '\u0035\u70B9', - '\u335E': '\u0036\u70B9', - '\u335F': '\u0037\u70B9', - '\u3360': '\u0038\u70B9', - '\u3361': '\u0039\u70B9', - '\u3362': '\u0031\u0030\u70B9', - '\u3363': '\u0031\u0031\u70B9', - '\u3364': '\u0031\u0032\u70B9', - '\u3365': '\u0031\u0033\u70B9', - '\u3366': '\u0031\u0034\u70B9', - '\u3367': '\u0031\u0035\u70B9', - '\u3368': '\u0031\u0036\u70B9', - '\u3369': '\u0031\u0037\u70B9', - '\u336A': '\u0031\u0038\u70B9', - '\u336B': '\u0031\u0039\u70B9', - '\u336C': '\u0032\u0030\u70B9', - '\u336D': '\u0032\u0031\u70B9', - '\u336E': '\u0032\u0032\u70B9', - '\u336F': '\u0032\u0033\u70B9', - '\u3370': '\u0032\u0034\u70B9', - '\u33E0': '\u0031\u65E5', - '\u33E1': '\u0032\u65E5', - '\u33E2': '\u0033\u65E5', - '\u33E3': '\u0034\u65E5', - '\u33E4': '\u0035\u65E5', - '\u33E5': '\u0036\u65E5', - '\u33E6': '\u0037\u65E5', - '\u33E7': '\u0038\u65E5', - '\u33E8': '\u0039\u65E5', - '\u33E9': '\u0031\u0030\u65E5', - '\u33EA': '\u0031\u0031\u65E5', - '\u33EB': '\u0031\u0032\u65E5', - '\u33EC': '\u0031\u0033\u65E5', - '\u33ED': '\u0031\u0034\u65E5', - '\u33EE': '\u0031\u0035\u65E5', - '\u33EF': '\u0031\u0036\u65E5', - '\u33F0': '\u0031\u0037\u65E5', - '\u33F1': '\u0031\u0038\u65E5', - '\u33F2': '\u0031\u0039\u65E5', - '\u33F3': '\u0032\u0030\u65E5', - '\u33F4': '\u0032\u0031\u65E5', - '\u33F5': '\u0032\u0032\u65E5', - '\u33F6': '\u0032\u0033\u65E5', - '\u33F7': '\u0032\u0034\u65E5', - '\u33F8': '\u0032\u0035\u65E5', - '\u33F9': '\u0032\u0036\u65E5', - '\u33FA': '\u0032\u0037\u65E5', - '\u33FB': '\u0032\u0038\u65E5', - '\u33FC': '\u0032\u0039\u65E5', - '\u33FD': '\u0033\u0030\u65E5', - '\u33FE': '\u0033\u0031\u65E5', - '\uFB00': '\u0066\u0066', - '\uFB01': '\u0066\u0069', - '\uFB02': '\u0066\u006C', - '\uFB03': '\u0066\u0066\u0069', - '\uFB04': '\u0066\u0066\u006C', - '\uFB05': '\u017F\u0074', - '\uFB06': '\u0073\u0074', - '\uFB13': '\u0574\u0576', - '\uFB14': '\u0574\u0565', - '\uFB15': '\u0574\u056B', - '\uFB16': '\u057E\u0576', - '\uFB17': '\u0574\u056D', - '\uFB4F': '\u05D0\u05DC', - '\uFB50': '\u0671', - '\uFB51': '\u0671', - '\uFB52': '\u067B', - '\uFB53': '\u067B', - '\uFB54': '\u067B', - '\uFB55': '\u067B', - '\uFB56': '\u067E', - '\uFB57': '\u067E', - '\uFB58': '\u067E', - '\uFB59': '\u067E', - '\uFB5A': '\u0680', - '\uFB5B': '\u0680', - '\uFB5C': '\u0680', - '\uFB5D': '\u0680', - '\uFB5E': '\u067A', - '\uFB5F': '\u067A', - '\uFB60': '\u067A', - '\uFB61': '\u067A', - '\uFB62': '\u067F', - '\uFB63': '\u067F', - '\uFB64': '\u067F', - '\uFB65': '\u067F', - '\uFB66': '\u0679', - '\uFB67': '\u0679', - '\uFB68': '\u0679', - '\uFB69': '\u0679', - '\uFB6A': '\u06A4', - '\uFB6B': '\u06A4', - '\uFB6C': '\u06A4', - '\uFB6D': '\u06A4', - '\uFB6E': '\u06A6', - '\uFB6F': '\u06A6', - '\uFB70': '\u06A6', - '\uFB71': '\u06A6', - '\uFB72': '\u0684', - '\uFB73': '\u0684', - '\uFB74': '\u0684', - '\uFB75': '\u0684', - '\uFB76': '\u0683', - '\uFB77': '\u0683', - '\uFB78': '\u0683', - '\uFB79': '\u0683', - '\uFB7A': '\u0686', - '\uFB7B': '\u0686', - '\uFB7C': '\u0686', - '\uFB7D': '\u0686', - '\uFB7E': '\u0687', - '\uFB7F': '\u0687', - '\uFB80': '\u0687', - '\uFB81': '\u0687', - '\uFB82': '\u068D', - '\uFB83': '\u068D', - '\uFB84': '\u068C', - '\uFB85': '\u068C', - '\uFB86': '\u068E', - '\uFB87': '\u068E', - '\uFB88': '\u0688', - '\uFB89': '\u0688', - '\uFB8A': '\u0698', - '\uFB8B': '\u0698', - '\uFB8C': '\u0691', - '\uFB8D': '\u0691', - '\uFB8E': '\u06A9', - '\uFB8F': '\u06A9', - '\uFB90': '\u06A9', - '\uFB91': '\u06A9', - '\uFB92': '\u06AF', - '\uFB93': '\u06AF', - '\uFB94': '\u06AF', - '\uFB95': '\u06AF', - '\uFB96': '\u06B3', - '\uFB97': '\u06B3', - '\uFB98': '\u06B3', - '\uFB99': '\u06B3', - '\uFB9A': '\u06B1', - '\uFB9B': '\u06B1', - '\uFB9C': '\u06B1', - '\uFB9D': '\u06B1', - '\uFB9E': '\u06BA', - '\uFB9F': '\u06BA', - '\uFBA0': '\u06BB', - '\uFBA1': '\u06BB', - '\uFBA2': '\u06BB', - '\uFBA3': '\u06BB', - '\uFBA4': '\u06C0', - '\uFBA5': '\u06C0', - '\uFBA6': '\u06C1', - '\uFBA7': '\u06C1', - '\uFBA8': '\u06C1', - '\uFBA9': '\u06C1', - '\uFBAA': '\u06BE', - '\uFBAB': '\u06BE', - '\uFBAC': '\u06BE', - '\uFBAD': '\u06BE', - '\uFBAE': '\u06D2', - '\uFBAF': '\u06D2', - '\uFBB0': '\u06D3', - '\uFBB1': '\u06D3', - '\uFBD3': '\u06AD', - '\uFBD4': '\u06AD', - '\uFBD5': '\u06AD', - '\uFBD6': '\u06AD', - '\uFBD7': '\u06C7', - '\uFBD8': '\u06C7', - '\uFBD9': '\u06C6', - '\uFBDA': '\u06C6', - '\uFBDB': '\u06C8', - '\uFBDC': '\u06C8', - '\uFBDD': '\u0677', - '\uFBDE': '\u06CB', - '\uFBDF': '\u06CB', - '\uFBE0': '\u06C5', - '\uFBE1': '\u06C5', - '\uFBE2': '\u06C9', - '\uFBE3': '\u06C9', - '\uFBE4': '\u06D0', - '\uFBE5': '\u06D0', - '\uFBE6': '\u06D0', - '\uFBE7': '\u06D0', - '\uFBE8': '\u0649', - '\uFBE9': '\u0649', - '\uFBEA': '\u0626\u0627', - '\uFBEB': '\u0626\u0627', - '\uFBEC': '\u0626\u06D5', - '\uFBED': '\u0626\u06D5', - '\uFBEE': '\u0626\u0648', - '\uFBEF': '\u0626\u0648', - '\uFBF0': '\u0626\u06C7', - '\uFBF1': '\u0626\u06C7', - '\uFBF2': '\u0626\u06C6', - '\uFBF3': '\u0626\u06C6', - '\uFBF4': '\u0626\u06C8', - '\uFBF5': '\u0626\u06C8', - '\uFBF6': '\u0626\u06D0', - '\uFBF7': '\u0626\u06D0', - '\uFBF8': '\u0626\u06D0', - '\uFBF9': '\u0626\u0649', - '\uFBFA': '\u0626\u0649', - '\uFBFB': '\u0626\u0649', - '\uFBFC': '\u06CC', - '\uFBFD': '\u06CC', - '\uFBFE': '\u06CC', - '\uFBFF': '\u06CC', - '\uFC00': '\u0626\u062C', - '\uFC01': '\u0626\u062D', - '\uFC02': '\u0626\u0645', - '\uFC03': '\u0626\u0649', - '\uFC04': '\u0626\u064A', - '\uFC05': '\u0628\u062C', - '\uFC06': '\u0628\u062D', - '\uFC07': '\u0628\u062E', - '\uFC08': '\u0628\u0645', - '\uFC09': '\u0628\u0649', - '\uFC0A': '\u0628\u064A', - '\uFC0B': '\u062A\u062C', - '\uFC0C': '\u062A\u062D', - '\uFC0D': '\u062A\u062E', - '\uFC0E': '\u062A\u0645', - '\uFC0F': '\u062A\u0649', - '\uFC10': '\u062A\u064A', - '\uFC11': '\u062B\u062C', - '\uFC12': '\u062B\u0645', - '\uFC13': '\u062B\u0649', - '\uFC14': '\u062B\u064A', - '\uFC15': '\u062C\u062D', - '\uFC16': '\u062C\u0645', - '\uFC17': '\u062D\u062C', - '\uFC18': '\u062D\u0645', - '\uFC19': '\u062E\u062C', - '\uFC1A': '\u062E\u062D', - '\uFC1B': '\u062E\u0645', - '\uFC1C': '\u0633\u062C', - '\uFC1D': '\u0633\u062D', - '\uFC1E': '\u0633\u062E', - '\uFC1F': '\u0633\u0645', - '\uFC20': '\u0635\u062D', - '\uFC21': '\u0635\u0645', - '\uFC22': '\u0636\u062C', - '\uFC23': '\u0636\u062D', - '\uFC24': '\u0636\u062E', - '\uFC25': '\u0636\u0645', - '\uFC26': '\u0637\u062D', - '\uFC27': '\u0637\u0645', - '\uFC28': '\u0638\u0645', - '\uFC29': '\u0639\u062C', - '\uFC2A': '\u0639\u0645', - '\uFC2B': '\u063A\u062C', - '\uFC2C': '\u063A\u0645', - '\uFC2D': '\u0641\u062C', - '\uFC2E': '\u0641\u062D', - '\uFC2F': '\u0641\u062E', - '\uFC30': '\u0641\u0645', - '\uFC31': '\u0641\u0649', - '\uFC32': '\u0641\u064A', - '\uFC33': '\u0642\u062D', - '\uFC34': '\u0642\u0645', - '\uFC35': '\u0642\u0649', - '\uFC36': '\u0642\u064A', - '\uFC37': '\u0643\u0627', - '\uFC38': '\u0643\u062C', - '\uFC39': '\u0643\u062D', - '\uFC3A': '\u0643\u062E', - '\uFC3B': '\u0643\u0644', - '\uFC3C': '\u0643\u0645', - '\uFC3D': '\u0643\u0649', - '\uFC3E': '\u0643\u064A', - '\uFC3F': '\u0644\u062C', - '\uFC40': '\u0644\u062D', - '\uFC41': '\u0644\u062E', - '\uFC42': '\u0644\u0645', - '\uFC43': '\u0644\u0649', - '\uFC44': '\u0644\u064A', - '\uFC45': '\u0645\u062C', - '\uFC46': '\u0645\u062D', - '\uFC47': '\u0645\u062E', - '\uFC48': '\u0645\u0645', - '\uFC49': '\u0645\u0649', - '\uFC4A': '\u0645\u064A', - '\uFC4B': '\u0646\u062C', - '\uFC4C': '\u0646\u062D', - '\uFC4D': '\u0646\u062E', - '\uFC4E': '\u0646\u0645', - '\uFC4F': '\u0646\u0649', - '\uFC50': '\u0646\u064A', - '\uFC51': '\u0647\u062C', - '\uFC52': '\u0647\u0645', - '\uFC53': '\u0647\u0649', - '\uFC54': '\u0647\u064A', - '\uFC55': '\u064A\u062C', - '\uFC56': '\u064A\u062D', - '\uFC57': '\u064A\u062E', - '\uFC58': '\u064A\u0645', - '\uFC59': '\u064A\u0649', - '\uFC5A': '\u064A\u064A', - '\uFC5B': '\u0630\u0670', - '\uFC5C': '\u0631\u0670', - '\uFC5D': '\u0649\u0670', - '\uFC5E': '\u0020\u064C\u0651', - '\uFC5F': '\u0020\u064D\u0651', - '\uFC60': '\u0020\u064E\u0651', - '\uFC61': '\u0020\u064F\u0651', - '\uFC62': '\u0020\u0650\u0651', - '\uFC63': '\u0020\u0651\u0670', - '\uFC64': '\u0626\u0631', - '\uFC65': '\u0626\u0632', - '\uFC66': '\u0626\u0645', - '\uFC67': '\u0626\u0646', - '\uFC68': '\u0626\u0649', - '\uFC69': '\u0626\u064A', - '\uFC6A': '\u0628\u0631', - '\uFC6B': '\u0628\u0632', - '\uFC6C': '\u0628\u0645', - '\uFC6D': '\u0628\u0646', - '\uFC6E': '\u0628\u0649', - '\uFC6F': '\u0628\u064A', - '\uFC70': '\u062A\u0631', - '\uFC71': '\u062A\u0632', - '\uFC72': '\u062A\u0645', - '\uFC73': '\u062A\u0646', - '\uFC74': '\u062A\u0649', - '\uFC75': '\u062A\u064A', - '\uFC76': '\u062B\u0631', - '\uFC77': '\u062B\u0632', - '\uFC78': '\u062B\u0645', - '\uFC79': '\u062B\u0646', - '\uFC7A': '\u062B\u0649', - '\uFC7B': '\u062B\u064A', - '\uFC7C': '\u0641\u0649', - '\uFC7D': '\u0641\u064A', - '\uFC7E': '\u0642\u0649', - '\uFC7F': '\u0642\u064A', - '\uFC80': '\u0643\u0627', - '\uFC81': '\u0643\u0644', - '\uFC82': '\u0643\u0645', - '\uFC83': '\u0643\u0649', - '\uFC84': '\u0643\u064A', - '\uFC85': '\u0644\u0645', - '\uFC86': '\u0644\u0649', - '\uFC87': '\u0644\u064A', - '\uFC88': '\u0645\u0627', - '\uFC89': '\u0645\u0645', - '\uFC8A': '\u0646\u0631', - '\uFC8B': '\u0646\u0632', - '\uFC8C': '\u0646\u0645', - '\uFC8D': '\u0646\u0646', - '\uFC8E': '\u0646\u0649', - '\uFC8F': '\u0646\u064A', - '\uFC90': '\u0649\u0670', - '\uFC91': '\u064A\u0631', - '\uFC92': '\u064A\u0632', - '\uFC93': '\u064A\u0645', - '\uFC94': '\u064A\u0646', - '\uFC95': '\u064A\u0649', - '\uFC96': '\u064A\u064A', - '\uFC97': '\u0626\u062C', - '\uFC98': '\u0626\u062D', - '\uFC99': '\u0626\u062E', - '\uFC9A': '\u0626\u0645', - '\uFC9B': '\u0626\u0647', - '\uFC9C': '\u0628\u062C', - '\uFC9D': '\u0628\u062D', - '\uFC9E': '\u0628\u062E', - '\uFC9F': '\u0628\u0645', - '\uFCA0': '\u0628\u0647', - '\uFCA1': '\u062A\u062C', - '\uFCA2': '\u062A\u062D', - '\uFCA3': '\u062A\u062E', - '\uFCA4': '\u062A\u0645', - '\uFCA5': '\u062A\u0647', - '\uFCA6': '\u062B\u0645', - '\uFCA7': '\u062C\u062D', - '\uFCA8': '\u062C\u0645', - '\uFCA9': '\u062D\u062C', - '\uFCAA': '\u062D\u0645', - '\uFCAB': '\u062E\u062C', - '\uFCAC': '\u062E\u0645', - '\uFCAD': '\u0633\u062C', - '\uFCAE': '\u0633\u062D', - '\uFCAF': '\u0633\u062E', - '\uFCB0': '\u0633\u0645', - '\uFCB1': '\u0635\u062D', - '\uFCB2': '\u0635\u062E', - '\uFCB3': '\u0635\u0645', - '\uFCB4': '\u0636\u062C', - '\uFCB5': '\u0636\u062D', - '\uFCB6': '\u0636\u062E', - '\uFCB7': '\u0636\u0645', - '\uFCB8': '\u0637\u062D', - '\uFCB9': '\u0638\u0645', - '\uFCBA': '\u0639\u062C', - '\uFCBB': '\u0639\u0645', - '\uFCBC': '\u063A\u062C', - '\uFCBD': '\u063A\u0645', - '\uFCBE': '\u0641\u062C', - '\uFCBF': '\u0641\u062D', - '\uFCC0': '\u0641\u062E', - '\uFCC1': '\u0641\u0645', - '\uFCC2': '\u0642\u062D', - '\uFCC3': '\u0642\u0645', - '\uFCC4': '\u0643\u062C', - '\uFCC5': '\u0643\u062D', - '\uFCC6': '\u0643\u062E', - '\uFCC7': '\u0643\u0644', - '\uFCC8': '\u0643\u0645', - '\uFCC9': '\u0644\u062C', - '\uFCCA': '\u0644\u062D', - '\uFCCB': '\u0644\u062E', - '\uFCCC': '\u0644\u0645', - '\uFCCD': '\u0644\u0647', - '\uFCCE': '\u0645\u062C', - '\uFCCF': '\u0645\u062D', - '\uFCD0': '\u0645\u062E', - '\uFCD1': '\u0645\u0645', - '\uFCD2': '\u0646\u062C', - '\uFCD3': '\u0646\u062D', - '\uFCD4': '\u0646\u062E', - '\uFCD5': '\u0646\u0645', - '\uFCD6': '\u0646\u0647', - '\uFCD7': '\u0647\u062C', - '\uFCD8': '\u0647\u0645', - '\uFCD9': '\u0647\u0670', - '\uFCDA': '\u064A\u062C', - '\uFCDB': '\u064A\u062D', - '\uFCDC': '\u064A\u062E', - '\uFCDD': '\u064A\u0645', - '\uFCDE': '\u064A\u0647', - '\uFCDF': '\u0626\u0645', - '\uFCE0': '\u0626\u0647', - '\uFCE1': '\u0628\u0645', - '\uFCE2': '\u0628\u0647', - '\uFCE3': '\u062A\u0645', - '\uFCE4': '\u062A\u0647', - '\uFCE5': '\u062B\u0645', - '\uFCE6': '\u062B\u0647', - '\uFCE7': '\u0633\u0645', - '\uFCE8': '\u0633\u0647', - '\uFCE9': '\u0634\u0645', - '\uFCEA': '\u0634\u0647', - '\uFCEB': '\u0643\u0644', - '\uFCEC': '\u0643\u0645', - '\uFCED': '\u0644\u0645', - '\uFCEE': '\u0646\u0645', - '\uFCEF': '\u0646\u0647', - '\uFCF0': '\u064A\u0645', - '\uFCF1': '\u064A\u0647', - '\uFCF2': '\u0640\u064E\u0651', - '\uFCF3': '\u0640\u064F\u0651', - '\uFCF4': '\u0640\u0650\u0651', - '\uFCF5': '\u0637\u0649', - '\uFCF6': '\u0637\u064A', - '\uFCF7': '\u0639\u0649', - '\uFCF8': '\u0639\u064A', - '\uFCF9': '\u063A\u0649', - '\uFCFA': '\u063A\u064A', - '\uFCFB': '\u0633\u0649', - '\uFCFC': '\u0633\u064A', - '\uFCFD': '\u0634\u0649', - '\uFCFE': '\u0634\u064A', - '\uFCFF': '\u062D\u0649', - '\uFD00': '\u062D\u064A', - '\uFD01': '\u062C\u0649', - '\uFD02': '\u062C\u064A', - '\uFD03': '\u062E\u0649', - '\uFD04': '\u062E\u064A', - '\uFD05': '\u0635\u0649', - '\uFD06': '\u0635\u064A', - '\uFD07': '\u0636\u0649', - '\uFD08': '\u0636\u064A', - '\uFD09': '\u0634\u062C', - '\uFD0A': '\u0634\u062D', - '\uFD0B': '\u0634\u062E', - '\uFD0C': '\u0634\u0645', - '\uFD0D': '\u0634\u0631', - '\uFD0E': '\u0633\u0631', - '\uFD0F': '\u0635\u0631', - '\uFD10': '\u0636\u0631', - '\uFD11': '\u0637\u0649', - '\uFD12': '\u0637\u064A', - '\uFD13': '\u0639\u0649', - '\uFD14': '\u0639\u064A', - '\uFD15': '\u063A\u0649', - '\uFD16': '\u063A\u064A', - '\uFD17': '\u0633\u0649', - '\uFD18': '\u0633\u064A', - '\uFD19': '\u0634\u0649', - '\uFD1A': '\u0634\u064A', - '\uFD1B': '\u062D\u0649', - '\uFD1C': '\u062D\u064A', - '\uFD1D': '\u062C\u0649', - '\uFD1E': '\u062C\u064A', - '\uFD1F': '\u062E\u0649', - '\uFD20': '\u062E\u064A', - '\uFD21': '\u0635\u0649', - '\uFD22': '\u0635\u064A', - '\uFD23': '\u0636\u0649', - '\uFD24': '\u0636\u064A', - '\uFD25': '\u0634\u062C', - '\uFD26': '\u0634\u062D', - '\uFD27': '\u0634\u062E', - '\uFD28': '\u0634\u0645', - '\uFD29': '\u0634\u0631', - '\uFD2A': '\u0633\u0631', - '\uFD2B': '\u0635\u0631', - '\uFD2C': '\u0636\u0631', - '\uFD2D': '\u0634\u062C', - '\uFD2E': '\u0634\u062D', - '\uFD2F': '\u0634\u062E', - '\uFD30': '\u0634\u0645', - '\uFD31': '\u0633\u0647', - '\uFD32': '\u0634\u0647', - '\uFD33': '\u0637\u0645', - '\uFD34': '\u0633\u062C', - '\uFD35': '\u0633\u062D', - '\uFD36': '\u0633\u062E', - '\uFD37': '\u0634\u062C', - '\uFD38': '\u0634\u062D', - '\uFD39': '\u0634\u062E', - '\uFD3A': '\u0637\u0645', - '\uFD3B': '\u0638\u0645', - '\uFD3C': '\u0627\u064B', - '\uFD3D': '\u0627\u064B', - '\uFD50': '\u062A\u062C\u0645', - '\uFD51': '\u062A\u062D\u062C', - '\uFD52': '\u062A\u062D\u062C', - '\uFD53': '\u062A\u062D\u0645', - '\uFD54': '\u062A\u062E\u0645', - '\uFD55': '\u062A\u0645\u062C', - '\uFD56': '\u062A\u0645\u062D', - '\uFD57': '\u062A\u0645\u062E', - '\uFD58': '\u062C\u0645\u062D', - '\uFD59': '\u062C\u0645\u062D', - '\uFD5A': '\u062D\u0645\u064A', - '\uFD5B': '\u062D\u0645\u0649', - '\uFD5C': '\u0633\u062D\u062C', - '\uFD5D': '\u0633\u062C\u062D', - '\uFD5E': '\u0633\u062C\u0649', - '\uFD5F': '\u0633\u0645\u062D', - '\uFD60': '\u0633\u0645\u062D', - '\uFD61': '\u0633\u0645\u062C', - '\uFD62': '\u0633\u0645\u0645', - '\uFD63': '\u0633\u0645\u0645', - '\uFD64': '\u0635\u062D\u062D', - '\uFD65': '\u0635\u062D\u062D', - '\uFD66': '\u0635\u0645\u0645', - '\uFD67': '\u0634\u062D\u0645', - '\uFD68': '\u0634\u062D\u0645', - '\uFD69': '\u0634\u062C\u064A', - '\uFD6A': '\u0634\u0645\u062E', - '\uFD6B': '\u0634\u0645\u062E', - '\uFD6C': '\u0634\u0645\u0645', - '\uFD6D': '\u0634\u0645\u0645', - '\uFD6E': '\u0636\u062D\u0649', - '\uFD6F': '\u0636\u062E\u0645', - '\uFD70': '\u0636\u062E\u0645', - '\uFD71': '\u0637\u0645\u062D', - '\uFD72': '\u0637\u0645\u062D', - '\uFD73': '\u0637\u0645\u0645', - '\uFD74': '\u0637\u0645\u064A', - '\uFD75': '\u0639\u062C\u0645', - '\uFD76': '\u0639\u0645\u0645', - '\uFD77': '\u0639\u0645\u0645', - '\uFD78': '\u0639\u0645\u0649', - '\uFD79': '\u063A\u0645\u0645', - '\uFD7A': '\u063A\u0645\u064A', - '\uFD7B': '\u063A\u0645\u0649', - '\uFD7C': '\u0641\u062E\u0645', - '\uFD7D': '\u0641\u062E\u0645', - '\uFD7E': '\u0642\u0645\u062D', - '\uFD7F': '\u0642\u0645\u0645', - '\uFD80': '\u0644\u062D\u0645', - '\uFD81': '\u0644\u062D\u064A', - '\uFD82': '\u0644\u062D\u0649', - '\uFD83': '\u0644\u062C\u062C', - '\uFD84': '\u0644\u062C\u062C', - '\uFD85': '\u0644\u062E\u0645', - '\uFD86': '\u0644\u062E\u0645', - '\uFD87': '\u0644\u0645\u062D', - '\uFD88': '\u0644\u0645\u062D', - '\uFD89': '\u0645\u062D\u062C', - '\uFD8A': '\u0645\u062D\u0645', - '\uFD8B': '\u0645\u062D\u064A', - '\uFD8C': '\u0645\u062C\u062D', - '\uFD8D': '\u0645\u062C\u0645', - '\uFD8E': '\u0645\u062E\u062C', - '\uFD8F': '\u0645\u062E\u0645', - '\uFD92': '\u0645\u062C\u062E', - '\uFD93': '\u0647\u0645\u062C', - '\uFD94': '\u0647\u0645\u0645', - '\uFD95': '\u0646\u062D\u0645', - '\uFD96': '\u0646\u062D\u0649', - '\uFD97': '\u0646\u062C\u0645', - '\uFD98': '\u0646\u062C\u0645', - '\uFD99': '\u0646\u062C\u0649', - '\uFD9A': '\u0646\u0645\u064A', - '\uFD9B': '\u0646\u0645\u0649', - '\uFD9C': '\u064A\u0645\u0645', - '\uFD9D': '\u064A\u0645\u0645', - '\uFD9E': '\u0628\u062E\u064A', - '\uFD9F': '\u062A\u062C\u064A', - '\uFDA0': '\u062A\u062C\u0649', - '\uFDA1': '\u062A\u062E\u064A', - '\uFDA2': '\u062A\u062E\u0649', - '\uFDA3': '\u062A\u0645\u064A', - '\uFDA4': '\u062A\u0645\u0649', - '\uFDA5': '\u062C\u0645\u064A', - '\uFDA6': '\u062C\u062D\u0649', - '\uFDA7': '\u062C\u0645\u0649', - '\uFDA8': '\u0633\u062E\u0649', - '\uFDA9': '\u0635\u062D\u064A', - '\uFDAA': '\u0634\u062D\u064A', - '\uFDAB': '\u0636\u062D\u064A', - '\uFDAC': '\u0644\u062C\u064A', - '\uFDAD': '\u0644\u0645\u064A', - '\uFDAE': '\u064A\u062D\u064A', - '\uFDAF': '\u064A\u062C\u064A', - '\uFDB0': '\u064A\u0645\u064A', - '\uFDB1': '\u0645\u0645\u064A', - '\uFDB2': '\u0642\u0645\u064A', - '\uFDB3': '\u0646\u062D\u064A', - '\uFDB4': '\u0642\u0645\u062D', - '\uFDB5': '\u0644\u062D\u0645', - '\uFDB6': '\u0639\u0645\u064A', - '\uFDB7': '\u0643\u0645\u064A', - '\uFDB8': '\u0646\u062C\u062D', - '\uFDB9': '\u0645\u062E\u064A', - '\uFDBA': '\u0644\u062C\u0645', - '\uFDBB': '\u0643\u0645\u0645', - '\uFDBC': '\u0644\u062C\u0645', - '\uFDBD': '\u0646\u062C\u062D', - '\uFDBE': '\u062C\u062D\u064A', - '\uFDBF': '\u062D\u062C\u064A', - '\uFDC0': '\u0645\u062C\u064A', - '\uFDC1': '\u0641\u0645\u064A', - '\uFDC2': '\u0628\u062D\u064A', - '\uFDC3': '\u0643\u0645\u0645', - '\uFDC4': '\u0639\u062C\u0645', - '\uFDC5': '\u0635\u0645\u0645', - '\uFDC6': '\u0633\u062E\u064A', - '\uFDC7': '\u0646\u062C\u064A', - '\uFE49': '\u203E', - '\uFE4A': '\u203E', - '\uFE4B': '\u203E', - '\uFE4C': '\u203E', - '\uFE4D': '\u005F', - '\uFE4E': '\u005F', - '\uFE4F': '\u005F', - '\uFE80': '\u0621', - '\uFE81': '\u0622', - '\uFE82': '\u0622', - '\uFE83': '\u0623', - '\uFE84': '\u0623', - '\uFE85': '\u0624', - '\uFE86': '\u0624', - '\uFE87': '\u0625', - '\uFE88': '\u0625', - '\uFE89': '\u0626', - '\uFE8A': '\u0626', - '\uFE8B': '\u0626', - '\uFE8C': '\u0626', - '\uFE8D': '\u0627', - '\uFE8E': '\u0627', - '\uFE8F': '\u0628', - '\uFE90': '\u0628', - '\uFE91': '\u0628', - '\uFE92': '\u0628', - '\uFE93': '\u0629', - '\uFE94': '\u0629', - '\uFE95': '\u062A', - '\uFE96': '\u062A', - '\uFE97': '\u062A', - '\uFE98': '\u062A', - '\uFE99': '\u062B', - '\uFE9A': '\u062B', - '\uFE9B': '\u062B', - '\uFE9C': '\u062B', - '\uFE9D': '\u062C', - '\uFE9E': '\u062C', - '\uFE9F': '\u062C', - '\uFEA0': '\u062C', - '\uFEA1': '\u062D', - '\uFEA2': '\u062D', - '\uFEA3': '\u062D', - '\uFEA4': '\u062D', - '\uFEA5': '\u062E', - '\uFEA6': '\u062E', - '\uFEA7': '\u062E', - '\uFEA8': '\u062E', - '\uFEA9': '\u062F', - '\uFEAA': '\u062F', - '\uFEAB': '\u0630', - '\uFEAC': '\u0630', - '\uFEAD': '\u0631', - '\uFEAE': '\u0631', - '\uFEAF': '\u0632', - '\uFEB0': '\u0632', - '\uFEB1': '\u0633', - '\uFEB2': '\u0633', - '\uFEB3': '\u0633', - '\uFEB4': '\u0633', - '\uFEB5': '\u0634', - '\uFEB6': '\u0634', - '\uFEB7': '\u0634', - '\uFEB8': '\u0634', - '\uFEB9': '\u0635', - '\uFEBA': '\u0635', - '\uFEBB': '\u0635', - '\uFEBC': '\u0635', - '\uFEBD': '\u0636', - '\uFEBE': '\u0636', - '\uFEBF': '\u0636', - '\uFEC0': '\u0636', - '\uFEC1': '\u0637', - '\uFEC2': '\u0637', - '\uFEC3': '\u0637', - '\uFEC4': '\u0637', - '\uFEC5': '\u0638', - '\uFEC6': '\u0638', - '\uFEC7': '\u0638', - '\uFEC8': '\u0638', - '\uFEC9': '\u0639', - '\uFECA': '\u0639', - '\uFECB': '\u0639', - '\uFECC': '\u0639', - '\uFECD': '\u063A', - '\uFECE': '\u063A', - '\uFECF': '\u063A', - '\uFED0': '\u063A', - '\uFED1': '\u0641', - '\uFED2': '\u0641', - '\uFED3': '\u0641', - '\uFED4': '\u0641', - '\uFED5': '\u0642', - '\uFED6': '\u0642', - '\uFED7': '\u0642', - '\uFED8': '\u0642', - '\uFED9': '\u0643', - '\uFEDA': '\u0643', - '\uFEDB': '\u0643', - '\uFEDC': '\u0643', - '\uFEDD': '\u0644', - '\uFEDE': '\u0644', - '\uFEDF': '\u0644', - '\uFEE0': '\u0644', - '\uFEE1': '\u0645', - '\uFEE2': '\u0645', - '\uFEE3': '\u0645', - '\uFEE4': '\u0645', - '\uFEE5': '\u0646', - '\uFEE6': '\u0646', - '\uFEE7': '\u0646', - '\uFEE8': '\u0646', - '\uFEE9': '\u0647', - '\uFEEA': '\u0647', - '\uFEEB': '\u0647', - '\uFEEC': '\u0647', - '\uFEED': '\u0648', - '\uFEEE': '\u0648', - '\uFEEF': '\u0649', - '\uFEF0': '\u0649', - '\uFEF1': '\u064A', - '\uFEF2': '\u064A', - '\uFEF3': '\u064A', - '\uFEF4': '\u064A', - '\uFEF5': '\u0644\u0622', - '\uFEF6': '\u0644\u0622', - '\uFEF7': '\u0644\u0623', - '\uFEF8': '\u0644\u0623', - '\uFEF9': '\u0644\u0625', - '\uFEFA': '\u0644\u0625', - '\uFEFB': '\u0644\u0627', - '\uFEFC': '\u0644\u0627' -}; - -function reverseIfRtl(chars) { - var charsLength = chars.length; - //reverse an arabic ligature - if (charsLength <= 1 || !isRTLRangeFor(chars.charCodeAt(0))) { - return chars; - } - var s = ''; - for (var ii = charsLength - 1; ii >= 0; ii--) { - s += chars[ii]; - } - return s; -} - -function adjustWidths(properties) { - if (properties.fontMatrix[0] === FONT_IDENTITY_MATRIX[0]) { - return; - } - // adjusting width to fontMatrix scale - var scale = 0.001 / properties.fontMatrix[0]; - var glyphsWidths = properties.widths; - for (var glyph in glyphsWidths) { - glyphsWidths[glyph] *= scale; - } - properties.defaultWidth *= scale; -} - -function getFontType(type, subtype) { - switch (type) { - case 'Type1': - return subtype === 'Type1C' ? FontType.TYPE1C : FontType.TYPE1; - case 'CIDFontType0': - return subtype === 'CIDFontType0C' ? FontType.CIDFONTTYPE0C : - FontType.CIDFONTTYPE0; - case 'OpenType': - return FontType.OPENTYPE; - case 'TrueType': - return FontType.TRUETYPE; - case 'CIDFontType2': - return FontType.CIDFONTTYPE2; - case 'MMType1': - return FontType.MMTYPE1; - case 'Type0': - return FontType.TYPE0; - default: - return FontType.UNKNOWN; - } -} - -var Glyph = (function GlyphClosure() { - function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId) { - this.fontChar = fontChar; - this.unicode = unicode; - this.accent = accent; - this.width = width; - this.vmetric = vmetric; - this.operatorListId = operatorListId; - } - - Glyph.prototype.matchesForCache = - function(fontChar, unicode, accent, width, vmetric, operatorListId) { - return this.fontChar === fontChar && - this.unicode === unicode && - this.accent === accent && - this.width === width && - this.vmetric === vmetric && - this.operatorListId === operatorListId; - }; - - return Glyph; -})(); - -var ToUnicodeMap = (function ToUnicodeMapClosure() { - function ToUnicodeMap(cmap) { - // The elements of this._map can be integers or strings, depending on how - // |cmap| was created. - this._map = cmap; - } - - ToUnicodeMap.prototype = { - get length() { - return this._map.length; - }, - - forEach: function(callback) { - for (var charCode in this._map) { - callback(charCode, this._map[charCode].charCodeAt(0)); - } - }, - - has: function(i) { - return this._map[i] !== undefined; - }, - - get: function(i) { - return this._map[i]; - }, - - charCodeOf: function(v) { - return this._map.indexOf(v); - } - }; - - return ToUnicodeMap; -})(); - -var IdentityToUnicodeMap = (function IdentityToUnicodeMapClosure() { - function IdentityToUnicodeMap(firstChar, lastChar) { - this.firstChar = firstChar; - this.lastChar = lastChar; - } - - IdentityToUnicodeMap.prototype = { - get length() { - return (this.lastChar + 1) - this.firstChar; - }, - - forEach: function (callback) { - for (var i = this.firstChar, ii = this.lastChar; i <= ii; i++) { - callback(i, i); - } - }, - - has: function (i) { - return this.firstChar <= i && i <= this.lastChar; - }, - - get: function (i) { - if (this.firstChar <= i && i <= this.lastChar) { - return String.fromCharCode(i); - } - return undefined; - }, - - charCodeOf: function (v) { - error('should not call .charCodeOf'); - } - }; - - return IdentityToUnicodeMap; -})(); - -var OpenTypeFileBuilder = (function OpenTypeFileBuilderClosure() { - function writeInt16(dest, offset, num) { - dest[offset] = (num >> 8) & 0xFF; - dest[offset + 1] = num & 0xFF; - } - - function writeInt32(dest, offset, num) { - dest[offset] = (num >> 24) & 0xFF; - dest[offset + 1] = (num >> 16) & 0xFF; - dest[offset + 2] = (num >> 8) & 0xFF; - dest[offset + 3] = num & 0xFF; - } - - function writeData(dest, offset, data) { - var i, ii; - if (data instanceof Uint8Array) { - dest.set(data, offset); - } else if (typeof data === 'string') { - for (i = 0, ii = data.length; i < ii; i++) { - dest[offset++] = data.charCodeAt(i) & 0xFF; - } - } else { - // treating everything else as array - for (i = 0, ii = data.length; i < ii; i++) { - dest[offset++] = data[i] & 0xFF; - } - } - } - - function OpenTypeFileBuilder(sfnt) { - this.sfnt = sfnt; - this.tables = Object.create(null); - } - - OpenTypeFileBuilder.getSearchParams = - function OpenTypeFileBuilder_getSearchParams(entriesCount, entrySize) { - var maxPower2 = 1, log2 = 0; - while ((maxPower2 ^ entriesCount) > maxPower2) { - maxPower2 <<= 1; - log2++; - } - var searchRange = maxPower2 * entrySize; - return { - range: searchRange, - entry: log2, - rangeShift: entrySize * entriesCount - searchRange - }; - }; - - var OTF_HEADER_SIZE = 12; - var OTF_TABLE_ENTRY_SIZE = 16; - - OpenTypeFileBuilder.prototype = { - toArray: function OpenTypeFileBuilder_toArray() { - var sfnt = this.sfnt; - - // Tables needs to be written by ascendant alphabetic order - var tables = this.tables; - var tablesNames = Object.keys(tables); - tablesNames.sort(); - var numTables = tablesNames.length; - - var i, j, jj, table, tableName; - // layout the tables data - var offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE; - var tableOffsets = [offset]; - for (i = 0; i < numTables; i++) { - table = tables[tablesNames[i]]; - var paddedLength = ((table.length + 3) & ~3) >>> 0; - offset += paddedLength; - tableOffsets.push(offset); - } - - var file = new Uint8Array(offset); - // write the table data first (mostly for checksum) - for (i = 0; i < numTables; i++) { - table = tables[tablesNames[i]]; - writeData(file, tableOffsets[i], table); - } - - // sfnt version (4 bytes) - if (sfnt === 'true') { - // Windows hates the Mac TrueType sfnt version number - sfnt = string32(0x00010000); - } - file[0] = sfnt.charCodeAt(0) & 0xFF; - file[1] = sfnt.charCodeAt(1) & 0xFF; - file[2] = sfnt.charCodeAt(2) & 0xFF; - file[3] = sfnt.charCodeAt(3) & 0xFF; - - // numTables (2 bytes) - writeInt16(file, 4, numTables); - - var searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16); - - // searchRange (2 bytes) - writeInt16(file, 6, searchParams.range); - // entrySelector (2 bytes) - writeInt16(file, 8, searchParams.entry); - // rangeShift (2 bytes) - writeInt16(file, 10, searchParams.rangeShift); - - offset = OTF_HEADER_SIZE; - // writing table entries - for (i = 0; i < numTables; i++) { - tableName = tablesNames[i]; - file[offset] = tableName.charCodeAt(0) & 0xFF; - file[offset + 1] = tableName.charCodeAt(1) & 0xFF; - file[offset + 2] = tableName.charCodeAt(2) & 0xFF; - file[offset + 3] = tableName.charCodeAt(3) & 0xFF; - - // checksum - var checksum = 0; - for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) { - var quad = (file[j] << 24) + (file[j + 1] << 16) + - (file[j + 2] << 8) + file[j + 3]; - checksum = (checksum + quad) | 0; - } - writeInt32(file, offset + 4, checksum); - - // offset - writeInt32(file, offset + 8, tableOffsets[i]); - // length - writeInt32(file, offset + 12, tables[tableName].length); - - offset += OTF_TABLE_ENTRY_SIZE; - } - return file; - }, - - addTable: function OpenTypeFileBuilder_addTable(tag, data) { - if (tag in this.tables) { - throw new Error('Table ' + tag + ' already exists'); - } - this.tables[tag] = data; - } - }; - - return OpenTypeFileBuilder; -})(); - -/** - * 'Font' is the class the outside world should use, it encapsulate all the font - * decoding logics whatever type it is (assuming the font type is supported). - * - * For example to read a Type1 font and to attach it to the document: - * var type1Font = new Font("MyFontName", binaryFile, propertiesObject); - * type1Font.bind(); - */ -var Font = (function FontClosure() { - function Font(name, file, properties) { - var charCode, glyphName, fontChar; - - this.name = name; - this.loadedName = properties.loadedName; - this.isType3Font = properties.isType3Font; - this.sizes = []; - - this.glyphCache = {}; - - var names = name.split('+'); - names = names.length > 1 ? names[1] : names[0]; - names = names.split(/[-,_]/g)[0]; - this.isSerifFont = !!(properties.flags & FontFlags.Serif); - this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic); - this.isMonospace = !!(properties.flags & FontFlags.FixedPitch); - - var type = properties.type; - var subtype = properties.subtype; - this.type = type; - - this.fallbackName = (this.isMonospace ? 'monospace' : - (this.isSerifFont ? 'serif' : 'sans-serif')); - - this.differences = properties.differences; - this.widths = properties.widths; - this.defaultWidth = properties.defaultWidth; - this.composite = properties.composite; - this.wideChars = properties.wideChars; - this.cMap = properties.cMap; - this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS; - this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS; - this.fontMatrix = properties.fontMatrix; - - this.toUnicode = properties.toUnicode = this.buildToUnicode(properties); - - this.toFontChar = []; - - if (properties.type === 'Type3') { - for (charCode = 0; charCode < 256; charCode++) { - this.toFontChar[charCode] = (this.differences[charCode] || - properties.defaultEncoding[charCode]); - } - this.fontType = FontType.TYPE3; - return; - } - - this.cidEncoding = properties.cidEncoding; - this.vertical = properties.vertical; - if (this.vertical) { - this.vmetrics = properties.vmetrics; - this.defaultVMetrics = properties.defaultVMetrics; - } - - if (!file || file.isEmpty) { - if (file) { - // Some bad PDF generators will include empty font files, - // attempting to recover by assuming that no file exists. - warn('Font file is empty in "' + name + '" (' + this.loadedName + ')'); - } - - this.missingFile = true; - // The file data is not specified. Trying to fix the font name - // to be used with the canvas.font. - var fontName = name.replace(/[,_]/g, '-'); - var isStandardFont = !!stdFontMap[fontName] || - !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]); - fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName; - - this.bold = (fontName.search(/bold/gi) !== -1); - this.italic = ((fontName.search(/oblique/gi) !== -1) || - (fontName.search(/italic/gi) !== -1)); - - // Use 'name' instead of 'fontName' here because the original - // name ArialBlack for example will be replaced by Helvetica. - this.black = (name.search(/Black/g) !== -1); - - // if at least one width is present, remeasure all chars when exists - this.remeasure = Object.keys(this.widths).length > 0; - if (isStandardFont && type === 'CIDFontType2' && - properties.cidEncoding.indexOf('Identity-') === 0) { - // Standard fonts might be embedded as CID font without glyph mapping. - // Building one based on GlyphMapForStandardFonts. - var map = []; - for (var code in GlyphMapForStandardFonts) { - map[+code] = GlyphMapForStandardFonts[code]; - } - var isIdentityUnicode = this.toUnicode instanceof IdentityToUnicodeMap; - if (!isIdentityUnicode) { - this.toUnicode.forEach(function(charCode, unicodeCharCode) { - map[+charCode] = unicodeCharCode; - }); - } - this.toFontChar = map; - this.toUnicode = new ToUnicodeMap(map); - } else if (/Symbol/i.test(fontName)) { - var symbols = Encodings.SymbolSetEncoding; - for (charCode in symbols) { - fontChar = GlyphsUnicode[symbols[charCode]]; - if (!fontChar) { - continue; - } - this.toFontChar[charCode] = fontChar; - } - for (charCode in properties.differences) { - fontChar = GlyphsUnicode[properties.differences[charCode]]; - if (!fontChar) { - continue; - } - this.toFontChar[charCode] = fontChar; - } - } else if (/Dingbats/i.test(fontName)) { - if (/Wingdings/i.test(name)) { - warn('Wingdings font without embedded font file, ' + - 'falling back to the ZapfDingbats encoding.'); - } - var dingbats = Encodings.ZapfDingbatsEncoding; - for (charCode in dingbats) { - fontChar = DingbatsGlyphsUnicode[dingbats[charCode]]; - if (!fontChar) { - continue; - } - this.toFontChar[charCode] = fontChar; - } - for (charCode in properties.differences) { - fontChar = DingbatsGlyphsUnicode[properties.differences[charCode]]; - if (!fontChar) { - continue; - } - this.toFontChar[charCode] = fontChar; - } - } else if (isStandardFont) { - this.toFontChar = []; - for (charCode in properties.defaultEncoding) { - glyphName = (properties.differences[charCode] || - properties.defaultEncoding[charCode]); - this.toFontChar[charCode] = GlyphsUnicode[glyphName]; - } - } else { - var unicodeCharCode, notCidFont = (type.indexOf('CIDFontType') === -1); - this.toUnicode.forEach(function(charCode, unicodeCharCode) { - if (notCidFont) { - glyphName = (properties.differences[charCode] || - properties.defaultEncoding[charCode]); - unicodeCharCode = (GlyphsUnicode[glyphName] || unicodeCharCode); - } - this.toFontChar[charCode] = unicodeCharCode; - }.bind(this)); - } - this.loadedName = fontName.split('-')[0]; - this.loading = false; - this.fontType = getFontType(type, subtype); - return; - } - - // Some fonts might use wrong font types for Type1C or CIDFontType0C - if (subtype === 'Type1C' && (type !== 'Type1' && type !== 'MMType1')) { - // Some TrueType fonts by mistake claim Type1C - if (isTrueTypeFile(file)) { - subtype = 'TrueType'; - } else { - type = 'Type1'; - } - } - if (subtype === 'CIDFontType0C' && type !== 'CIDFontType0') { - type = 'CIDFontType0'; - } - if (subtype === 'OpenType') { - type = 'OpenType'; - } - // Some CIDFontType0C fonts by mistake claim CIDFontType0. - if (type === 'CIDFontType0') { - subtype = isType1File(file) ? 'CIDFontType0' : 'CIDFontType0C'; - } - - var data; - switch (type) { - case 'MMType1': - info('MMType1 font (' + name + '), falling back to Type1.'); - /* falls through */ - case 'Type1': - case 'CIDFontType0': - this.mimetype = 'font/opentype'; - - var cff = (subtype === 'Type1C' || subtype === 'CIDFontType0C') ? - new CFFFont(file, properties) : new Type1Font(name, file, properties); - - adjustWidths(properties); - - // Wrap the CFF data inside an OTF font file - data = this.convert(name, cff, properties); - break; - - case 'OpenType': - case 'TrueType': - case 'CIDFontType2': - this.mimetype = 'font/opentype'; - - // Repair the TrueType file. It is can be damaged in the point of - // view of the sanitizer - data = this.checkAndRepair(name, file, properties); - if (this.isOpenType) { - type = 'OpenType'; - } - break; - - default: - error('Font ' + type + ' is not supported'); - break; - } - - this.data = data; - this.fontType = getFontType(type, subtype); - - // Transfer some properties again that could change during font conversion - this.fontMatrix = properties.fontMatrix; - this.widths = properties.widths; - this.defaultWidth = properties.defaultWidth; - this.encoding = properties.baseEncoding; - this.seacMap = properties.seacMap; - - this.loading = true; - } - - Font.getFontID = (function () { - var ID = 1; - return function Font_getFontID() { - return String(ID++); - }; - })(); - - function int16(b0, b1) { - return (b0 << 8) + b1; - } - - function int32(b0, b1, b2, b3) { - return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; - } - - function string16(value) { - return String.fromCharCode((value >> 8) & 0xff, value & 0xff); - } - - function safeString16(value) { - // clamp value to the 16-bit int range - value = (value > 0x7FFF ? 0x7FFF : (value < -0x8000 ? -0x8000 : value)); - return String.fromCharCode((value >> 8) & 0xff, value & 0xff); - } - - function isTrueTypeFile(file) { - var header = file.peekBytes(4); - return readUint32(header, 0) === 0x00010000; - } - - function isType1File(file) { - var header = file.peekBytes(2); - // All Type1 font programs must begin with the comment '%!' (0x25 + 0x21). - if (header[0] === 0x25 && header[1] === 0x21) { - return true; - } - // ... obviously some fonts violate that part of the specification, - // please refer to the comment in |Type1Font| below. - if (header[0] === 0x80 && header[1] === 0x01) { // pfb file header. - return true; - } - return false; - } - - /** - * Helper function for |adjustMapping|. - * @return {boolean} - */ - function isProblematicUnicodeLocation(code) { - if (code <= 0x1F) { // Control chars - return true; - } - if (code >= 0x80 && code <= 0x9F) { // Control chars - return true; - } - if ((code >= 0x2000 && code <= 0x200F) || // General punctuation chars - (code >= 0x2028 && code <= 0x202F) || - (code >= 0x2060 && code <= 0x206F)) { - return true; - } - if (code >= 0xFFF0 && code <= 0xFFFF) { // Specials Unicode block - return true; - } - switch (code) { - case 0x7F: // Control char - case 0xA0: // Non breaking space - case 0xAD: // Soft hyphen - case 0x0E33: // Thai character SARA AM - case 0x2011: // Non breaking hyphen - case 0x205F: // Medium mathematical space - case 0x25CC: // Dotted circle (combining mark) - return true; - } - return false; - } - - /** - * Rebuilds the char code to glyph ID map by trying to replace the char codes - * with their unicode value. It also moves char codes that are in known - * problematic locations. - * @return {Object} Two properties: - * 'toFontChar' - maps original char codes(the value that will be read - * from commands such as show text) to the char codes that will be used in the - * font that we build - * 'charCodeToGlyphId' - maps the new font char codes to glyph ids - */ - function adjustMapping(charCodeToGlyphId, properties) { - var toUnicode = properties.toUnicode; - var isSymbolic = !!(properties.flags & FontFlags.Symbolic); - var isIdentityUnicode = - properties.toUnicode instanceof IdentityToUnicodeMap; - var newMap = Object.create(null); - var toFontChar = []; - var usedFontCharCodes = []; - var nextAvailableFontCharCode = PRIVATE_USE_OFFSET_START; - for (var originalCharCode in charCodeToGlyphId) { - originalCharCode |= 0; - var glyphId = charCodeToGlyphId[originalCharCode]; - var fontCharCode = originalCharCode; - // First try to map the value to a unicode position if a non identity map - // was created. - if (!isIdentityUnicode && toUnicode.has(originalCharCode)) { - var unicode = toUnicode.get(fontCharCode); - // TODO: Try to map ligatures to the correct spot. - if (unicode.length === 1) { - fontCharCode = unicode.charCodeAt(0); - } - } - // Try to move control characters, special characters and already mapped - // characters to the private use area since they will not be drawn by - // canvas if left in their current position. Also, move characters if the - // font was symbolic and there is only an identity unicode map since the - // characters probably aren't in the correct position (fixes an issue - // with firefox and thuluthfont). - if ((usedFontCharCodes[fontCharCode] !== undefined || - isProblematicUnicodeLocation(fontCharCode) || - (isSymbolic && isIdentityUnicode)) && - nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END) { // Room left. - // Loop to try and find a free spot in the private use area. - do { - fontCharCode = nextAvailableFontCharCode++; - - if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) { - fontCharCode = 0xF020; - nextAvailableFontCharCode = fontCharCode + 1; - } - - } while (usedFontCharCodes[fontCharCode] !== undefined && - nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END); - } - - newMap[fontCharCode] = glyphId; - toFontChar[originalCharCode] = fontCharCode; - usedFontCharCodes[fontCharCode] = true; - } - return { - toFontChar: toFontChar, - charCodeToGlyphId: newMap, - nextAvailableFontCharCode: nextAvailableFontCharCode - }; - } - - function getRanges(glyphs) { - // Array.sort() sorts by characters, not numerically, so convert to an - // array of characters. - var codes = []; - for (var charCode in glyphs) { - codes.push({ fontCharCode: charCode | 0, glyphId: glyphs[charCode] }); - } - codes.sort(function fontGetRangesSort(a, b) { - return a.fontCharCode - b.fontCharCode; - }); - - // Split the sorted codes into ranges. - var ranges = []; - var length = codes.length; - for (var n = 0; n < length; ) { - var start = codes[n].fontCharCode; - var codeIndices = [codes[n].glyphId]; - ++n; - var end = start; - while (n < length && end + 1 === codes[n].fontCharCode) { - codeIndices.push(codes[n].glyphId); - ++end; - ++n; - if (end === 0xFFFF) { - break; - } - } - ranges.push([start, end, codeIndices]); - } - - return ranges; - } - - function createCmapTable(glyphs) { - var ranges = getRanges(glyphs); - var numTables = ranges[ranges.length - 1][1] > 0xFFFF ? 2 : 1; - var cmap = '\x00\x00' + // version - string16(numTables) + // numTables - '\x00\x03' + // platformID - '\x00\x01' + // encodingID - string32(4 + numTables * 8); // start of the table record - - var i, ii, j, jj; - for (i = ranges.length - 1; i >= 0; --i) { - if (ranges[i][0] <= 0xFFFF) { break; } - } - var bmpLength = i + 1; - - if (ranges[i][0] < 0xFFFF && ranges[i][1] === 0xFFFF) { - ranges[i][1] = 0xFFFE; - } - var trailingRangesCount = ranges[i][1] < 0xFFFF ? 1 : 0; - var segCount = bmpLength + trailingRangesCount; - var searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2); - - // Fill up the 4 parallel arrays describing the segments. - var startCount = ''; - var endCount = ''; - var idDeltas = ''; - var idRangeOffsets = ''; - var glyphsIds = ''; - var bias = 0; - - var range, start, end, codes; - for (i = 0, ii = bmpLength; i < ii; i++) { - range = ranges[i]; - start = range[0]; - end = range[1]; - startCount += string16(start); - endCount += string16(end); - codes = range[2]; - var contiguous = true; - for (j = 1, jj = codes.length; j < jj; ++j) { - if (codes[j] !== codes[j - 1] + 1) { - contiguous = false; - break; - } - } - if (!contiguous) { - var offset = (segCount - i) * 2 + bias * 2; - bias += (end - start + 1); - - idDeltas += string16(0); - idRangeOffsets += string16(offset); - - for (j = 0, jj = codes.length; j < jj; ++j) { - glyphsIds += string16(codes[j]); - } - } else { - var startCode = codes[0]; - - idDeltas += string16((startCode - start) & 0xFFFF); - idRangeOffsets += string16(0); - } - } - - if (trailingRangesCount > 0) { - endCount += '\xFF\xFF'; - startCount += '\xFF\xFF'; - idDeltas += '\x00\x01'; - idRangeOffsets += '\x00\x00'; - } - - var format314 = '\x00\x00' + // language - string16(2 * segCount) + - string16(searchParams.range) + - string16(searchParams.entry) + - string16(searchParams.rangeShift) + - endCount + '\x00\x00' + startCount + - idDeltas + idRangeOffsets + glyphsIds; - - var format31012 = ''; - var header31012 = ''; - if (numTables > 1) { - cmap += '\x00\x03' + // platformID - '\x00\x0A' + // encodingID - string32(4 + numTables * 8 + - 4 + format314.length); // start of the table record - format31012 = ''; - for (i = 0, ii = ranges.length; i < ii; i++) { - range = ranges[i]; - start = range[0]; - codes = range[2]; - var code = codes[0]; - for (j = 1, jj = codes.length; j < jj; ++j) { - if (codes[j] !== codes[j - 1] + 1) { - end = range[0] + j - 1; - format31012 += string32(start) + // startCharCode - string32(end) + // endCharCode - string32(code); // startGlyphID - start = end + 1; - code = codes[j]; - } - } - format31012 += string32(start) + // startCharCode - string32(range[1]) + // endCharCode - string32(code); // startGlyphID - } - header31012 = '\x00\x0C' + // format - '\x00\x00' + // reserved - string32(format31012.length + 16) + // length - '\x00\x00\x00\x00' + // language - string32(format31012.length / 12); // nGroups - } - - return cmap + '\x00\x04' + // format - string16(format314.length + 4) + // length - format314 + header31012 + format31012; - } - - function validateOS2Table(os2) { - var stream = new Stream(os2.data); - var version = stream.getUint16(); - // TODO verify all OS/2 tables fields, but currently we validate only those - // that give us issues - stream.getBytes(60); // skipping type, misc sizes, panose, unicode ranges - var selection = stream.getUint16(); - if (version < 4 && (selection & 0x0300)) { - return false; - } - var firstChar = stream.getUint16(); - var lastChar = stream.getUint16(); - if (firstChar > lastChar) { - return false; - } - stream.getBytes(6); // skipping sTypoAscender/Descender/LineGap - var usWinAscent = stream.getUint16(); - if (usWinAscent === 0) { // makes font unreadable by windows - return false; - } - - // OS/2 appears to be valid, resetting some fields - os2.data[8] = os2.data[9] = 0; // IE rejects fonts if fsType != 0 - return true; - } - - function createOS2Table(properties, charstrings, override) { - override = override || { - unitsPerEm: 0, - yMax: 0, - yMin: 0, - ascent: 0, - descent: 0 - }; - - var ulUnicodeRange1 = 0; - var ulUnicodeRange2 = 0; - var ulUnicodeRange3 = 0; - var ulUnicodeRange4 = 0; - - var firstCharIndex = null; - var lastCharIndex = 0; - - if (charstrings) { - for (var code in charstrings) { - code |= 0; - if (firstCharIndex > code || !firstCharIndex) { - firstCharIndex = code; - } - if (lastCharIndex < code) { - lastCharIndex = code; - } - - var position = getUnicodeRangeFor(code); - if (position < 32) { - ulUnicodeRange1 |= 1 << position; - } else if (position < 64) { - ulUnicodeRange2 |= 1 << position - 32; - } else if (position < 96) { - ulUnicodeRange3 |= 1 << position - 64; - } else if (position < 123) { - ulUnicodeRange4 |= 1 << position - 96; - } else { - error('Unicode ranges Bits > 123 are reserved for internal usage'); - } - } - } else { - // TODO - firstCharIndex = 0; - lastCharIndex = 255; - } - - var bbox = properties.bbox || [0, 0, 0, 0]; - var unitsPerEm = (override.unitsPerEm || - 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]); - - // if the font units differ to the PDF glyph space units - // then scale up the values - var scale = (properties.ascentScaled ? 1.0 : - unitsPerEm / PDF_GLYPH_SPACE_UNITS); - - var typoAscent = (override.ascent || - Math.round(scale * (properties.ascent || bbox[3]))); - var typoDescent = (override.descent || - Math.round(scale * (properties.descent || bbox[1]))); - if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) { - typoDescent = -typoDescent; // fixing incorrect descent - } - var winAscent = override.yMax || typoAscent; - var winDescent = -override.yMin || -typoDescent; - - return '\x00\x03' + // version - '\x02\x24' + // xAvgCharWidth - '\x01\xF4' + // usWeightClass - '\x00\x05' + // usWidthClass - '\x00\x00' + // fstype (0 to let the font loads via font-face on IE) - '\x02\x8A' + // ySubscriptXSize - '\x02\xBB' + // ySubscriptYSize - '\x00\x00' + // ySubscriptXOffset - '\x00\x8C' + // ySubscriptYOffset - '\x02\x8A' + // ySuperScriptXSize - '\x02\xBB' + // ySuperScriptYSize - '\x00\x00' + // ySuperScriptXOffset - '\x01\xDF' + // ySuperScriptYOffset - '\x00\x31' + // yStrikeOutSize - '\x01\x02' + // yStrikeOutPosition - '\x00\x00' + // sFamilyClass - '\x00\x00\x06' + - String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + - '\x00\x00\x00\x00\x00\x00' + // Panose - string32(ulUnicodeRange1) + // ulUnicodeRange1 (Bits 0-31) - string32(ulUnicodeRange2) + // ulUnicodeRange2 (Bits 32-63) - string32(ulUnicodeRange3) + // ulUnicodeRange3 (Bits 64-95) - string32(ulUnicodeRange4) + // ulUnicodeRange4 (Bits 96-127) - '\x2A\x32\x31\x2A' + // achVendID - string16(properties.italicAngle ? 1 : 0) + // fsSelection - string16(firstCharIndex || - properties.firstChar) + // usFirstCharIndex - string16(lastCharIndex || properties.lastChar) + // usLastCharIndex - string16(typoAscent) + // sTypoAscender - string16(typoDescent) + // sTypoDescender - '\x00\x64' + // sTypoLineGap (7%-10% of the unitsPerEM value) - string16(winAscent) + // usWinAscent - string16(winDescent) + // usWinDescent - '\x00\x00\x00\x00' + // ulCodePageRange1 (Bits 0-31) - '\x00\x00\x00\x00' + // ulCodePageRange2 (Bits 32-63) - string16(properties.xHeight) + // sxHeight - string16(properties.capHeight) + // sCapHeight - string16(0) + // usDefaultChar - string16(firstCharIndex || properties.firstChar) + // usBreakChar - '\x00\x03'; // usMaxContext - } - - function createPostTable(properties) { - var angle = Math.floor(properties.italicAngle * (Math.pow(2, 16))); - return ('\x00\x03\x00\x00' + // Version number - string32(angle) + // italicAngle - '\x00\x00' + // underlinePosition - '\x00\x00' + // underlineThickness - string32(properties.fixedPitch) + // isFixedPitch - '\x00\x00\x00\x00' + // minMemType42 - '\x00\x00\x00\x00' + // maxMemType42 - '\x00\x00\x00\x00' + // minMemType1 - '\x00\x00\x00\x00'); // maxMemType1 - } - - function createNameTable(name, proto) { - if (!proto) { - proto = [[], []]; // no strings and unicode strings - } - - var strings = [ - proto[0][0] || 'Original licence', // 0.Copyright - proto[0][1] || name, // 1.Font family - proto[0][2] || 'Unknown', // 2.Font subfamily (font weight) - proto[0][3] || 'uniqueID', // 3.Unique ID - proto[0][4] || name, // 4.Full font name - proto[0][5] || 'Version 0.11', // 5.Version - proto[0][6] || '', // 6.Postscript name - proto[0][7] || 'Unknown', // 7.Trademark - proto[0][8] || 'Unknown', // 8.Manufacturer - proto[0][9] || 'Unknown' // 9.Designer - ]; - - // Mac want 1-byte per character strings while Windows want - // 2-bytes per character, so duplicate the names table - var stringsUnicode = []; - var i, ii, j, jj, str; - for (i = 0, ii = strings.length; i < ii; i++) { - str = proto[1][i] || strings[i]; - - var strBufUnicode = []; - for (j = 0, jj = str.length; j < jj; j++) { - strBufUnicode.push(string16(str.charCodeAt(j))); - } - stringsUnicode.push(strBufUnicode.join('')); - } - - var names = [strings, stringsUnicode]; - var platforms = ['\x00\x01', '\x00\x03']; - var encodings = ['\x00\x00', '\x00\x01']; - var languages = ['\x00\x00', '\x04\x09']; - - var namesRecordCount = strings.length * platforms.length; - var nameTable = - '\x00\x00' + // format - string16(namesRecordCount) + // Number of names Record - string16(namesRecordCount * 12 + 6); // Storage - - // Build the name records field - var strOffset = 0; - for (i = 0, ii = platforms.length; i < ii; i++) { - var strs = names[i]; - for (j = 0, jj = strs.length; j < jj; j++) { - str = strs[j]; - var nameRecord = - platforms[i] + // platform ID - encodings[i] + // encoding ID - languages[i] + // language ID - string16(j) + // name ID - string16(str.length) + - string16(strOffset); - nameTable += nameRecord; - strOffset += str.length; - } - } - - nameTable += strings.join('') + stringsUnicode.join(''); - return nameTable; - } - - Font.prototype = { - name: null, - font: null, - mimetype: null, - encoding: null, - get renderer() { - var renderer = FontRendererFactory.create(this); - return shadow(this, 'renderer', renderer); - }, - - exportData: function Font_exportData() { - var data = {}; - for (var i in this) { - if (this.hasOwnProperty(i)) { - data[i] = this[i]; - } - } - return data; - }, - - checkAndRepair: function Font_checkAndRepair(name, font, properties) { - function readTableEntry(file) { - var tag = bytesToString(file.getBytes(4)); - - var checksum = file.getInt32(); - var offset = file.getInt32() >>> 0; - var length = file.getInt32() >>> 0; - - // Read the table associated data - var previousPosition = file.pos; - file.pos = file.start ? file.start : 0; - file.skip(offset); - var data = file.getBytes(length); - file.pos = previousPosition; - - if (tag === 'head') { - // clearing checksum adjustment - data[8] = data[9] = data[10] = data[11] = 0; - data[17] |= 0x20; //Set font optimized for cleartype flag - } - - return { - tag: tag, - checksum: checksum, - length: length, - offset: offset, - data: data - }; - } - - function readOpenTypeHeader(ttf) { - return { - version: bytesToString(ttf.getBytes(4)), - numTables: ttf.getUint16(), - searchRange: ttf.getUint16(), - entrySelector: ttf.getUint16(), - rangeShift: ttf.getUint16() - }; - } - - /** - * Read the appropriate subtable from the cmap according to 9.6.6.4 from - * PDF spec - */ - function readCmapTable(cmap, font, isSymbolicFont) { - var segment; - var start = (font.start ? font.start : 0) + cmap.offset; - font.pos = start; - - var version = font.getUint16(); - var numTables = font.getUint16(); - - var potentialTable; - var canBreak = false; - // There's an order of preference in terms of which cmap subtable to - // use: - // - non-symbolic fonts the preference is a 3,1 table then a 1,0 table - // - symbolic fonts the preference is a 3,0 table then a 1,0 table - // The following takes advantage of the fact that the tables are sorted - // to work. - for (var i = 0; i < numTables; i++) { - var platformId = font.getUint16(); - var encodingId = font.getUint16(); - var offset = font.getInt32() >>> 0; - var useTable = false; - - if (platformId === 0 && encodingId === 0) { - useTable = true; - // Continue the loop since there still may be a higher priority - // table. - } else if (platformId === 1 && encodingId === 0) { - useTable = true; - // Continue the loop since there still may be a higher priority - // table. - } else if (platformId === 3 && encodingId === 1 && - (!isSymbolicFont || !potentialTable)) { - useTable = true; - if (!isSymbolicFont) { - canBreak = true; - } - } else if (isSymbolicFont && platformId === 3 && encodingId === 0) { - useTable = true; - canBreak = true; - } - - if (useTable) { - potentialTable = { - platformId: platformId, - encodingId: encodingId, - offset: offset - }; - } - if (canBreak) { - break; - } - } - - if (!potentialTable) { - warn('Could not find a preferred cmap table.'); - return { - platformId: -1, - encodingId: -1, - mappings: [], - hasShortCmap: false - }; - } - - font.pos = start + potentialTable.offset; - var format = font.getUint16(); - var length = font.getUint16(); - var language = font.getUint16(); - - var hasShortCmap = false; - var mappings = []; - var j, glyphId; - - // TODO(mack): refactor this cmap subtable reading logic out - if (format === 0) { - for (j = 0; j < 256; j++) { - var index = font.getByte(); - if (!index) { - continue; - } - mappings.push({ - charCode: j, - glyphId: index - }); - } - hasShortCmap = true; - } else if (format === 4) { - // re-creating the table in format 4 since the encoding - // might be changed - var segCount = (font.getUint16() >> 1); - font.getBytes(6); // skipping range fields - var segIndex, segments = []; - for (segIndex = 0; segIndex < segCount; segIndex++) { - segments.push({ end: font.getUint16() }); - } - font.getUint16(); - for (segIndex = 0; segIndex < segCount; segIndex++) { - segments[segIndex].start = font.getUint16(); - } - - for (segIndex = 0; segIndex < segCount; segIndex++) { - segments[segIndex].delta = font.getUint16(); - } - - var offsetsCount = 0; - for (segIndex = 0; segIndex < segCount; segIndex++) { - segment = segments[segIndex]; - var rangeOffset = font.getUint16(); - if (!rangeOffset) { - segment.offsetIndex = -1; - continue; - } - - var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex); - segment.offsetIndex = offsetIndex; - offsetsCount = Math.max(offsetsCount, offsetIndex + - segment.end - segment.start + 1); - } - - var offsets = []; - for (j = 0; j < offsetsCount; j++) { - offsets.push(font.getUint16()); - } - - for (segIndex = 0; segIndex < segCount; segIndex++) { - segment = segments[segIndex]; - start = segment.start; - var end = segment.end; - var delta = segment.delta; - offsetIndex = segment.offsetIndex; - - for (j = start; j <= end; j++) { - if (j === 0xFFFF) { - continue; - } - - glyphId = (offsetIndex < 0 ? - j : offsets[offsetIndex + j - start]); - glyphId = (glyphId + delta) & 0xFFFF; - if (glyphId === 0) { - continue; - } - mappings.push({ - charCode: j, - glyphId: glyphId - }); - } - } - } else if (format === 6) { - // Format 6 is a 2-bytes dense mapping, which means the font data - // lives glue together even if they are pretty far in the unicode - // table. (This looks weird, so I can have missed something), this - // works on Linux but seems to fails on Mac so let's rewrite the - // cmap table to a 3-1-4 style - var firstCode = font.getUint16(); - var entryCount = font.getUint16(); - - for (j = 0; j < entryCount; j++) { - glyphId = font.getUint16(); - var charCode = firstCode + j; - - mappings.push({ - charCode: charCode, - glyphId: glyphId - }); - } - } else { - error('cmap table has unsupported format: ' + format); - } - - // removing duplicate entries - mappings.sort(function (a, b) { - return a.charCode - b.charCode; - }); - for (i = 1; i < mappings.length; i++) { - if (mappings[i - 1].charCode === mappings[i].charCode) { - mappings.splice(i, 1); - i--; - } - } - - return { - platformId: potentialTable.platformId, - encodingId: potentialTable.encodingId, - mappings: mappings, - hasShortCmap: hasShortCmap - }; - } - - function sanitizeMetrics(font, header, metrics, numGlyphs) { - if (!header) { - if (metrics) { - metrics.data = null; - } - return; - } - - font.pos = (font.start ? font.start : 0) + header.offset; - font.pos += header.length - 2; - var numOfMetrics = font.getUint16(); - - if (numOfMetrics > numGlyphs) { - info('The numOfMetrics (' + numOfMetrics + ') should not be ' + - 'greater than the numGlyphs (' + numGlyphs + ')'); - // Reduce numOfMetrics if it is greater than numGlyphs - numOfMetrics = numGlyphs; - header.data[34] = (numOfMetrics & 0xff00) >> 8; - header.data[35] = numOfMetrics & 0x00ff; - } - - var numOfSidebearings = numGlyphs - numOfMetrics; - var numMissing = numOfSidebearings - - ((metrics.length - numOfMetrics * 4) >> 1); - - if (numMissing > 0) { - // For each missing glyph, we set both the width and lsb to 0 (zero). - // Since we need to add two properties for each glyph, this explains - // the use of |numMissing * 2| when initializing the typed array. - var entries = new Uint8Array(metrics.length + numMissing * 2); - entries.set(metrics.data); - metrics.data = entries; - } - } - - function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, - hintsValid) { - if (sourceEnd - sourceStart <= 12) { - // glyph with data less than 12 is invalid one - return 0; - } - var glyf = source.subarray(sourceStart, sourceEnd); - var contoursCount = (glyf[0] << 8) | glyf[1]; - if (contoursCount & 0x8000) { - // complex glyph, writing as is - dest.set(glyf, destStart); - return glyf.length; - } - - var i, j = 10, flagsCount = 0; - for (i = 0; i < contoursCount; i++) { - var endPoint = (glyf[j] << 8) | glyf[j + 1]; - flagsCount = endPoint + 1; - j += 2; - } - // skipping instructions - var instructionsStart = j; - var instructionsLength = (glyf[j] << 8) | glyf[j + 1]; - j += 2 + instructionsLength; - var instructionsEnd = j; - // validating flags - var coordinatesLength = 0; - for (i = 0; i < flagsCount; i++) { - var flag = glyf[j++]; - if (flag & 0xC0) { - // reserved flags must be zero, cleaning up - glyf[j - 1] = flag & 0x3F; - } - var xyLength = ((flag & 2) ? 1 : (flag & 16) ? 0 : 2) + - ((flag & 4) ? 1 : (flag & 32) ? 0 : 2); - coordinatesLength += xyLength; - if (flag & 8) { - var repeat = glyf[j++]; - i += repeat; - coordinatesLength += repeat * xyLength; - } - } - // glyph without coordinates will be rejected - if (coordinatesLength === 0) { - return 0; - } - var glyphDataLength = j + coordinatesLength; - if (glyphDataLength > glyf.length) { - // not enough data for coordinates - return 0; - } - if (!hintsValid && instructionsLength > 0) { - dest.set(glyf.subarray(0, instructionsStart), destStart); - dest.set([0, 0], destStart + instructionsStart); - dest.set(glyf.subarray(instructionsEnd, glyphDataLength), - destStart + instructionsStart + 2); - glyphDataLength -= instructionsLength; - if (glyf.length - glyphDataLength > 3) { - glyphDataLength = (glyphDataLength + 3) & ~3; - } - return glyphDataLength; - } - if (glyf.length - glyphDataLength > 3) { - // truncating and aligning to 4 bytes the long glyph data - glyphDataLength = (glyphDataLength + 3) & ~3; - dest.set(glyf.subarray(0, glyphDataLength), destStart); - return glyphDataLength; - } - // glyph data is fine - dest.set(glyf, destStart); - return glyf.length; - } - - function sanitizeHead(head, numGlyphs, locaLength) { - var data = head.data; - - // Validate version: - // Should always be 0x00010000 - var version = int32(data[0], data[1], data[2], data[3]); - if (version >> 16 !== 1) { - info('Attempting to fix invalid version in head table: ' + version); - data[0] = 0; - data[1] = 1; - data[2] = 0; - data[3] = 0; - } - - var indexToLocFormat = int16(data[50], data[51]); - if (indexToLocFormat < 0 || indexToLocFormat > 1) { - info('Attempting to fix invalid indexToLocFormat in head table: ' + - indexToLocFormat); - - // The value of indexToLocFormat should be 0 if the loca table - // consists of short offsets, and should be 1 if the loca table - // consists of long offsets. - // - // The number of entries in the loca table should be numGlyphs + 1. - // - // Using this information, we can work backwards to deduce if the - // size of each offset in the loca table, and thus figure out the - // appropriate value for indexToLocFormat. - - var numGlyphsPlusOne = numGlyphs + 1; - if (locaLength === numGlyphsPlusOne << 1) { - // 0x0000 indicates the loca table consists of short offsets - data[50] = 0; - data[51] = 0; - } else if (locaLength === numGlyphsPlusOne << 2) { - // 0x0001 indicates the loca table consists of long offsets - data[50] = 0; - data[51] = 1; - } else { - warn('Could not fix indexToLocFormat: ' + indexToLocFormat); - } - } - } - - function sanitizeGlyphLocations(loca, glyf, numGlyphs, - isGlyphLocationsLong, hintsValid, - dupFirstEntry) { - var itemSize, itemDecode, itemEncode; - if (isGlyphLocationsLong) { - itemSize = 4; - itemDecode = function fontItemDecodeLong(data, offset) { - return (data[offset] << 24) | (data[offset + 1] << 16) | - (data[offset + 2] << 8) | data[offset + 3]; - }; - itemEncode = function fontItemEncodeLong(data, offset, value) { - data[offset] = (value >>> 24) & 0xFF; - data[offset + 1] = (value >> 16) & 0xFF; - data[offset + 2] = (value >> 8) & 0xFF; - data[offset + 3] = value & 0xFF; - }; - } else { - itemSize = 2; - itemDecode = function fontItemDecode(data, offset) { - return (data[offset] << 9) | (data[offset + 1] << 1); - }; - itemEncode = function fontItemEncode(data, offset, value) { - data[offset] = (value >> 9) & 0xFF; - data[offset + 1] = (value >> 1) & 0xFF; - }; - } - var locaData = loca.data; - var locaDataSize = itemSize * (1 + numGlyphs); - // is loca.data too short or long? - if (locaData.length !== locaDataSize) { - locaData = new Uint8Array(locaDataSize); - locaData.set(loca.data.subarray(0, locaDataSize)); - loca.data = locaData; - } - // removing the invalid glyphs - var oldGlyfData = glyf.data; - var oldGlyfDataLength = oldGlyfData.length; - var newGlyfData = new Uint8Array(oldGlyfDataLength); - var startOffset = itemDecode(locaData, 0); - var writeOffset = 0; - var missingGlyphData = {}; - itemEncode(locaData, 0, writeOffset); - var i, j; - for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { - var endOffset = itemDecode(locaData, j); - if (endOffset > oldGlyfDataLength && - ((oldGlyfDataLength + 3) & ~3) === endOffset) { - // Aspose breaks fonts by aligning the glyphs to the qword, but not - // the glyf table size, which makes last glyph out of range. - endOffset = oldGlyfDataLength; - } - if (endOffset > oldGlyfDataLength) { - // glyph end offset points outside glyf data, rejecting the glyph - itemEncode(locaData, j, writeOffset); - startOffset = endOffset; - continue; - } - - if (startOffset === endOffset) { - missingGlyphData[i] = true; - } - - var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset, - newGlyfData, writeOffset, hintsValid); - writeOffset += newLength; - itemEncode(locaData, j, writeOffset); - startOffset = endOffset; - } - - if (writeOffset === 0) { - // glyf table cannot be empty -- redoing the glyf and loca tables - // to have single glyph with one point - var simpleGlyph = new Uint8Array( - [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); - for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { - itemEncode(locaData, j, simpleGlyph.length); - } - glyf.data = simpleGlyph; - return missingGlyphData; - } - - if (dupFirstEntry) { - var firstEntryLength = itemDecode(locaData, itemSize); - if (newGlyfData.length > firstEntryLength + writeOffset) { - glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset); - } else { - glyf.data = new Uint8Array(firstEntryLength + writeOffset); - glyf.data.set(newGlyfData.subarray(0, writeOffset)); - } - glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset); - itemEncode(loca.data, locaData.length - itemSize, - writeOffset + firstEntryLength); - } else { - glyf.data = newGlyfData.subarray(0, writeOffset); - } - return missingGlyphData; - } - - function readPostScriptTable(post, properties, maxpNumGlyphs) { - var start = (font.start ? font.start : 0) + post.offset; - font.pos = start; - - var length = post.length, end = start + length; - var version = font.getInt32(); - // skip rest to the tables - font.getBytes(28); - - var glyphNames; - var valid = true; - var i; - - switch (version) { - case 0x00010000: - glyphNames = MacStandardGlyphOrdering; - break; - case 0x00020000: - var numGlyphs = font.getUint16(); - if (numGlyphs !== maxpNumGlyphs) { - valid = false; - break; - } - var glyphNameIndexes = []; - for (i = 0; i < numGlyphs; ++i) { - var index = font.getUint16(); - if (index >= 32768) { - valid = false; - break; - } - glyphNameIndexes.push(index); - } - if (!valid) { - break; - } - var customNames = []; - var strBuf = []; - while (font.pos < end) { - var stringLength = font.getByte(); - strBuf.length = stringLength; - for (i = 0; i < stringLength; ++i) { - strBuf[i] = String.fromCharCode(font.getByte()); - } - customNames.push(strBuf.join('')); - } - glyphNames = []; - for (i = 0; i < numGlyphs; ++i) { - var j = glyphNameIndexes[i]; - if (j < 258) { - glyphNames.push(MacStandardGlyphOrdering[j]); - continue; - } - glyphNames.push(customNames[j - 258]); - } - break; - case 0x00030000: - break; - default: - warn('Unknown/unsupported post table version ' + version); - valid = false; - break; - } - properties.glyphNames = glyphNames; - return valid; - } - - function readNameTable(nameTable) { - var start = (font.start ? font.start : 0) + nameTable.offset; - font.pos = start; - - var names = [[], []]; - var length = nameTable.length, end = start + length; - var format = font.getUint16(); - var FORMAT_0_HEADER_LENGTH = 6; - if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) { - // unsupported name table format or table "too" small - return names; - } - var numRecords = font.getUint16(); - var stringsStart = font.getUint16(); - var records = []; - var NAME_RECORD_LENGTH = 12; - var i, ii; - - for (i = 0; i < numRecords && - font.pos + NAME_RECORD_LENGTH <= end; i++) { - var r = { - platform: font.getUint16(), - encoding: font.getUint16(), - language: font.getUint16(), - name: font.getUint16(), - length: font.getUint16(), - offset: font.getUint16() - }; - // using only Macintosh and Windows platform/encoding names - if ((r.platform === 1 && r.encoding === 0 && r.language === 0) || - (r.platform === 3 && r.encoding === 1 && r.language === 0x409)) { - records.push(r); - } - } - for (i = 0, ii = records.length; i < ii; i++) { - var record = records[i]; - var pos = start + stringsStart + record.offset; - if (pos + record.length > end) { - continue; // outside of name table, ignoring - } - font.pos = pos; - var nameIndex = record.name; - if (record.encoding) { - // unicode - var str = ''; - for (var j = 0, jj = record.length; j < jj; j += 2) { - str += String.fromCharCode(font.getUint16()); - } - names[1][nameIndex] = str; - } else { - names[0][nameIndex] = bytesToString(font.getBytes(record.length)); - } - } - return names; - } - - var TTOpsStackDeltas = [ - 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, - -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, - 1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, - 0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, - 0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, - -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, - -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, - -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2]; - // 0xC0-DF == -1 and 0xE0-FF == -2 - - function sanitizeTTProgram(table, ttContext) { - var data = table.data; - var i = 0, j, n, b, funcId, pc, lastEndf = 0, lastDeff = 0; - var stack = []; - var callstack = []; - var functionsCalled = []; - var tooComplexToFollowFunctions = - ttContext.tooComplexToFollowFunctions; - var inFDEF = false, ifLevel = 0, inELSE = 0; - for (var ii = data.length; i < ii;) { - var op = data[i++]; - // The TrueType instruction set docs can be found at - // https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html - if (op === 0x40) { // NPUSHB - pushes n bytes - n = data[i++]; - if (inFDEF || inELSE) { - i += n; - } else { - for (j = 0; j < n; j++) { - stack.push(data[i++]); - } - } - } else if (op === 0x41) { // NPUSHW - pushes n words - n = data[i++]; - if (inFDEF || inELSE) { - i += n * 2; - } else { - for (j = 0; j < n; j++) { - b = data[i++]; - stack.push((b << 8) | data[i++]); - } - } - } else if ((op & 0xF8) === 0xB0) { // PUSHB - pushes bytes - n = op - 0xB0 + 1; - if (inFDEF || inELSE) { - i += n; - } else { - for (j = 0; j < n; j++) { - stack.push(data[i++]); - } - } - } else if ((op & 0xF8) === 0xB8) { // PUSHW - pushes words - n = op - 0xB8 + 1; - if (inFDEF || inELSE) { - i += n * 2; - } else { - for (j = 0; j < n; j++) { - b = data[i++]; - stack.push((b << 8) | data[i++]); - } - } - } else if (op === 0x2B && !tooComplexToFollowFunctions) { // CALL - if (!inFDEF && !inELSE) { - // collecting inforamtion about which functions are used - funcId = stack[stack.length - 1]; - ttContext.functionsUsed[funcId] = true; - if (funcId in ttContext.functionsStackDeltas) { - stack.length += ttContext.functionsStackDeltas[funcId]; - } else if (funcId in ttContext.functionsDefined && - functionsCalled.indexOf(funcId) < 0) { - callstack.push({data: data, i: i, stackTop: stack.length - 1}); - functionsCalled.push(funcId); - pc = ttContext.functionsDefined[funcId]; - if (!pc) { - warn('TT: CALL non-existent function'); - ttContext.hintsValid = false; - return; - } - data = pc.data; - i = pc.i; - } - } - } else if (op === 0x2C && !tooComplexToFollowFunctions) { // FDEF - if (inFDEF || inELSE) { - warn('TT: nested FDEFs not allowed'); - tooComplexToFollowFunctions = true; - } - inFDEF = true; - // collecting inforamtion about which functions are defined - lastDeff = i; - funcId = stack.pop(); - ttContext.functionsDefined[funcId] = {data: data, i: i}; - } else if (op === 0x2D) { // ENDF - end of function - if (inFDEF) { - inFDEF = false; - lastEndf = i; - } else { - pc = callstack.pop(); - if (!pc) { - warn('TT: ENDF bad stack'); - ttContext.hintsValid = false; - return; - } - funcId = functionsCalled.pop(); - data = pc.data; - i = pc.i; - ttContext.functionsStackDeltas[funcId] = - stack.length - pc.stackTop; - } - } else if (op === 0x89) { // IDEF - instruction definition - if (inFDEF || inELSE) { - warn('TT: nested IDEFs not allowed'); - tooComplexToFollowFunctions = true; - } - inFDEF = true; - // recording it as a function to track ENDF - lastDeff = i; - } else if (op === 0x58) { // IF - ++ifLevel; - } else if (op === 0x1B) { // ELSE - inELSE = ifLevel; - } else if (op === 0x59) { // EIF - if (inELSE === ifLevel) { - inELSE = 0; - } - --ifLevel; - } else if (op === 0x1C) { // JMPR - if (!inFDEF && !inELSE) { - var offset = stack[stack.length - 1]; - // only jumping forward to prevent infinite loop - if (offset > 0) { - i += offset - 1; - } - } - } - // Adjusting stack not extactly, but just enough to get function id - if (!inFDEF && !inELSE) { - var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : - op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0; - if (op >= 0x71 && op <= 0x75) { - n = stack.pop(); - if (n === n) { - stackDelta = -n * 2; - } - } - while (stackDelta < 0 && stack.length > 0) { - stack.pop(); - stackDelta++; - } - while (stackDelta > 0) { - stack.push(NaN); // pushing any number into stack - stackDelta--; - } - } - } - ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions; - var content = [data]; - if (i > data.length) { - content.push(new Uint8Array(i - data.length)); - } - if (lastDeff > lastEndf) { - warn('TT: complementing a missing function tail'); - // new function definition started, but not finished - // complete function by [CLEAR, ENDF] - content.push(new Uint8Array([0x22, 0x2D])); - } - foldTTTable(table, content); - } - - function checkInvalidFunctions(ttContext, maxFunctionDefs) { - if (ttContext.tooComplexToFollowFunctions) { - return; - } - if (ttContext.functionsDefined.length > maxFunctionDefs) { - warn('TT: more functions defined than expected'); - ttContext.hintsValid = false; - return; - } - for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) { - if (j > maxFunctionDefs) { - warn('TT: invalid function id: ' + j); - ttContext.hintsValid = false; - return; - } - if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) { - warn('TT: undefined function: ' + j); - ttContext.hintsValid = false; - return; - } - } - } - - function foldTTTable(table, content) { - if (content.length > 1) { - // concatenating the content items - var newLength = 0; - var j, jj; - for (j = 0, jj = content.length; j < jj; j++) { - newLength += content[j].length; - } - newLength = (newLength + 3) & ~3; - var result = new Uint8Array(newLength); - var pos = 0; - for (j = 0, jj = content.length; j < jj; j++) { - result.set(content[j], pos); - pos += content[j].length; - } - table.data = result; - table.length = newLength; - } - } - - function sanitizeTTPrograms(fpgm, prep, cvt) { - var ttContext = { - functionsDefined: [], - functionsUsed: [], - functionsStackDeltas: [], - tooComplexToFollowFunctions: false, - hintsValid: true - }; - if (fpgm) { - sanitizeTTProgram(fpgm, ttContext); - } - if (prep) { - sanitizeTTProgram(prep, ttContext); - } - if (fpgm) { - checkInvalidFunctions(ttContext, maxFunctionDefs); - } - if (cvt && (cvt.length & 1)) { - var cvtData = new Uint8Array(cvt.length + 1); - cvtData.set(cvt.data); - cvt.data = cvtData; - } - return ttContext.hintsValid; - } - - // The following steps modify the original font data, making copy - font = new Stream(new Uint8Array(font.getBytes())); - - var VALID_TABLES = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', - 'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt ', 'CFF ']; - - var header = readOpenTypeHeader(font); - var numTables = header.numTables; - var cff, cffFile; - - var tables = { 'OS/2': null, cmap: null, head: null, hhea: null, - hmtx: null, maxp: null, name: null, post: null }; - var table; - for (var i = 0; i < numTables; i++) { - table = readTableEntry(font); - if (VALID_TABLES.indexOf(table.tag) < 0) { - continue; // skipping table if it's not a required or optional table - } - if (table.length === 0) { - continue; // skipping empty tables - } - tables[table.tag] = table; - } - - var isTrueType = !tables['CFF ']; - if (!isTrueType) { - // OpenType font - if (header.version === 'OTTO' || - !tables.head || !tables.hhea || !tables.maxp || !tables.post) { - // no major tables: throwing everything at CFFFont - cffFile = new Stream(tables['CFF '].data); - cff = new CFFFont(cffFile, properties); - - return this.convert(name, cff, properties); - } - - delete tables.glyf; - delete tables.loca; - delete tables.fpgm; - delete tables.prep; - delete tables['cvt ']; - this.isOpenType = true; - } else { - if (!tables.glyf || !tables.loca) { - error('Required "glyf" or "loca" tables are not found'); - } - this.isOpenType = false; - } - - if (!tables.maxp) { - error('Required "maxp" table is not found'); - } - - font.pos = (font.start || 0) + tables.maxp.offset; - var version = font.getInt32(); - var numGlyphs = font.getUint16(); - var maxFunctionDefs = 0; - if (version >= 0x00010000 && tables.maxp.length >= 22) { - // maxZones can be invalid - font.pos += 8; - var maxZones = font.getUint16(); - if (maxZones > 2) { // reset to 2 if font has invalid maxZones - tables.maxp.data[14] = 0; - tables.maxp.data[15] = 2; - } - font.pos += 4; - maxFunctionDefs = font.getUint16(); - } - - var dupFirstEntry = false; - if (properties.type === 'CIDFontType2' && properties.toUnicode && - properties.toUnicode.get(0) > '\u0000') { - // oracle's defect (see 3427), duplicating first entry - dupFirstEntry = true; - numGlyphs++; - tables.maxp.data[4] = numGlyphs >> 8; - tables.maxp.data[5] = numGlyphs & 255; - } - - var hintsValid = sanitizeTTPrograms(tables.fpgm, tables.prep, - tables['cvt '], maxFunctionDefs); - if (!hintsValid) { - delete tables.fpgm; - delete tables.prep; - delete tables['cvt ']; - } - - // Ensure the hmtx table contains the advance width and - // sidebearings information for numGlyphs in the maxp table - sanitizeMetrics(font, tables.hhea, tables.hmtx, numGlyphs); - - if (!tables.head) { - error('Required "head" table is not found'); - } - - sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0); - - var missingGlyphs = {}; - if (isTrueType) { - var isGlyphLocationsLong = int16(tables.head.data[50], - tables.head.data[51]); - missingGlyphs = sanitizeGlyphLocations(tables.loca, tables.glyf, - numGlyphs, isGlyphLocationsLong, - hintsValid, dupFirstEntry); - } - - if (!tables.hhea) { - error('Required "hhea" table is not found'); - } - - // Sanitizer reduces the glyph advanceWidth to the maxAdvanceWidth - // Sometimes it's 0. That needs to be fixed - if (tables.hhea.data[10] === 0 && tables.hhea.data[11] === 0) { - tables.hhea.data[10] = 0xFF; - tables.hhea.data[11] = 0xFF; - } - - // The 'post' table has glyphs names. - if (tables.post) { - var valid = readPostScriptTable(tables.post, properties, numGlyphs); - if (!valid) { - tables.post = null; - } - } - - var charCodeToGlyphId = [], charCode, toUnicode = properties.toUnicode; - - function hasGlyph(glyphId, charCode) { - if (!missingGlyphs[glyphId]) { - return true; - } - if (charCode >= 0 && toUnicode.has(charCode)) { - return true; - } - return false; - } - - if (properties.type === 'CIDFontType2') { - var cidToGidMap = properties.cidToGidMap || []; - var isCidToGidMapEmpty = cidToGidMap.length === 0; - - properties.cMap.forEach(function(charCode, cid) { - assert(cid <= 0xffff, 'Max size of CID is 65,535'); - var glyphId = -1; - if (isCidToGidMapEmpty) { - glyphId = charCode; - } else if (cidToGidMap[cid] !== undefined) { - glyphId = cidToGidMap[cid]; - } - - if (glyphId >= 0 && glyphId < numGlyphs && - hasGlyph(glyphId, charCode)) { - charCodeToGlyphId[charCode] = glyphId; - } - }); - if (dupFirstEntry) { - charCodeToGlyphId[0] = numGlyphs - 1; - } - } else { - // Most of the following logic in this code branch is based on the - // 9.6.6.4 of the PDF spec. - var cmapTable = readCmapTable(tables.cmap, font, this.isSymbolicFont); - var cmapPlatformId = cmapTable.platformId; - var cmapEncodingId = cmapTable.encodingId; - var cmapMappings = cmapTable.mappings; - var cmapMappingsLength = cmapMappings.length; - var hasEncoding = properties.differences.length || - !!properties.baseEncodingName; - - // The spec seems to imply that if the font is symbolic the encoding - // should be ignored, this doesn't appear to work for 'preistabelle.pdf' - // where the the font is symbolic and it has an encoding. - if (hasEncoding && - (cmapPlatformId === 3 && cmapEncodingId === 1 || - cmapPlatformId === 1 && cmapEncodingId === 0) || - (cmapPlatformId === -1 && cmapEncodingId === -1 && // Temporary hack - !!Encodings[properties.baseEncodingName])) { // Temporary hack - // When no preferred cmap table was found and |baseEncodingName| is - // one of the predefined encodings, we seem to obtain a better - // |charCodeToGlyphId| map from the code below (fixes bug 1057544). - // TODO: Note that this is a hack which should be removed as soon as - // we have proper support for more exotic cmap tables. - - var baseEncoding = []; - if (properties.baseEncodingName === 'MacRomanEncoding' || - properties.baseEncodingName === 'WinAnsiEncoding') { - baseEncoding = Encodings[properties.baseEncodingName]; - } - for (charCode = 0; charCode < 256; charCode++) { - var glyphName; - if (this.differences && charCode in this.differences) { - glyphName = this.differences[charCode]; - } else if (charCode in baseEncoding && - baseEncoding[charCode] !== '') { - glyphName = baseEncoding[charCode]; - } else { - glyphName = Encodings.StandardEncoding[charCode]; - } - if (!glyphName) { - continue; - } - var unicodeOrCharCode; - if (cmapPlatformId === 3 && cmapEncodingId === 1) { - unicodeOrCharCode = GlyphsUnicode[glyphName]; - } else if (cmapPlatformId === 1 && cmapEncodingId === 0) { - // TODO: the encoding needs to be updated with mac os table. - unicodeOrCharCode = Encodings.MacRomanEncoding.indexOf(glyphName); - } - - var found = false; - for (i = 0; i < cmapMappingsLength; ++i) { - if (cmapMappings[i].charCode === unicodeOrCharCode && - hasGlyph(cmapMappings[i].glyphId, unicodeOrCharCode)) { - charCodeToGlyphId[charCode] = cmapMappings[i].glyphId; - found = true; - break; - } - } - if (!found && properties.glyphNames) { - // Try to map using the post table. There are currently no known - // pdfs that this fixes. - var glyphId = properties.glyphNames.indexOf(glyphName); - if (glyphId > 0 && hasGlyph(glyphId, -1)) { - charCodeToGlyphId[charCode] = glyphId; - } - } - } - } else if (cmapPlatformId === 0 && cmapEncodingId === 0) { - // Default Unicode semantics, use the charcodes as is. - for (i = 0; i < cmapMappingsLength; ++i) { - charCodeToGlyphId[cmapMappings[i].charCode] = - cmapMappings[i].glyphId; - } - } else { - // For (3, 0) cmap tables: - // The charcode key being stored in charCodeToGlyphId is the lower - // byte of the two-byte charcodes of the cmap table since according to - // the spec: 'each byte from the string shall be prepended with the - // high byte of the range [of charcodes in the cmap table], to form - // a two-byte character, which shall be used to select the - // associated glyph description from the subtable'. - // - // For (1, 0) cmap tables: - // 'single bytes from the string shall be used to look up the - // associated glyph descriptions from the subtable'. This means - // charcodes in the cmap will be single bytes, so no-op since - // glyph.charCode & 0xFF === glyph.charCode - for (i = 0; i < cmapMappingsLength; ++i) { - charCode = cmapMappings[i].charCode & 0xFF; - charCodeToGlyphId[charCode] = cmapMappings[i].glyphId; - } - } - } - - if (charCodeToGlyphId.length === 0) { - // defines at least one glyph - charCodeToGlyphId[0] = 0; - } - - // Converting glyphs and ids into font's cmap table - var newMapping = adjustMapping(charCodeToGlyphId, properties); - this.toFontChar = newMapping.toFontChar; - tables.cmap = { - tag: 'cmap', - data: createCmapTable(newMapping.charCodeToGlyphId) - }; - - if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) { - // extract some more font properties from the OpenType head and - // hhea tables; yMin and descent value are always negative - var override = { - unitsPerEm: int16(tables.head.data[18], tables.head.data[19]), - yMax: int16(tables.head.data[42], tables.head.data[43]), - yMin: int16(tables.head.data[38], tables.head.data[39]) - 0x10000, - ascent: int16(tables.hhea.data[4], tables.hhea.data[5]), - descent: int16(tables.hhea.data[6], tables.hhea.data[7]) - 0x10000 - }; - - tables['OS/2'] = { - tag: 'OS/2', - data: createOS2Table(properties, newMapping.charCodeToGlyphId, - override) - }; - } - - // Rewrite the 'post' table if needed - if (!tables.post) { - tables.post = { - tag: 'post', - data: createPostTable(properties) - }; - } - - if (!isTrueType) { - try { - // Trying to repair CFF file - cffFile = new Stream(tables['CFF '].data); - var parser = new CFFParser(cffFile, properties); - cff = parser.parse(); - var compiler = new CFFCompiler(cff); - tables['CFF '].data = compiler.compile(); - } catch (e) { - warn('Failed to compile font ' + properties.loadedName); - } - } - - // Re-creating 'name' table - if (!tables.name) { - tables.name = { - tag: 'name', - data: createNameTable(this.name) - }; - } else { - // ... using existing 'name' table as prototype - var namePrototype = readNameTable(tables.name); - tables.name.data = createNameTable(name, namePrototype); - } - - var builder = new OpenTypeFileBuilder(header.version); - for (var tableTag in tables) { - builder.addTable(tableTag, tables[tableTag].data); - } - return builder.toArray(); - }, - - convert: function Font_convert(fontName, font, properties) { - // TODO: Check the charstring widths to determine this. - properties.fixedPitch = false; - - var mapping = font.getGlyphMapping(properties); - var newMapping = adjustMapping(mapping, properties); - this.toFontChar = newMapping.toFontChar; - var numGlyphs = font.numGlyphs; - - function getCharCodes(charCodeToGlyphId, glyphId) { - var charCodes = null; - for (var charCode in charCodeToGlyphId) { - if (glyphId === charCodeToGlyphId[charCode]) { - if (!charCodes) { - charCodes = []; - } - charCodes.push(charCode | 0); - } - } - return charCodes; - } - - function createCharCode(charCodeToGlyphId, glyphId) { - for (var charCode in charCodeToGlyphId) { - if (glyphId === charCodeToGlyphId[charCode]) { - return charCode | 0; - } - } - newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = - glyphId; - return newMapping.nextAvailableFontCharCode++; - } - - var seacs = font.seacs; - if (SEAC_ANALYSIS_ENABLED && seacs && seacs.length) { - var matrix = properties.fontMatrix || FONT_IDENTITY_MATRIX; - var charset = font.getCharset(); - var seacMap = Object.create(null); - for (var glyphId in seacs) { - glyphId |= 0; - var seac = seacs[glyphId]; - var baseGlyphName = Encodings.StandardEncoding[seac[2]]; - var accentGlyphName = Encodings.StandardEncoding[seac[3]]; - var baseGlyphId = charset.indexOf(baseGlyphName); - var accentGlyphId = charset.indexOf(accentGlyphName); - if (baseGlyphId < 0 || accentGlyphId < 0) { - continue; - } - var accentOffset = { - x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4], - y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5] - }; - - var charCodes = getCharCodes(mapping, glyphId); - if (!charCodes) { - // There's no point in mapping it if the char code was never mapped - // to begin with. - continue; - } - for (var i = 0, ii = charCodes.length; i < ii; i++) { - var charCode = charCodes[i]; - // Find a fontCharCode that maps to the base and accent glyphs. - // If one doesn't exists, create it. - var charCodeToGlyphId = newMapping.charCodeToGlyphId; - var baseFontCharCode = createCharCode(charCodeToGlyphId, - baseGlyphId); - var accentFontCharCode = createCharCode(charCodeToGlyphId, - accentGlyphId); - seacMap[charCode] = { - baseFontCharCode: baseFontCharCode, - accentFontCharCode: accentFontCharCode, - accentOffset: accentOffset - }; - } - } - properties.seacMap = seacMap; - } - - var unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]; - - var builder = new OpenTypeFileBuilder('\x4F\x54\x54\x4F'); - // PostScript Font Program - builder.addTable('CFF ', font.data); - // OS/2 and Windows Specific metrics - builder.addTable('OS/2', createOS2Table(properties, - newMapping.charCodeToGlyphId)); - // Character to glyphs mapping - builder.addTable('cmap', createCmapTable(newMapping.charCodeToGlyphId)); - // Font header - builder.addTable('head', - '\x00\x01\x00\x00' + // Version number - '\x00\x00\x10\x00' + // fontRevision - '\x00\x00\x00\x00' + // checksumAdjustement - '\x5F\x0F\x3C\xF5' + // magicNumber - '\x00\x00' + // Flags - safeString16(unitsPerEm) + // unitsPerEM - '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // creation date - '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // modifification date - '\x00\x00' + // xMin - safeString16(properties.descent) + // yMin - '\x0F\xFF' + // xMax - safeString16(properties.ascent) + // yMax - string16(properties.italicAngle ? 2 : 0) + // macStyle - '\x00\x11' + // lowestRecPPEM - '\x00\x00' + // fontDirectionHint - '\x00\x00' + // indexToLocFormat - '\x00\x00'); // glyphDataFormat - - // Horizontal header - builder.addTable('hhea', - '\x00\x01\x00\x00' + // Version number - safeString16(properties.ascent) + // Typographic Ascent - safeString16(properties.descent) + // Typographic Descent - '\x00\x00' + // Line Gap - '\xFF\xFF' + // advanceWidthMax - '\x00\x00' + // minLeftSidebearing - '\x00\x00' + // minRightSidebearing - '\x00\x00' + // xMaxExtent - safeString16(properties.capHeight) + // caretSlopeRise - safeString16(Math.tan(properties.italicAngle) * - properties.xHeight) + // caretSlopeRun - '\x00\x00' + // caretOffset - '\x00\x00' + // -reserved- - '\x00\x00' + // -reserved- - '\x00\x00' + // -reserved- - '\x00\x00' + // -reserved- - '\x00\x00' + // metricDataFormat - string16(numGlyphs)); // Number of HMetrics - - // Horizontal metrics - builder.addTable('hmtx', (function fontFieldsHmtx() { - var charstrings = font.charstrings; - var cffWidths = font.cff ? font.cff.widths : null; - var hmtx = '\x00\x00\x00\x00'; // Fake .notdef - for (var i = 1, ii = numGlyphs; i < ii; i++) { - var width = 0; - if (charstrings) { - var charstring = charstrings[i - 1]; - width = 'width' in charstring ? charstring.width : 0; - } else if (cffWidths) { - width = Math.ceil(cffWidths[i] || 0); - } - hmtx += string16(width) + string16(0); - } - return hmtx; - })()); - - // Maximum profile - builder.addTable('maxp', - '\x00\x00\x50\x00' + // Version number - string16(numGlyphs)); // Num of glyphs - - // Naming tables - builder.addTable('name', createNameTable(fontName)); - - // PostScript informations - builder.addTable('post', createPostTable(properties)); - - return builder.toArray(); - }, - - /** - * Builds a char code to unicode map based on section 9.10 of the spec. - * @param {Object} properties Font properties object. - * @return {Object} A ToUnicodeMap object. - */ - buildToUnicode: function Font_buildToUnicode(properties) { - // Section 9.10.2 Mapping Character Codes to Unicode Values - if (properties.toUnicode && properties.toUnicode.length !== 0) { - return properties.toUnicode; - } - // According to the spec if the font is a simple font we should only map - // to unicode if the base encoding is MacRoman, MacExpert, or WinAnsi or - // the differences array only contains adobe standard or symbol set names, - // in pratice it seems better to always try to create a toUnicode - // map based of the default encoding. - var toUnicode, charcode; - if (!properties.composite /* is simple font */) { - toUnicode = []; - var encoding = properties.defaultEncoding.slice(); - var baseEncodingName = properties.baseEncodingName; - // Merge in the differences array. - var differences = properties.differences; - for (charcode in differences) { - encoding[charcode] = differences[charcode]; - } - for (charcode in encoding) { - // a) Map the character code to a character name. - var glyphName = encoding[charcode]; - // b) Look up the character name in the Adobe Glyph List (see the - // Bibliography) to obtain the corresponding Unicode value. - if (glyphName === '') { - continue; - } else if (GlyphsUnicode[glyphName] === undefined) { - // (undocumented) c) Few heuristics to recognize unknown glyphs - // NOTE: Adobe Reader does not do this step, but OSX Preview does - var code = 0; - switch (glyphName[0]) { - case 'G': // Gxx glyph - if (glyphName.length === 3) { - code = parseInt(glyphName.substr(1), 16); - } - break; - case 'g': // g00xx glyph - if (glyphName.length === 5) { - code = parseInt(glyphName.substr(1), 16); - } - break; - case 'C': // Cddd glyph - case 'c': // cddd glyph - if (glyphName.length >= 3) { - code = +glyphName.substr(1); - } - break; - } - if (code) { - // If |baseEncodingName| is one the predefined encodings, - // and |code| equals |charcode|, using the glyph defined in the - // baseEncoding seems to yield a better |toUnicode| mapping - // (fixes issue 5070). - if (baseEncodingName && code === +charcode) { - var baseEncoding = Encodings[baseEncodingName]; - if (baseEncoding && (glyphName = baseEncoding[charcode])) { - toUnicode[charcode] = - String.fromCharCode(GlyphsUnicode[glyphName]); - continue; - } - } - toUnicode[charcode] = String.fromCharCode(code); - } - continue; - } - toUnicode[charcode] = String.fromCharCode(GlyphsUnicode[glyphName]); - } - return new ToUnicodeMap(toUnicode); - } - // If the font is a composite font that uses one of the predefined CMaps - // listed in Table 118 (except Identity–H and Identity–V) or whose - // descendant CIDFont uses the Adobe-GB1, Adobe-CNS1, Adobe-Japan1, or - // Adobe-Korea1 character collection: - if (properties.composite && ( - (properties.cMap.builtInCMap && - !(properties.cMap instanceof IdentityCMap)) || - (properties.cidSystemInfo.registry === 'Adobe' && - (properties.cidSystemInfo.ordering === 'GB1' || - properties.cidSystemInfo.ordering === 'CNS1' || - properties.cidSystemInfo.ordering === 'Japan1' || - properties.cidSystemInfo.ordering === 'Korea1')))) { - // Then: - // a) Map the character code to a character identifier (CID) according - // to the font’s CMap. - // b) Obtain the registry and ordering of the character collection used - // by the font’s CMap (for example, Adobe and Japan1) from its - // CIDSystemInfo dictionary. - var registry = properties.cidSystemInfo.registry; - var ordering = properties.cidSystemInfo.ordering; - // c) Construct a second CMap name by concatenating the registry and - // ordering obtained in step (b) in the format registry–ordering–UCS2 - // (for example, Adobe–Japan1–UCS2). - var ucs2CMapName = new Name(registry + '-' + ordering + '-UCS2'); - // d) Obtain the CMap with the name constructed in step (c) (available - // from the ASN Web site; see the Bibliography). - var ucs2CMap = CMapFactory.create(ucs2CMapName, - { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null); - var cMap = properties.cMap; - toUnicode = []; - cMap.forEach(function(charcode, cid) { - assert(cid <= 0xffff, 'Max size of CID is 65,535'); - // e) Map the CID obtained in step (a) according to the CMap obtained - // in step (d), producing a Unicode value. - var ucs2 = ucs2CMap.lookup(cid); - if (ucs2) { - toUnicode[charcode] = - String.fromCharCode((ucs2.charCodeAt(0) << 8) + - ucs2.charCodeAt(1)); - } - }); - return new ToUnicodeMap(toUnicode); - } - - // The viewer's choice, just use an identity map. - return new IdentityToUnicodeMap(properties.firstChar, - properties.lastChar); - }, - - get spaceWidth() { - if ('_shadowWidth' in this) { - return this._shadowWidth; - } - - // trying to estimate space character width - var possibleSpaceReplacements = ['space', 'minus', 'one', 'i']; - var width; - for (var i = 0, ii = possibleSpaceReplacements.length; i < ii; i++) { - var glyphName = possibleSpaceReplacements[i]; - // if possible, getting width by glyph name - if (glyphName in this.widths) { - width = this.widths[glyphName]; - break; - } - var glyphUnicode = GlyphsUnicode[glyphName]; - // finding the charcode via unicodeToCID map - var charcode = 0; - if (this.composite) { - if (this.cMap.contains(glyphUnicode)) { - charcode = this.cMap.lookup(glyphUnicode); - } - } - // ... via toUnicode map - if (!charcode && 'toUnicode' in this) { - charcode = this.toUnicode.charCodeOf(glyphUnicode); - } - // setting it to unicode if negative or undefined - if (charcode <= 0) { - charcode = glyphUnicode; - } - // trying to get width via charcode - width = this.widths[charcode]; - if (width) { - break; // the non-zero width found - } - } - width = width || this.defaultWidth; - // Do not shadow the property here. See discussion: - // https://github.com/mozilla/pdf.js/pull/2127#discussion_r1662280 - this._shadowWidth = width; - return width; - }, - - charToGlyph: function Font_charToGlyph(charcode) { - var fontCharCode, width, operatorListId; - - var widthCode = charcode; - if (this.cMap && this.cMap.contains(charcode)) { - widthCode = this.cMap.lookup(charcode); - } - width = this.widths[widthCode]; - width = isNum(width) ? width : this.defaultWidth; - var vmetric = this.vmetrics && this.vmetrics[widthCode]; - - var unicode = this.toUnicode.get(charcode) || charcode; - if (typeof unicode === 'number') { - unicode = String.fromCharCode(unicode); - } - - // First try the toFontChar map, if it's not there then try falling - // back to the char code. - fontCharCode = this.toFontChar[charcode] || charcode; - if (this.missingFile) { - fontCharCode = mapSpecialUnicodeValues(fontCharCode); - } - - if (this.isType3Font) { - // Font char code in this case is actually a glyph name. - operatorListId = fontCharCode; - } - - var accent = null; - if (this.seacMap && this.seacMap[charcode]) { - var seac = this.seacMap[charcode]; - fontCharCode = seac.baseFontCharCode; - accent = { - fontChar: String.fromCharCode(seac.accentFontCharCode), - offset: seac.accentOffset - }; - } - - var fontChar = String.fromCharCode(fontCharCode); - - var glyph = this.glyphCache[charcode]; - if (!glyph || - !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, - operatorListId)) { - glyph = new Glyph(fontChar, unicode, accent, width, vmetric, - operatorListId); - this.glyphCache[charcode] = glyph; - } - return glyph; - }, - - charsToGlyphs: function Font_charsToGlyphs(chars) { - var charsCache = this.charsCache; - var glyphs, glyph, charcode; - - // if we translated this string before, just grab it from the cache - if (charsCache) { - glyphs = charsCache[chars]; - if (glyphs) { - return glyphs; - } - } - - // lazily create the translation cache - if (!charsCache) { - charsCache = this.charsCache = Object.create(null); - } - - glyphs = []; - var charsCacheKey = chars; - var i = 0, ii; - - if (this.cMap) { - // composite fonts have multi-byte strings convert the string from - // single-byte to multi-byte - var c = {}; - while (i < chars.length) { - this.cMap.readCharCode(chars, i, c); - charcode = c.charcode; - var length = c.length; - i += length; - glyph = this.charToGlyph(charcode); - glyphs.push(glyph); - // placing null after each word break charcode (ASCII SPACE) - // Ignore occurences of 0x20 in multiple-byte codes. - if (length === 1 && chars.charCodeAt(i - 1) === 0x20) { - glyphs.push(null); - } - } - } else { - for (i = 0, ii = chars.length; i < ii; ++i) { - charcode = chars.charCodeAt(i); - glyph = this.charToGlyph(charcode); - glyphs.push(glyph); - if (charcode === 0x20) { - glyphs.push(null); - } - } - } - - // Enter the translated string into the cache - return (charsCache[charsCacheKey] = glyphs); - } - }; - - return Font; -})(); - -var ErrorFont = (function ErrorFontClosure() { - function ErrorFont(error) { - this.error = error; - this.loadedName = 'g_font_error'; - this.loading = false; - } - - ErrorFont.prototype = { - charsToGlyphs: function ErrorFont_charsToGlyphs() { - return []; - }, - exportData: function ErrorFont_exportData() { - return {error: this.error}; - } - }; - - return ErrorFont; -})(); - -/** - * Shared logic for building a char code to glyph id mapping for Type1 and - * simple CFF fonts. See section 9.6.6.2 of the spec. - * @param {Object} properties Font properties object. - * @param {Object} builtInEncoding The encoding contained within the actual font - * data. - * @param {Array} Array of glyph names where the index is the glyph ID. - * @returns {Object} A char code to glyph ID map. - */ -function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) { - var charCodeToGlyphId = Object.create(null); - var glyphId, charCode, baseEncoding; - - if (properties.baseEncodingName) { - // If a valid base encoding name was used, the mapping is initialized with - // that. - baseEncoding = Encodings[properties.baseEncodingName]; - for (charCode = 0; charCode < baseEncoding.length; charCode++) { - glyphId = glyphNames.indexOf(baseEncoding[charCode]); - if (glyphId >= 0) { - charCodeToGlyphId[charCode] = glyphId; - } else { - charCodeToGlyphId[charCode] = 0; // notdef - } - } - } else if (!!(properties.flags & FontFlags.Symbolic)) { - // For a symbolic font the encoding should be the fonts built-in - // encoding. - for (charCode in builtInEncoding) { - charCodeToGlyphId[charCode] = builtInEncoding[charCode]; - } - } else { - // For non-symbolic fonts that don't have a base encoding the standard - // encoding should be used. - baseEncoding = Encodings.StandardEncoding; - for (charCode = 0; charCode < baseEncoding.length; charCode++) { - glyphId = glyphNames.indexOf(baseEncoding[charCode]); - if (glyphId >= 0) { - charCodeToGlyphId[charCode] = glyphId; - } else { - charCodeToGlyphId[charCode] = 0; // notdef - } - } - } - - // Lastly, merge in the differences. - var differences = properties.differences; - if (differences) { - for (charCode in differences) { - var glyphName = differences[charCode]; - glyphId = glyphNames.indexOf(glyphName); - if (glyphId >= 0) { - charCodeToGlyphId[charCode] = glyphId; - } else { - charCodeToGlyphId[charCode] = 0; // notdef - } - } - } - return charCodeToGlyphId; -} - -/* - * CharStrings are encoded following the the CharString Encoding sequence - * describe in Chapter 6 of the "Adobe Type1 Font Format" specification. - * The value in a byte indicates a command, a number, or subsequent bytes - * that are to be interpreted in a special way. - * - * CharString Number Encoding: - * A CharString byte containing the values from 32 through 255 inclusive - * indicate an integer. These values are decoded in four ranges. - * - * 1. A CharString byte containing a value, v, between 32 and 246 inclusive, - * indicate the integer v - 139. Thus, the integer values from -107 through - * 107 inclusive may be encoded in single byte. - * - * 2. A CharString byte containing a value, v, between 247 and 250 inclusive, - * indicates an integer involving the next byte, w, according to the formula: - * [(v - 247) x 256] + w + 108 - * - * 3. A CharString byte containing a value, v, between 251 and 254 inclusive, - * indicates an integer involving the next byte, w, according to the formula: - * -[(v - 251) * 256] - w - 108 - * - * 4. A CharString containing the value 255 indicates that the next 4 bytes - * are a two complement signed integer. The first of these bytes contains the - * highest order bits, the second byte contains the next higher order bits - * and the fourth byte contain the lowest order bits. - * - * - * CharString Command Encoding: - * CharStrings commands are encoded in 1 or 2 bytes. - * - * Single byte commands are encoded in 1 byte that contains a value between - * 0 and 31 inclusive. - * If a command byte contains the value 12, then the value in the next byte - * indicates a command. This "escape" mechanism allows many extra commands - * to be encoded and this encoding technique helps to minimize the length of - * the charStrings. - */ -var Type1CharString = (function Type1CharStringClosure() { - var COMMAND_MAP = { - 'hstem': [1], - 'vstem': [3], - 'vmoveto': [4], - 'rlineto': [5], - 'hlineto': [6], - 'vlineto': [7], - 'rrcurveto': [8], - 'callsubr': [10], - 'flex': [12, 35], - 'drop' : [12, 18], - 'endchar': [14], - 'rmoveto': [21], - 'hmoveto': [22], - 'vhcurveto': [30], - 'hvcurveto': [31] - }; - - function Type1CharString() { - this.width = 0; - this.lsb = 0; - this.flexing = false; - this.output = []; - this.stack = []; - } - - Type1CharString.prototype = { - convert: function Type1CharString_convert(encoded, subrs) { - var count = encoded.length; - var error = false; - var wx, sbx, subrNumber; - for (var i = 0; i < count; i++) { - var value = encoded[i]; - if (value < 32) { - if (value === 12) { - value = (value << 8) + encoded[++i]; - } - switch (value) { - case 1: // hstem - if (!HINTING_ENABLED) { - this.stack = []; - break; - } - error = this.executeCommand(2, COMMAND_MAP.hstem); - break; - case 3: // vstem - if (!HINTING_ENABLED) { - this.stack = []; - break; - } - error = this.executeCommand(2, COMMAND_MAP.vstem); - break; - case 4: // vmoveto - if (this.flexing) { - if (this.stack.length < 1) { - error = true; - break; - } - // Add the dx for flex and but also swap the values so they are - // the right order. - var dy = this.stack.pop(); - this.stack.push(0, dy); - break; - } - error = this.executeCommand(1, COMMAND_MAP.vmoveto); - break; - case 5: // rlineto - error = this.executeCommand(2, COMMAND_MAP.rlineto); - break; - case 6: // hlineto - error = this.executeCommand(1, COMMAND_MAP.hlineto); - break; - case 7: // vlineto - error = this.executeCommand(1, COMMAND_MAP.vlineto); - break; - case 8: // rrcurveto - error = this.executeCommand(6, COMMAND_MAP.rrcurveto); - break; - case 9: // closepath - // closepath is a Type1 command that does not take argument and is - // useless in Type2 and it can simply be ignored. - this.stack = []; - break; - case 10: // callsubr - if (this.stack.length < 1) { - error = true; - break; - } - subrNumber = this.stack.pop(); - error = this.convert(subrs[subrNumber], subrs); - break; - case 11: // return - return error; - case 13: // hsbw - if (this.stack.length < 2) { - error = true; - break; - } - // To convert to type2 we have to move the width value to the - // first part of the charstring and then use hmoveto with lsb. - wx = this.stack.pop(); - sbx = this.stack.pop(); - this.lsb = sbx; - this.width = wx; - this.stack.push(wx, sbx); - error = this.executeCommand(2, COMMAND_MAP.hmoveto); - break; - case 14: // endchar - this.output.push(COMMAND_MAP.endchar[0]); - break; - case 21: // rmoveto - if (this.flexing) { - break; - } - error = this.executeCommand(2, COMMAND_MAP.rmoveto); - break; - case 22: // hmoveto - if (this.flexing) { - // Add the dy for flex. - this.stack.push(0); - break; - } - error = this.executeCommand(1, COMMAND_MAP.hmoveto); - break; - case 30: // vhcurveto - error = this.executeCommand(4, COMMAND_MAP.vhcurveto); - break; - case 31: // hvcurveto - error = this.executeCommand(4, COMMAND_MAP.hvcurveto); - break; - case (12 << 8) + 0: // dotsection - // dotsection is a Type1 command to specify some hinting feature - // for dots that do not take a parameter and it can safely be - // ignored for Type2. - this.stack = []; - break; - case (12 << 8) + 1: // vstem3 - if (!HINTING_ENABLED) { - this.stack = []; - break; - } - // [vh]stem3 are Type1 only and Type2 supports [vh]stem with - // multiple parameters, so instead of returning [vh]stem3 take a - // shortcut and return [vhstem] instead. - error = this.executeCommand(2, COMMAND_MAP.vstem); - break; - case (12 << 8) + 2: // hstem3 - if (!HINTING_ENABLED) { - this.stack = []; - break; - } - // See vstem3. - error = this.executeCommand(2, COMMAND_MAP.hstem); - break; - case (12 << 8) + 6: // seac - // seac is like type 2's special endchar but it doesn't use the - // first argument asb, so remove it. - if (SEAC_ANALYSIS_ENABLED) { - this.seac = this.stack.splice(-4, 4); - error = this.executeCommand(0, COMMAND_MAP.endchar); - } else { - error = this.executeCommand(4, COMMAND_MAP.endchar); - } - break; - case (12 << 8) + 7: // sbw - if (this.stack.length < 4) { - error = true; - break; - } - // To convert to type2 we have to move the width value to the - // first part of the charstring and then use rmoveto with - // (dx, dy). The height argument will not be used for vmtx and - // vhea tables reconstruction -- ignoring it. - var wy = this.stack.pop(); - wx = this.stack.pop(); - var sby = this.stack.pop(); - sbx = this.stack.pop(); - this.lsb = sbx; - this.width = wx; - this.stack.push(wx, sbx, sby); - error = this.executeCommand(3, COMMAND_MAP.rmoveto); - break; - case (12 << 8) + 12: // div - if (this.stack.length < 2) { - error = true; - break; - } - var num2 = this.stack.pop(); - var num1 = this.stack.pop(); - this.stack.push(num1 / num2); - break; - case (12 << 8) + 16: // callothersubr - if (this.stack.length < 2) { - error = true; - break; - } - subrNumber = this.stack.pop(); - var numArgs = this.stack.pop(); - if (subrNumber === 0 && numArgs === 3) { - var flexArgs = this.stack.splice(this.stack.length - 17, 17); - this.stack.push( - flexArgs[2] + flexArgs[0], // bcp1x + rpx - flexArgs[3] + flexArgs[1], // bcp1y + rpy - flexArgs[4], // bcp2x - flexArgs[5], // bcp2y - flexArgs[6], // p2x - flexArgs[7], // p2y - flexArgs[8], // bcp3x - flexArgs[9], // bcp3y - flexArgs[10], // bcp4x - flexArgs[11], // bcp4y - flexArgs[12], // p3x - flexArgs[13], // p3y - flexArgs[14] // flexDepth - // 15 = finalx unused by flex - // 16 = finaly unused by flex - ); - error = this.executeCommand(13, COMMAND_MAP.flex, true); - this.flexing = false; - this.stack.push(flexArgs[15], flexArgs[16]); - } else if (subrNumber === 1 && numArgs === 0) { - this.flexing = true; - } - break; - case (12 << 8) + 17: // pop - // Ignore this since it is only used with othersubr. - break; - case (12 << 8) + 33: // setcurrentpoint - // Ignore for now. - this.stack = []; - break; - default: - warn('Unknown type 1 charstring command of "' + value + '"'); - break; - } - if (error) { - break; - } - continue; - } else if (value <= 246) { - value = value - 139; - } else if (value <= 250) { - value = ((value - 247) * 256) + encoded[++i] + 108; - } else if (value <= 254) { - value = -((value - 251) * 256) - encoded[++i] - 108; - } else { - value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | - (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0; - } - this.stack.push(value); - } - return error; - }, - - executeCommand: function(howManyArgs, command, keepStack) { - var stackLength = this.stack.length; - if (howManyArgs > stackLength) { - return true; - } - var start = stackLength - howManyArgs; - for (var i = start; i < stackLength; i++) { - var value = this.stack[i]; - if (value === (value | 0)) { // int - this.output.push(28, (value >> 8) & 0xff, value & 0xff); - } else { // fixed point - value = (65536 * value) | 0; - this.output.push(255, - (value >> 24) & 0xFF, - (value >> 16) & 0xFF, - (value >> 8) & 0xFF, - value & 0xFF); - } - } - this.output.push.apply(this.output, command); - if (keepStack) { - this.stack.splice(start, howManyArgs); - } else { - this.stack.length = 0; - } - return false; - } - }; - - return Type1CharString; -})(); - -/* - * Type1Parser encapsulate the needed code for parsing a Type1 font - * program. Some of its logic depends on the Type2 charstrings - * structure. - * Note: this doesn't really parse the font since that would require evaluation - * of PostScript, but it is possible in most cases to extract what we need - * without a full parse. - */ -var Type1Parser = (function Type1ParserClosure() { - /* - * Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence - * of Plaintext Bytes. The function took a key as a parameter which can be - * for decrypting the eexec block of for decoding charStrings. - */ - var EEXEC_ENCRYPT_KEY = 55665; - var CHAR_STRS_ENCRYPT_KEY = 4330; - - function isHexDigit(code) { - return code >= 48 && code <= 57 || // '0'-'9' - code >= 65 && code <= 70 || // 'A'-'F' - code >= 97 && code <= 102; // 'a'-'f' - } - - function decrypt(data, key, discardNumber) { - var r = key | 0, c1 = 52845, c2 = 22719; - var count = data.length; - var decrypted = new Uint8Array(count); - for (var i = 0; i < count; i++) { - var value = data[i]; - decrypted[i] = value ^ (r >> 8); - r = ((value + r) * c1 + c2) & ((1 << 16) - 1); - } - return Array.prototype.slice.call(decrypted, discardNumber); - } - - function decryptAscii(data, key, discardNumber) { - var r = key | 0, c1 = 52845, c2 = 22719; - var count = data.length, maybeLength = count >>> 1; - var decrypted = new Uint8Array(maybeLength); - var i, j; - for (i = 0, j = 0; i < count; i++) { - var digit1 = data[i]; - if (!isHexDigit(digit1)) { - continue; - } - i++; - var digit2; - while (i < count && !isHexDigit(digit2 = data[i])) { - i++; - } - if (i < count) { - var value = parseInt(String.fromCharCode(digit1, digit2), 16); - decrypted[j++] = value ^ (r >> 8); - r = ((value + r) * c1 + c2) & ((1 << 16) - 1); - } - } - return Array.prototype.slice.call(decrypted, discardNumber, j); - } - - function isSpecial(c) { - return c === 0x2F || // '/' - c === 0x5B || c === 0x5D || // '[', ']' - c === 0x7B || c === 0x7D || // '{', '}' - c === 0x28 || c === 0x29; // '(', ')' - } - - function Type1Parser(stream, encrypted) { - if (encrypted) { - var data = stream.getBytes(); - var isBinary = !(isHexDigit(data[0]) && isHexDigit(data[1]) && - isHexDigit(data[2]) && isHexDigit(data[3])); - stream = new Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : - decryptAscii(data, EEXEC_ENCRYPT_KEY, 4)); - } - this.stream = stream; - this.nextChar(); - } - - Type1Parser.prototype = { - readNumberArray: function Type1Parser_readNumberArray() { - this.getToken(); // read '[' or '{' (arrays can start with either) - var array = []; - while (true) { - var token = this.getToken(); - if (token === null || token === ']' || token === '}') { - break; - } - array.push(parseFloat(token || 0)); - } - return array; - }, - - readNumber: function Type1Parser_readNumber() { - var token = this.getToken(); - return parseFloat(token || 0); - }, - - readInt: function Type1Parser_readInt() { - // Use '| 0' to prevent setting a double into length such as the double - // does not flow into the loop variable. - var token = this.getToken(); - return parseInt(token || 0, 10) | 0; - }, - - readBoolean: function Type1Parser_readBoolean() { - var token = this.getToken(); - - // Use 1 and 0 since that's what type2 charstrings use. - return token === 'true' ? 1 : 0; - }, - - nextChar : function Type1_nextChar() { - return (this.currentChar = this.stream.getByte()); - }, - - getToken: function Type1Parser_getToken() { - // Eat whitespace and comments. - var comment = false; - var ch = this.currentChar; - while (true) { - if (ch === -1) { - return null; - } - - if (comment) { - if (ch === 0x0A || ch === 0x0D) { - comment = false; - } - } else if (ch === 0x25) { // '%' - comment = true; - } else if (!Lexer.isSpace(ch)) { - break; - } - ch = this.nextChar(); - } - if (isSpecial(ch)) { - this.nextChar(); - return String.fromCharCode(ch); - } - var token = ''; - do { - token += String.fromCharCode(ch); - ch = this.nextChar(); - } while (ch >= 0 && !Lexer.isSpace(ch) && !isSpecial(ch)); - return token; - }, - - /* - * Returns an object containing a Subrs array and a CharStrings - * array extracted from and eexec encrypted block of data - */ - extractFontProgram: function Type1Parser_extractFontProgram() { - var stream = this.stream; - - var subrs = [], charstrings = []; - var program = { - subrs: [], - charstrings: [], - properties: { - 'privateData': { - 'lenIV': 4 - } - } - }; - var token, length, data, lenIV, encoded; - while ((token = this.getToken()) !== null) { - if (token !== '/') { - continue; - } - token = this.getToken(); - switch (token) { - case 'CharStrings': - // The number immediately following CharStrings must be greater or - // equal to the number of CharStrings. - this.getToken(); - this.getToken(); // read in 'dict' - this.getToken(); // read in 'dup' - this.getToken(); // read in 'begin' - while(true) { - token = this.getToken(); - if (token === null || token === 'end') { - break; - } - - if (token !== '/') { - continue; - } - var glyph = this.getToken(); - length = this.readInt(); - this.getToken(); // read in 'RD' or '-|' - data = stream.makeSubStream(stream.pos, length); - lenIV = program.properties.privateData['lenIV']; - encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV); - // Skip past the required space and binary data. - stream.skip(length); - this.nextChar(); - token = this.getToken(); // read in 'ND' or '|-' - if (token === 'noaccess') { - this.getToken(); // read in 'def' - } - charstrings.push({ - glyph: glyph, - encoded: encoded - }); - } - break; - case 'Subrs': - var num = this.readInt(); - this.getToken(); // read in 'array' - while ((token = this.getToken()) === 'dup') { - var index = this.readInt(); - length = this.readInt(); - this.getToken(); // read in 'RD' or '-|' - data = stream.makeSubStream(stream.pos, length); - lenIV = program.properties.privateData['lenIV']; - encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV); - // Skip past the required space and binary data. - stream.skip(length); - this.nextChar(); - token = this.getToken(); // read in 'NP' or '|' - if (token === 'noaccess') { - this.getToken(); // read in 'put' - } - subrs[index] = encoded; - } - break; - case 'BlueValues': - case 'OtherBlues': - case 'FamilyBlues': - case 'FamilyOtherBlues': - var blueArray = this.readNumberArray(); - // *Blue* values may contain invalid data: disables reading of - // those values when hinting is disabled. - if (blueArray.length > 0 && (blueArray.length % 2) === 0 && - HINTING_ENABLED) { - program.properties.privateData[token] = blueArray; - } - break; - case 'StemSnapH': - case 'StemSnapV': - program.properties.privateData[token] = this.readNumberArray(); - break; - case 'StdHW': - case 'StdVW': - program.properties.privateData[token] = - this.readNumberArray()[0]; - break; - case 'BlueShift': - case 'lenIV': - case 'BlueFuzz': - case 'BlueScale': - case 'LanguageGroup': - case 'ExpansionFactor': - program.properties.privateData[token] = this.readNumber(); - break; - case 'ForceBold': - program.properties.privateData[token] = this.readBoolean(); - break; - } - } - - for (var i = 0; i < charstrings.length; i++) { - glyph = charstrings[i].glyph; - encoded = charstrings[i].encoded; - var charString = new Type1CharString(); - var error = charString.convert(encoded, subrs); - var output = charString.output; - if (error) { - // It seems when FreeType encounters an error while evaluating a glyph - // that it completely ignores the glyph so we'll mimic that behaviour - // here and put an endchar to make the validator happy. - output = [14]; - } - program.charstrings.push({ - glyphName: glyph, - charstring: output, - width: charString.width, - lsb: charString.lsb, - seac: charString.seac - }); - } - - return program; - }, - - extractFontHeader: function Type1Parser_extractFontHeader(properties) { - var token; - while ((token = this.getToken()) !== null) { - if (token !== '/') { - continue; - } - token = this.getToken(); - switch (token) { - case 'FontMatrix': - var matrix = this.readNumberArray(); - properties.fontMatrix = matrix; - break; - case 'Encoding': - var encodingArg = this.getToken(); - var encoding; - if (!/^\d+$/.test(encodingArg)) { - // encoding name is specified - encoding = Encodings[encodingArg]; - } else { - encoding = []; - var size = parseInt(encodingArg, 10) | 0; - this.getToken(); // read in 'array' - - for (var j = 0; j < size; j++) { - token = this.getToken(); - // skipping till first dup or def (e.g. ignoring for statement) - while (token !== 'dup' && token !== 'def') { - token = this.getToken(); - if (token === null) { - return; // invalid header - } - } - if (token === 'def') { - break; // read all array data - } - var index = this.readInt(); - this.getToken(); // read in '/' - var glyph = this.getToken(); - encoding[index] = glyph; - this.getToken(); // read the in 'put' - } - } - properties.builtInEncoding = encoding; - break; - case 'FontBBox': - var fontBBox = this.readNumberArray(); - // adjusting ascent/descent - properties.ascent = fontBBox[3]; - properties.descent = fontBBox[1]; - properties.ascentScaled = true; - break; - } - } - } - }; - - return Type1Parser; -})(); - -/** - * The CFF class takes a Type1 file and wrap it into a - * 'Compact Font Format' which itself embed Type2 charstrings. - */ -var CFFStandardStrings = [ - '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', - 'ampersand', 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus', - 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', - 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', - 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', - 'underscore', 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', - 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', - 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', - 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', - 'periodcentered', 'paragraph', 'bullet', 'quotesinglbase', 'quotedblbase', - 'quotedblright', 'guillemotright', 'ellipsis', 'perthousand', 'questiondown', - 'grave', 'acute', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', - 'dieresis', 'ring', 'cedilla', 'hungarumlaut', 'ogonek', 'caron', 'emdash', - 'AE', 'ordfeminine', 'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', - 'dotlessi', 'lslash', 'oslash', 'oe', 'germandbls', 'onesuperior', - 'logicalnot', 'mu', 'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', - 'onequarter', 'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', - 'twosuperior', 'registered', 'minus', 'eth', 'multiply', 'threesuperior', - 'copyright', 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', - 'Atilde', 'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', - 'Iacute', 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', - 'Ocircumflex', 'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', - 'Ucircumflex', 'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', - 'aacute', 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', - 'ccedilla', 'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', - 'icircumflex', 'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', - 'odieresis', 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', - 'udieresis', 'ugrave', 'yacute', 'ydieresis', 'zcaron', 'exclamsmall', - 'Hungarumlautsmall', 'dollaroldstyle', 'dollarsuperior', 'ampersandsmall', - 'Acutesmall', 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', - 'onedotenleader', 'zerooldstyle', 'oneoldstyle', 'twooldstyle', - 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', - 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'commasuperior', - 'threequartersemdash', 'periodsuperior', 'questionsmall', 'asuperior', - 'bsuperior', 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', - 'lsuperior', 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', - 'tsuperior', 'ff', 'ffi', 'ffl', 'parenleftinferior', 'parenrightinferior', - 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 'Asmall', 'Bsmall', - 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall', - 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', 'Osmall', 'Psmall', - 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall', - 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', - 'Tildesmall', 'exclamdownsmall', 'centoldstyle', 'Lslashsmall', - 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall', 'Caronsmall', - 'Dotaccentsmall', 'Macronsmall', 'figuredash', 'hypheninferior', - 'Ogoneksmall', 'Ringsmall', 'Cedillasmall', 'questiondownsmall', 'oneeighth', - 'threeeighths', 'fiveeighths', 'seveneighths', 'onethird', 'twothirds', - 'zerosuperior', 'foursuperior', 'fivesuperior', 'sixsuperior', - 'sevensuperior', 'eightsuperior', 'ninesuperior', 'zeroinferior', - 'oneinferior', 'twoinferior', 'threeinferior', 'fourinferior', - 'fiveinferior', 'sixinferior', 'seveninferior', 'eightinferior', - 'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior', - 'commainferior', 'Agravesmall', 'Aacutesmall', 'Acircumflexsmall', - 'Atildesmall', 'Adieresissmall', 'Aringsmall', 'AEsmall', 'Ccedillasmall', - 'Egravesmall', 'Eacutesmall', 'Ecircumflexsmall', 'Edieresissmall', - 'Igravesmall', 'Iacutesmall', 'Icircumflexsmall', 'Idieresissmall', - 'Ethsmall', 'Ntildesmall', 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', - 'Otildesmall', 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', - 'Uacutesmall', 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', - 'Thornsmall', 'Ydieresissmall', '001.000', '001.001', '001.002', '001.003', - 'Black', 'Bold', 'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold' -]; - -// Type1Font is also a CIDFontType0. -var Type1Font = function Type1Font(name, file, properties) { - // Some bad generators embed pfb file as is, we have to strip 6-byte headers. - // Also, length1 and length2 might be off by 6 bytes as well. - // http://www.math.ubc.ca/~cass/piscript/type1.pdf - var PFB_HEADER_SIZE = 6; - var headerBlockLength = properties.length1; - var eexecBlockLength = properties.length2; - var pfbHeader = file.peekBytes(PFB_HEADER_SIZE); - var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01; - if (pfbHeaderPresent) { - file.skip(PFB_HEADER_SIZE); - headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | - (pfbHeader[3] << 8) | pfbHeader[2]; - } - - // Get the data block containing glyphs and subrs informations - var headerBlock = new Stream(file.getBytes(headerBlockLength)); - var headerBlockParser = new Type1Parser(headerBlock); - headerBlockParser.extractFontHeader(properties); - - if (pfbHeaderPresent) { - pfbHeader = file.getBytes(PFB_HEADER_SIZE); - eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | - (pfbHeader[3] << 8) | pfbHeader[2]; - } - - // Decrypt the data blocks and retrieve it's content - var eexecBlock = new Stream(file.getBytes(eexecBlockLength)); - var eexecBlockParser = new Type1Parser(eexecBlock, true); - var data = eexecBlockParser.extractFontProgram(); - for (var info in data.properties) { - properties[info] = data.properties[info]; - } - - var charstrings = data.charstrings; - var type2Charstrings = this.getType2Charstrings(charstrings); - var subrs = this.getType2Subrs(data.subrs); - - this.charstrings = charstrings; - this.data = this.wrap(name, type2Charstrings, this.charstrings, - subrs, properties); - this.seacs = this.getSeacs(data.charstrings); -}; - -Type1Font.prototype = { - get numGlyphs() { - return this.charstrings.length + 1; - }, - - getCharset: function Type1Font_getCharset() { - var charset = ['.notdef']; - var charstrings = this.charstrings; - for (var glyphId = 0; glyphId < charstrings.length; glyphId++) { - charset.push(charstrings[glyphId].glyphName); - } - return charset; - }, - - getGlyphMapping: function Type1Font_getGlyphMapping(properties) { - var charstrings = this.charstrings; - var glyphNames = ['.notdef'], glyphId; - for (glyphId = 0; glyphId < charstrings.length; glyphId++) { - glyphNames.push(charstrings[glyphId].glyphName); - } - var encoding = properties.builtInEncoding; - if (encoding) { - var builtInEncoding = {}; - for (var charCode in encoding) { - glyphId = glyphNames.indexOf(encoding[charCode]); - if (glyphId >= 0) { - builtInEncoding[charCode] = glyphId; - } - } - } - - return type1FontGlyphMapping(properties, builtInEncoding, glyphNames); - }, - - getSeacs: function Type1Font_getSeacs(charstrings) { - var i, ii; - var seacMap = []; - for (i = 0, ii = charstrings.length; i < ii; i++) { - var charstring = charstrings[i]; - if (charstring.seac) { - // Offset by 1 for .notdef - seacMap[i + 1] = charstring.seac; - } - } - return seacMap; - }, - - getType2Charstrings: function Type1Font_getType2Charstrings( - type1Charstrings) { - var type2Charstrings = []; - for (var i = 0, ii = type1Charstrings.length; i < ii; i++) { - type2Charstrings.push(type1Charstrings[i].charstring); - } - return type2Charstrings; - }, - - getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) { - var bias = 0; - var count = type1Subrs.length; - if (count < 1133) { - bias = 107; - } else if (count < 33769) { - bias = 1131; - } else { - bias = 32768; - } - - // Add a bunch of empty subrs to deal with the Type2 bias - var type2Subrs = []; - var i; - for (i = 0; i < bias; i++) { - type2Subrs.push([0x0B]); - } - - for (i = 0; i < count; i++) { - type2Subrs.push(type1Subrs[i]); - } - - return type2Subrs; - }, - - wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs, properties) { - var cff = new CFF(); - cff.header = new CFFHeader(1, 0, 4, 4); - - cff.names = [name]; - - var topDict = new CFFTopDict(); - // CFF strings IDs 0...390 are predefined names, so refering - // to entries in our own String INDEX starts at SID 391. - topDict.setByName('version', 391); - topDict.setByName('Notice', 392); - topDict.setByName('FullName', 393); - topDict.setByName('FamilyName', 394); - topDict.setByName('Weight', 395); - topDict.setByName('Encoding', null); // placeholder - topDict.setByName('FontMatrix', properties.fontMatrix); - topDict.setByName('FontBBox', properties.bbox); - topDict.setByName('charset', null); // placeholder - topDict.setByName('CharStrings', null); // placeholder - topDict.setByName('Private', null); // placeholder - cff.topDict = topDict; - - var strings = new CFFStrings(); - strings.add('Version 0.11'); // Version - strings.add('See original notice'); // Notice - strings.add(name); // FullName - strings.add(name); // FamilyName - strings.add('Medium'); // Weight - cff.strings = strings; - - cff.globalSubrIndex = new CFFIndex(); - - var count = glyphs.length; - var charsetArray = [0]; - var i, ii; - for (i = 0; i < count; i++) { - var index = CFFStandardStrings.indexOf(charstrings[i].glyphName); - // TODO: Insert the string and correctly map it. Previously it was - // thought mapping names that aren't in the standard strings to .notdef - // was fine, however in issue818 when mapping them all to .notdef the - // adieresis glyph no longer worked. - if (index === -1) { - index = 0; - } - charsetArray.push((index >> 8) & 0xff, index & 0xff); - } - cff.charset = new CFFCharset(false, 0, [], charsetArray); - - var charStringsIndex = new CFFIndex(); - charStringsIndex.add([0x8B, 0x0E]); // .notdef - for (i = 0; i < count; i++) { - charStringsIndex.add(glyphs[i]); - } - cff.charStrings = charStringsIndex; - - var privateDict = new CFFPrivateDict(); - privateDict.setByName('Subrs', null); // placeholder - var fields = [ - 'BlueValues', - 'OtherBlues', - 'FamilyBlues', - 'FamilyOtherBlues', - 'StemSnapH', - 'StemSnapV', - 'BlueShift', - 'BlueFuzz', - 'BlueScale', - 'LanguageGroup', - 'ExpansionFactor', - 'ForceBold', - 'StdHW', - 'StdVW' - ]; - for (i = 0, ii = fields.length; i < ii; i++) { - var field = fields[i]; - if (!properties.privateData.hasOwnProperty(field)) { - continue; - } - var value = properties.privateData[field]; - if (isArray(value)) { - // All of the private dictionary array data in CFF must be stored as - // "delta-encoded" numbers. - for (var j = value.length - 1; j > 0; j--) { - value[j] -= value[j - 1]; // ... difference from previous value - } - } - privateDict.setByName(field, value); - } - cff.topDict.privateDict = privateDict; - - var subrIndex = new CFFIndex(); - for (i = 0, ii = subrs.length; i < ii; i++) { - subrIndex.add(subrs[i]); - } - privateDict.subrsIndex = subrIndex; - - var compiler = new CFFCompiler(cff); - return compiler.compile(); - } -}; - -var CFFFont = (function CFFFontClosure() { - function CFFFont(file, properties) { - this.properties = properties; - - var parser = new CFFParser(file, properties); - this.cff = parser.parse(); - var compiler = new CFFCompiler(this.cff); - this.seacs = this.cff.seacs; - try { - this.data = compiler.compile(); - } catch (e) { - warn('Failed to compile font ' + properties.loadedName); - // There may have just been an issue with the compiler, set the data - // anyway and hope the font loaded. - this.data = file; - } - } - - CFFFont.prototype = { - get numGlyphs() { - return this.cff.charStrings.count; - }, - getCharset: function CFFFont_getCharset() { - return this.cff.charset.charset; - }, - getGlyphMapping: function CFFFont_getGlyphMapping() { - var cff = this.cff; - var properties = this.properties; - var charsets = cff.charset.charset; - var charCodeToGlyphId; - var glyphId; - - if (properties.composite) { - charCodeToGlyphId = Object.create(null); - if (cff.isCIDFont) { - // If the font is actually a CID font then we should use the charset - // to map CIDs to GIDs. - for (glyphId = 0; glyphId < charsets.length; glyphId++) { - var cid = charsets[glyphId]; - var charCode = properties.cMap.charCodeOf(cid); - charCodeToGlyphId[charCode] = glyphId; - } - } else { - // If it is NOT actually a CID font then CIDs should be mapped - // directly to GIDs. - for (glyphId = 0; glyphId < cff.charStrings.count; glyphId++) { - charCodeToGlyphId[glyphId] = glyphId; - } - } - return charCodeToGlyphId; - } - - var encoding = cff.encoding ? cff.encoding.encoding : null; - charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets); - return charCodeToGlyphId; - } - }; - - return CFFFont; -})(); - -var CFFParser = (function CFFParserClosure() { - var CharstringValidationData = [ - null, - { id: 'hstem', min: 2, stackClearing: true, stem: true }, - null, - { id: 'vstem', min: 2, stackClearing: true, stem: true }, - { id: 'vmoveto', min: 1, stackClearing: true }, - { id: 'rlineto', min: 2, resetStack: true }, - { id: 'hlineto', min: 1, resetStack: true }, - { id: 'vlineto', min: 1, resetStack: true }, - { id: 'rrcurveto', min: 6, resetStack: true }, - null, - { id: 'callsubr', min: 1, undefStack: true }, - { id: 'return', min: 0, undefStack: true }, - null, // 12 - null, - { id: 'endchar', min: 0, stackClearing: true }, - null, - null, - null, - { id: 'hstemhm', min: 2, stackClearing: true, stem: true }, - { id: 'hintmask', min: 0, stackClearing: true }, - { id: 'cntrmask', min: 0, stackClearing: true }, - { id: 'rmoveto', min: 2, stackClearing: true }, - { id: 'hmoveto', min: 1, stackClearing: true }, - { id: 'vstemhm', min: 2, stackClearing: true, stem: true }, - { id: 'rcurveline', min: 8, resetStack: true }, - { id: 'rlinecurve', min: 8, resetStack: true }, - { id: 'vvcurveto', min: 4, resetStack: true }, - { id: 'hhcurveto', min: 4, resetStack: true }, - null, // shortint - { id: 'callgsubr', min: 1, undefStack: true }, - { id: 'vhcurveto', min: 4, resetStack: true }, - { id: 'hvcurveto', min: 4, resetStack: true } - ]; - var CharstringValidationData12 = [ - null, - null, - null, - { id: 'and', min: 2, stackDelta: -1 }, - { id: 'or', min: 2, stackDelta: -1 }, - { id: 'not', min: 1, stackDelta: 0 }, - null, - null, - null, - { id: 'abs', min: 1, stackDelta: 0 }, - { id: 'add', min: 2, stackDelta: -1, - stackFn: function stack_div(stack, index) { - stack[index - 2] = stack[index - 2] + stack[index - 1]; - } - }, - { id: 'sub', min: 2, stackDelta: -1, - stackFn: function stack_div(stack, index) { - stack[index - 2] = stack[index - 2] - stack[index - 1]; - } - }, - { id: 'div', min: 2, stackDelta: -1, - stackFn: function stack_div(stack, index) { - stack[index - 2] = stack[index - 2] / stack[index - 1]; - } - }, - null, - { id: 'neg', min: 1, stackDelta: 0, - stackFn: function stack_div(stack, index) { - stack[index - 1] = -stack[index - 1]; - } - }, - { id: 'eq', min: 2, stackDelta: -1 }, - null, - null, - { id: 'drop', min: 1, stackDelta: -1 }, - null, - { id: 'put', min: 2, stackDelta: -2 }, - { id: 'get', min: 1, stackDelta: 0 }, - { id: 'ifelse', min: 4, stackDelta: -3 }, - { id: 'random', min: 0, stackDelta: 1 }, - { id: 'mul', min: 2, stackDelta: -1, - stackFn: function stack_div(stack, index) { - stack[index - 2] = stack[index - 2] * stack[index - 1]; - } - }, - null, - { id: 'sqrt', min: 1, stackDelta: 0 }, - { id: 'dup', min: 1, stackDelta: 1 }, - { id: 'exch', min: 2, stackDelta: 0 }, - { id: 'index', min: 2, stackDelta: 0 }, - { id: 'roll', min: 3, stackDelta: -2 }, - null, - null, - null, - { id: 'hflex', min: 7, resetStack: true }, - { id: 'flex', min: 13, resetStack: true }, - { id: 'hflex1', min: 9, resetStack: true }, - { id: 'flex1', min: 11, resetStack: true } - ]; - - function CFFParser(file, properties) { - this.bytes = file.getBytes(); - this.properties = properties; - } - CFFParser.prototype = { - parse: function CFFParser_parse() { - var properties = this.properties; - var cff = new CFF(); - this.cff = cff; - - // The first five sections must be in order, all the others are reached - // via offsets contained in one of the below. - var header = this.parseHeader(); - var nameIndex = this.parseIndex(header.endPos); - var topDictIndex = this.parseIndex(nameIndex.endPos); - var stringIndex = this.parseIndex(topDictIndex.endPos); - var globalSubrIndex = this.parseIndex(stringIndex.endPos); - - var topDictParsed = this.parseDict(topDictIndex.obj.get(0)); - var topDict = this.createDict(CFFTopDict, topDictParsed, cff.strings); - - cff.header = header.obj; - cff.names = this.parseNameIndex(nameIndex.obj); - cff.strings = this.parseStringIndex(stringIndex.obj); - cff.topDict = topDict; - cff.globalSubrIndex = globalSubrIndex.obj; - - this.parsePrivateDict(cff.topDict); - - cff.isCIDFont = topDict.hasName('ROS'); - - var charStringOffset = topDict.getByName('CharStrings'); - var charStringsAndSeacs = this.parseCharStrings(charStringOffset); - cff.charStrings = charStringsAndSeacs.charStrings; - cff.seacs = charStringsAndSeacs.seacs; - cff.widths = charStringsAndSeacs.widths; - - var fontMatrix = topDict.getByName('FontMatrix'); - if (fontMatrix) { - properties.fontMatrix = fontMatrix; - } - - var fontBBox = topDict.getByName('FontBBox'); - if (fontBBox) { - // adjusting ascent/descent - properties.ascent = fontBBox[3]; - properties.descent = fontBBox[1]; - properties.ascentScaled = true; - } - - var charset, encoding; - if (cff.isCIDFont) { - var fdArrayIndex = this.parseIndex(topDict.getByName('FDArray')).obj; - for (var i = 0, ii = fdArrayIndex.count; i < ii; ++i) { - var dictRaw = fdArrayIndex.get(i); - var fontDict = this.createDict(CFFTopDict, this.parseDict(dictRaw), - cff.strings); - this.parsePrivateDict(fontDict); - cff.fdArray.push(fontDict); - } - // cid fonts don't have an encoding - encoding = null; - charset = this.parseCharsets(topDict.getByName('charset'), - cff.charStrings.count, cff.strings, true); - cff.fdSelect = this.parseFDSelect(topDict.getByName('FDSelect'), - cff.charStrings.count); - } else { - charset = this.parseCharsets(topDict.getByName('charset'), - cff.charStrings.count, cff.strings, false); - encoding = this.parseEncoding(topDict.getByName('Encoding'), - properties, - cff.strings, charset.charset); - } - cff.charset = charset; - cff.encoding = encoding; - - return cff; - }, - parseHeader: function CFFParser_parseHeader() { - var bytes = this.bytes; - var bytesLength = bytes.length; - var offset = 0; - - // Prevent an infinite loop, by checking that the offset is within the - // bounds of the bytes array. Necessary in empty, or invalid, font files. - while (offset < bytesLength && bytes[offset] !== 1) { - ++offset; - } - if (offset >= bytesLength) { - error('Invalid CFF header'); - } else if (offset !== 0) { - info('cff data is shifted'); - bytes = bytes.subarray(offset); - this.bytes = bytes; - } - var major = bytes[0]; - var minor = bytes[1]; - var hdrSize = bytes[2]; - var offSize = bytes[3]; - var header = new CFFHeader(major, minor, hdrSize, offSize); - return { obj: header, endPos: hdrSize }; - }, - parseDict: function CFFParser_parseDict(dict) { - var pos = 0; - - function parseOperand() { - var value = dict[pos++]; - if (value === 30) { - return parseFloatOperand(pos); - } else if (value === 28) { - value = dict[pos++]; - value = ((value << 24) | (dict[pos++] << 16)) >> 16; - return value; - } else if (value === 29) { - value = dict[pos++]; - value = (value << 8) | dict[pos++]; - value = (value << 8) | dict[pos++]; - value = (value << 8) | dict[pos++]; - return value; - } else if (value >= 32 && value <= 246) { - return value - 139; - } else if (value >= 247 && value <= 250) { - return ((value - 247) * 256) + dict[pos++] + 108; - } else if (value >= 251 && value <= 254) { - return -((value - 251) * 256) - dict[pos++] - 108; - } else { - error('255 is not a valid DICT command'); - } - return -1; - } - - function parseFloatOperand() { - var str = ''; - var eof = 15; - var lookup = ['0', '1', '2', '3', '4', '5', '6', '7', '8', - '9', '.', 'E', 'E-', null, '-']; - var length = dict.length; - while (pos < length) { - var b = dict[pos++]; - var b1 = b >> 4; - var b2 = b & 15; - - if (b1 === eof) { - break; - } - str += lookup[b1]; - - if (b2 === eof) { - break; - } - str += lookup[b2]; - } - return parseFloat(str); - } - - var operands = []; - var entries = []; - - pos = 0; - var end = dict.length; - while (pos < end) { - var b = dict[pos]; - if (b <= 21) { - if (b === 12) { - b = (b << 8) | dict[++pos]; - } - entries.push([b, operands]); - operands = []; - ++pos; - } else { - operands.push(parseOperand()); - } - } - return entries; - }, - parseIndex: function CFFParser_parseIndex(pos) { - var cffIndex = new CFFIndex(); - var bytes = this.bytes; - var count = (bytes[pos++] << 8) | bytes[pos++]; - var offsets = []; - var end = pos; - var i, ii; - - if (count !== 0) { - var offsetSize = bytes[pos++]; - // add 1 for offset to determine size of last object - var startPos = pos + ((count + 1) * offsetSize) - 1; - - for (i = 0, ii = count + 1; i < ii; ++i) { - var offset = 0; - for (var j = 0; j < offsetSize; ++j) { - offset <<= 8; - offset += bytes[pos++]; - } - offsets.push(startPos + offset); - } - end = offsets[count]; - } - for (i = 0, ii = offsets.length - 1; i < ii; ++i) { - var offsetStart = offsets[i]; - var offsetEnd = offsets[i + 1]; - cffIndex.add(bytes.subarray(offsetStart, offsetEnd)); - } - return {obj: cffIndex, endPos: end}; - }, - parseNameIndex: function CFFParser_parseNameIndex(index) { - var names = []; - for (var i = 0, ii = index.count; i < ii; ++i) { - var name = index.get(i); - // OTS doesn't allow names to be over 127 characters. - var length = Math.min(name.length, 127); - var data = []; - // OTS also only permits certain characters in the name. - for (var j = 0; j < length; ++j) { - var c = name[j]; - if (j === 0 && c === 0) { - data[j] = c; - continue; - } - if ((c < 33 || c > 126) || c === 91 /* [ */ || c === 93 /* ] */ || - c === 40 /* ( */ || c === 41 /* ) */ || c === 123 /* { */ || - c === 125 /* } */ || c === 60 /* < */ || c === 62 /* > */ || - c === 47 /* / */ || c === 37 /* % */ || c === 35 /* # */) { - data[j] = 95; - continue; - } - data[j] = c; - } - names.push(bytesToString(data)); - } - return names; - }, - parseStringIndex: function CFFParser_parseStringIndex(index) { - var strings = new CFFStrings(); - for (var i = 0, ii = index.count; i < ii; ++i) { - var data = index.get(i); - strings.add(bytesToString(data)); - } - return strings; - }, - createDict: function CFFParser_createDict(Type, dict, strings) { - var cffDict = new Type(strings); - for (var i = 0, ii = dict.length; i < ii; ++i) { - var pair = dict[i]; - var key = pair[0]; - var value = pair[1]; - cffDict.setByKey(key, value); - } - return cffDict; - }, - parseCharStrings: function CFFParser_parseCharStrings(charStringOffset) { - var charStrings = this.parseIndex(charStringOffset).obj; - var seacs = []; - var widths = []; - var count = charStrings.count; - for (var i = 0; i < count; i++) { - var charstring = charStrings.get(i); - - var stackSize = 0; - var stack = []; - var undefStack = true; - var hints = 0; - var valid = true; - var data = charstring; - var length = data.length; - var firstStackClearing = true; - for (var j = 0; j < length;) { - var value = data[j++]; - var validationCommand = null; - if (value === 12) { - var q = data[j++]; - if (q === 0) { - // The CFF specification state that the 'dotsection' command - // (12, 0) is deprecated and treated as a no-op, but all Type2 - // charstrings processors should support them. Unfortunately - // the font sanitizer don't. As a workaround the sequence (12, 0) - // is replaced by a useless (0, hmoveto). - data[j - 2] = 139; - data[j - 1] = 22; - stackSize = 0; - } else { - validationCommand = CharstringValidationData12[q]; - } - } else if (value === 28) { // number (16 bit) - stack[stackSize] = ((data[j] << 24) | (data[j + 1] << 16)) >> 16; - j += 2; - stackSize++; - } else if (value === 14) { - if (stackSize >= 4) { - stackSize -= 4; - if (SEAC_ANALYSIS_ENABLED) { - seacs[i] = stack.slice(stackSize, stackSize + 4); - valid = false; - } - } - validationCommand = CharstringValidationData[value]; - } else if (value >= 32 && value <= 246) { // number - stack[stackSize] = value - 139; - stackSize++; - } else if (value >= 247 && value <= 254) { // number (+1 bytes) - stack[stackSize] = (value < 251 ? - ((value - 247) << 8) + data[j] + 108 : - -((value - 251) << 8) - data[j] - 108); - j++; - stackSize++; - } else if (value === 255) { // number (32 bit) - stack[stackSize] = ((data[j] << 24) | (data[j + 1] << 16) | - (data[j + 2] << 8) | data[j + 3]) / 65536; - j += 4; - stackSize++; - } else if (value === 19 || value === 20) { - hints += stackSize >> 1; - j += (hints + 7) >> 3; // skipping right amount of hints flag data - stackSize %= 2; - validationCommand = CharstringValidationData[value]; - } else { - validationCommand = CharstringValidationData[value]; - } - if (validationCommand) { - if (validationCommand.stem) { - hints += stackSize >> 1; - } - if ('min' in validationCommand) { - if (!undefStack && stackSize < validationCommand.min) { - warn('Not enough parameters for ' + validationCommand.id + - '; actual: ' + stackSize + - ', expected: ' + validationCommand.min); - valid = false; - break; - } - } - if (firstStackClearing && validationCommand.stackClearing) { - firstStackClearing = false; - // the optional character width can be found before the first - // stack-clearing command arguments - stackSize -= validationCommand.min; - if (stackSize >= 2 && validationCommand.stem) { - // there are even amount of arguments for stem commands - stackSize %= 2; - } else if (stackSize > 1) { - warn('Found too many parameters for stack-clearing command'); - } - if (stackSize > 0 && stack[stackSize - 1] >= 0) { - widths[i] = stack[stackSize - 1]; - } - } - if ('stackDelta' in validationCommand) { - if ('stackFn' in validationCommand) { - validationCommand.stackFn(stack, stackSize); - } - stackSize += validationCommand.stackDelta; - } else if (validationCommand.stackClearing) { - stackSize = 0; - } else if (validationCommand.resetStack) { - stackSize = 0; - undefStack = false; - } else if (validationCommand.undefStack) { - stackSize = 0; - undefStack = true; - firstStackClearing = false; - } - } - } - if (!valid) { - // resetting invalid charstring to single 'endchar' - charStrings.set(i, new Uint8Array([14])); - } - } - return { charStrings: charStrings, seacs: seacs, widths: widths }; - }, - emptyPrivateDictionary: - function CFFParser_emptyPrivateDictionary(parentDict) { - var privateDict = this.createDict(CFFPrivateDict, [], - parentDict.strings); - parentDict.setByKey(18, [0, 0]); - parentDict.privateDict = privateDict; - }, - parsePrivateDict: function CFFParser_parsePrivateDict(parentDict) { - // no private dict, do nothing - if (!parentDict.hasName('Private')) { - this.emptyPrivateDictionary(parentDict); - return; - } - var privateOffset = parentDict.getByName('Private'); - // make sure the params are formatted correctly - if (!isArray(privateOffset) || privateOffset.length !== 2) { - parentDict.removeByName('Private'); - return; - } - var size = privateOffset[0]; - var offset = privateOffset[1]; - // remove empty dicts or ones that refer to invalid location - if (size === 0 || offset >= this.bytes.length) { - this.emptyPrivateDictionary(parentDict); - return; - } - - var privateDictEnd = offset + size; - var dictData = this.bytes.subarray(offset, privateDictEnd); - var dict = this.parseDict(dictData); - var privateDict = this.createDict(CFFPrivateDict, dict, - parentDict.strings); - parentDict.privateDict = privateDict; - - // Parse the Subrs index also since it's relative to the private dict. - if (!privateDict.getByName('Subrs')) { - return; - } - var subrsOffset = privateDict.getByName('Subrs'); - var relativeOffset = offset + subrsOffset; - // Validate the offset. - if (subrsOffset === 0 || relativeOffset >= this.bytes.length) { - this.emptyPrivateDictionary(parentDict); - return; - } - var subrsIndex = this.parseIndex(relativeOffset); - privateDict.subrsIndex = subrsIndex.obj; - }, - parseCharsets: function CFFParser_parseCharsets(pos, length, strings, cid) { - if (pos === 0) { - return new CFFCharset(true, CFFCharsetPredefinedTypes.ISO_ADOBE, - ISOAdobeCharset); - } else if (pos === 1) { - return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT, - ExpertCharset); - } else if (pos === 2) { - return new CFFCharset(true, CFFCharsetPredefinedTypes.EXPERT_SUBSET, - ExpertSubsetCharset); - } - - var bytes = this.bytes; - var start = pos; - var format = bytes[pos++]; - var charset = ['.notdef']; - var id, count, i; - - // subtract 1 for the .notdef glyph - length -= 1; - - switch (format) { - case 0: - for (i = 0; i < length; i++) { - id = (bytes[pos++] << 8) | bytes[pos++]; - charset.push(cid ? id : strings.get(id)); - } - break; - case 1: - while (charset.length <= length) { - id = (bytes[pos++] << 8) | bytes[pos++]; - count = bytes[pos++]; - for (i = 0; i <= count; i++) { - charset.push(cid ? id++ : strings.get(id++)); - } - } - break; - case 2: - while (charset.length <= length) { - id = (bytes[pos++] << 8) | bytes[pos++]; - count = (bytes[pos++] << 8) | bytes[pos++]; - for (i = 0; i <= count; i++) { - charset.push(cid ? id++ : strings.get(id++)); - } - } - break; - default: - error('Unknown charset format'); - } - // Raw won't be needed if we actually compile the charset. - var end = pos; - var raw = bytes.subarray(start, end); - - return new CFFCharset(false, format, charset, raw); - }, - parseEncoding: function CFFParser_parseEncoding(pos, - properties, - strings, - charset) { - var encoding = {}; - var bytes = this.bytes; - var predefined = false; - var hasSupplement = false; - var format, i, ii; - var raw = null; - - function readSupplement() { - var supplementsCount = bytes[pos++]; - for (i = 0; i < supplementsCount; i++) { - var code = bytes[pos++]; - var sid = (bytes[pos++] << 8) + (bytes[pos++] & 0xff); - encoding[code] = charset.indexOf(strings.get(sid)); - } - } - - if (pos === 0 || pos === 1) { - predefined = true; - format = pos; - var baseEncoding = pos ? Encodings.ExpertEncoding : - Encodings.StandardEncoding; - for (i = 0, ii = charset.length; i < ii; i++) { - var index = baseEncoding.indexOf(charset[i]); - if (index !== -1) { - encoding[index] = i; - } - } - } else { - var dataStart = pos; - format = bytes[pos++]; - switch (format & 0x7f) { - case 0: - var glyphsCount = bytes[pos++]; - for (i = 1; i <= glyphsCount; i++) { - encoding[bytes[pos++]] = i; - } - break; - - case 1: - var rangesCount = bytes[pos++]; - var gid = 1; - for (i = 0; i < rangesCount; i++) { - var start = bytes[pos++]; - var left = bytes[pos++]; - for (var j = start; j <= start + left; j++) { - encoding[j] = gid++; - } - } - break; - - default: - error('Unknow encoding format: ' + format + ' in CFF'); - break; - } - var dataEnd = pos; - if (format & 0x80) { - // The font sanitizer does not support CFF encoding with a - // supplement, since the encoding is not really used to map - // between gid to glyph, let's overwrite what is declared in - // the top dictionary to let the sanitizer think the font use - // StandardEncoding, that's a lie but that's ok. - bytes[dataStart] &= 0x7f; - readSupplement(); - hasSupplement = true; - } - raw = bytes.subarray(dataStart, dataEnd); - } - format = format & 0x7f; - return new CFFEncoding(predefined, format, encoding, raw); - }, - parseFDSelect: function CFFParser_parseFDSelect(pos, length) { - var start = pos; - var bytes = this.bytes; - var format = bytes[pos++]; - var fdSelect = []; - var i; - - switch (format) { - case 0: - for (i = 0; i < length; ++i) { - var id = bytes[pos++]; - fdSelect.push(id); - } - break; - case 3: - var rangesCount = (bytes[pos++] << 8) | bytes[pos++]; - for (i = 0; i < rangesCount; ++i) { - var first = (bytes[pos++] << 8) | bytes[pos++]; - var fdIndex = bytes[pos++]; - var next = (bytes[pos] << 8) | bytes[pos + 1]; - for (var j = first; j < next; ++j) { - fdSelect.push(fdIndex); - } - } - // Advance past the sentinel(next). - pos += 2; - break; - default: - error('Unknown fdselect format ' + format); - break; - } - var end = pos; - return new CFFFDSelect(fdSelect, bytes.subarray(start, end)); - } - }; - return CFFParser; -})(); - -// Compact Font Format -var CFF = (function CFFClosure() { - function CFF() { - this.header = null; - this.names = []; - this.topDict = null; - this.strings = new CFFStrings(); - this.globalSubrIndex = null; - - // The following could really be per font, but since we only have one font - // store them here. - this.encoding = null; - this.charset = null; - this.charStrings = null; - this.fdArray = []; - this.fdSelect = null; - - this.isCIDFont = false; - } - return CFF; -})(); - -var CFFHeader = (function CFFHeaderClosure() { - function CFFHeader(major, minor, hdrSize, offSize) { - this.major = major; - this.minor = minor; - this.hdrSize = hdrSize; - this.offSize = offSize; - } - return CFFHeader; -})(); - -var CFFStrings = (function CFFStringsClosure() { - function CFFStrings() { - this.strings = []; - } - CFFStrings.prototype = { - get: function CFFStrings_get(index) { - if (index >= 0 && index <= 390) { - return CFFStandardStrings[index]; - } - if (index - 391 <= this.strings.length) { - return this.strings[index - 391]; - } - return CFFStandardStrings[0]; - }, - add: function CFFStrings_add(value) { - this.strings.push(value); - }, - get count() { - return this.strings.length; - } - }; - return CFFStrings; -})(); - -var CFFIndex = (function CFFIndexClosure() { - function CFFIndex() { - this.objects = []; - this.length = 0; - } - CFFIndex.prototype = { - add: function CFFIndex_add(data) { - this.length += data.length; - this.objects.push(data); - }, - set: function CFFIndex_set(index, data) { - this.length += data.length - this.objects[index].length; - this.objects[index] = data; - }, - get: function CFFIndex_get(index) { - return this.objects[index]; - }, - get count() { - return this.objects.length; - } - }; - return CFFIndex; -})(); - -var CFFDict = (function CFFDictClosure() { - function CFFDict(tables, strings) { - this.keyToNameMap = tables.keyToNameMap; - this.nameToKeyMap = tables.nameToKeyMap; - this.defaults = tables.defaults; - this.types = tables.types; - this.opcodes = tables.opcodes; - this.order = tables.order; - this.strings = strings; - this.values = {}; - } - CFFDict.prototype = { - // value should always be an array - setByKey: function CFFDict_setByKey(key, value) { - if (!(key in this.keyToNameMap)) { - return false; - } - // ignore empty values - if (value.length === 0) { - return true; - } - var type = this.types[key]; - // remove the array wrapping these types of values - if (type === 'num' || type === 'sid' || type === 'offset') { - value = value[0]; - } - this.values[key] = value; - return true; - }, - setByName: function CFFDict_setByName(name, value) { - if (!(name in this.nameToKeyMap)) { - error('Invalid dictionary name "' + name + '"'); - } - this.values[this.nameToKeyMap[name]] = value; - }, - hasName: function CFFDict_hasName(name) { - return this.nameToKeyMap[name] in this.values; - }, - getByName: function CFFDict_getByName(name) { - if (!(name in this.nameToKeyMap)) { - error('Invalid dictionary name "' + name + '"'); - } - var key = this.nameToKeyMap[name]; - if (!(key in this.values)) { - return this.defaults[key]; - } - return this.values[key]; - }, - removeByName: function CFFDict_removeByName(name) { - delete this.values[this.nameToKeyMap[name]]; - } - }; - CFFDict.createTables = function CFFDict_createTables(layout) { - var tables = { - keyToNameMap: {}, - nameToKeyMap: {}, - defaults: {}, - types: {}, - opcodes: {}, - order: [] - }; - for (var i = 0, ii = layout.length; i < ii; ++i) { - var entry = layout[i]; - var key = isArray(entry[0]) ? (entry[0][0] << 8) + entry[0][1] : entry[0]; - tables.keyToNameMap[key] = entry[1]; - tables.nameToKeyMap[entry[1]] = key; - tables.types[key] = entry[2]; - tables.defaults[key] = entry[3]; - tables.opcodes[key] = isArray(entry[0]) ? entry[0] : [entry[0]]; - tables.order.push(key); - } - return tables; - }; - return CFFDict; -})(); - -var CFFTopDict = (function CFFTopDictClosure() { - var layout = [ - [[12, 30], 'ROS', ['sid', 'sid', 'num'], null], - [[12, 20], 'SyntheticBase', 'num', null], - [0, 'version', 'sid', null], - [1, 'Notice', 'sid', null], - [[12, 0], 'Copyright', 'sid', null], - [2, 'FullName', 'sid', null], - [3, 'FamilyName', 'sid', null], - [4, 'Weight', 'sid', null], - [[12, 1], 'isFixedPitch', 'num', 0], - [[12, 2], 'ItalicAngle', 'num', 0], - [[12, 3], 'UnderlinePosition', 'num', -100], - [[12, 4], 'UnderlineThickness', 'num', 50], - [[12, 5], 'PaintType', 'num', 0], - [[12, 6], 'CharstringType', 'num', 2], - [[12, 7], 'FontMatrix', ['num', 'num', 'num', 'num', 'num', 'num'], - [0.001, 0, 0, 0.001, 0, 0]], - [13, 'UniqueID', 'num', null], - [5, 'FontBBox', ['num', 'num', 'num', 'num'], [0, 0, 0, 0]], - [[12, 8], 'StrokeWidth', 'num', 0], - [14, 'XUID', 'array', null], - [15, 'charset', 'offset', 0], - [16, 'Encoding', 'offset', 0], - [17, 'CharStrings', 'offset', 0], - [18, 'Private', ['offset', 'offset'], null], - [[12, 21], 'PostScript', 'sid', null], - [[12, 22], 'BaseFontName', 'sid', null], - [[12, 23], 'BaseFontBlend', 'delta', null], - [[12, 31], 'CIDFontVersion', 'num', 0], - [[12, 32], 'CIDFontRevision', 'num', 0], - [[12, 33], 'CIDFontType', 'num', 0], - [[12, 34], 'CIDCount', 'num', 8720], - [[12, 35], 'UIDBase', 'num', null], - // XXX: CID Fonts on DirectWrite 6.1 only seem to work if FDSelect comes - // before FDArray. - [[12, 37], 'FDSelect', 'offset', null], - [[12, 36], 'FDArray', 'offset', null], - [[12, 38], 'FontName', 'sid', null] - ]; - var tables = null; - function CFFTopDict(strings) { - if (tables === null) { - tables = CFFDict.createTables(layout); - } - CFFDict.call(this, tables, strings); - this.privateDict = null; - } - CFFTopDict.prototype = Object.create(CFFDict.prototype); - return CFFTopDict; -})(); - -var CFFPrivateDict = (function CFFPrivateDictClosure() { - var layout = [ - [6, 'BlueValues', 'delta', null], - [7, 'OtherBlues', 'delta', null], - [8, 'FamilyBlues', 'delta', null], - [9, 'FamilyOtherBlues', 'delta', null], - [[12, 9], 'BlueScale', 'num', 0.039625], - [[12, 10], 'BlueShift', 'num', 7], - [[12, 11], 'BlueFuzz', 'num', 1], - [10, 'StdHW', 'num', null], - [11, 'StdVW', 'num', null], - [[12, 12], 'StemSnapH', 'delta', null], - [[12, 13], 'StemSnapV', 'delta', null], - [[12, 14], 'ForceBold', 'num', 0], - [[12, 17], 'LanguageGroup', 'num', 0], - [[12, 18], 'ExpansionFactor', 'num', 0.06], - [[12, 19], 'initialRandomSeed', 'num', 0], - [20, 'defaultWidthX', 'num', 0], - [21, 'nominalWidthX', 'num', 0], - [19, 'Subrs', 'offset', null] - ]; - var tables = null; - function CFFPrivateDict(strings) { - if (tables === null) { - tables = CFFDict.createTables(layout); - } - CFFDict.call(this, tables, strings); - this.subrsIndex = null; - } - CFFPrivateDict.prototype = Object.create(CFFDict.prototype); - return CFFPrivateDict; -})(); - -var CFFCharsetPredefinedTypes = { - ISO_ADOBE: 0, - EXPERT: 1, - EXPERT_SUBSET: 2 -}; -var CFFCharset = (function CFFCharsetClosure() { - function CFFCharset(predefined, format, charset, raw) { - this.predefined = predefined; - this.format = format; - this.charset = charset; - this.raw = raw; - } - return CFFCharset; -})(); - -var CFFEncoding = (function CFFEncodingClosure() { - function CFFEncoding(predefined, format, encoding, raw) { - this.predefined = predefined; - this.format = format; - this.encoding = encoding; - this.raw = raw; - } - return CFFEncoding; -})(); - -var CFFFDSelect = (function CFFFDSelectClosure() { - function CFFFDSelect(fdSelect, raw) { - this.fdSelect = fdSelect; - this.raw = raw; - } - return CFFFDSelect; -})(); - -// Helper class to keep track of where an offset is within the data and helps -// filling in that offset once it's known. -var CFFOffsetTracker = (function CFFOffsetTrackerClosure() { - function CFFOffsetTracker() { - this.offsets = {}; - } - CFFOffsetTracker.prototype = { - isTracking: function CFFOffsetTracker_isTracking(key) { - return key in this.offsets; - }, - track: function CFFOffsetTracker_track(key, location) { - if (key in this.offsets) { - error('Already tracking location of ' + key); - } - this.offsets[key] = location; - }, - offset: function CFFOffsetTracker_offset(value) { - for (var key in this.offsets) { - this.offsets[key] += value; - } - }, - setEntryLocation: function CFFOffsetTracker_setEntryLocation(key, - values, - output) { - if (!(key in this.offsets)) { - error('Not tracking location of ' + key); - } - var data = output.data; - var dataOffset = this.offsets[key]; - var size = 5; - for (var i = 0, ii = values.length; i < ii; ++i) { - var offset0 = i * size + dataOffset; - var offset1 = offset0 + 1; - var offset2 = offset0 + 2; - var offset3 = offset0 + 3; - var offset4 = offset0 + 4; - // It's easy to screw up offsets so perform this sanity check. - if (data[offset0] !== 0x1d || data[offset1] !== 0 || - data[offset2] !== 0 || data[offset3] !== 0 || data[offset4] !== 0) { - error('writing to an offset that is not empty'); - } - var value = values[i]; - data[offset0] = 0x1d; - data[offset1] = (value >> 24) & 0xFF; - data[offset2] = (value >> 16) & 0xFF; - data[offset3] = (value >> 8) & 0xFF; - data[offset4] = value & 0xFF; - } - } - }; - return CFFOffsetTracker; -})(); - -// Takes a CFF and converts it to the binary representation. -var CFFCompiler = (function CFFCompilerClosure() { - function CFFCompiler(cff) { - this.cff = cff; - } - CFFCompiler.prototype = { - compile: function CFFCompiler_compile() { - var cff = this.cff; - var output = { - data: [], - length: 0, - add: function CFFCompiler_add(data) { - this.data = this.data.concat(data); - this.length = this.data.length; - } - }; - - // Compile the five entries that must be in order. - var header = this.compileHeader(cff.header); - output.add(header); - - var nameIndex = this.compileNameIndex(cff.names); - output.add(nameIndex); - - if (cff.isCIDFont) { - // The spec is unclear on how font matrices should relate to each other - // when there is one in the main top dict and the sub top dicts. - // Windows handles this differently than linux and osx so we have to - // normalize to work on all. - // Rules based off of some mailing list discussions: - // - If main font has a matrix and subfont doesn't, use the main matrix. - // - If no main font matrix and there is a subfont matrix, use the - // subfont matrix. - // - If both have matrices, concat together. - // - If neither have matrices, use default. - // To make this work on all platforms we move the top matrix into each - // sub top dict and concat if necessary. - if (cff.topDict.hasName('FontMatrix')) { - var base = cff.topDict.getByName('FontMatrix'); - cff.topDict.removeByName('FontMatrix'); - for (var i = 0, ii = cff.fdArray.length; i < ii; i++) { - var subDict = cff.fdArray[i]; - var matrix = base.slice(0); - if (subDict.hasName('FontMatrix')) { - matrix = Util.transform(matrix, subDict.getByName('FontMatrix')); - } - subDict.setByName('FontMatrix', matrix); - } - } - } - - var compiled = this.compileTopDicts([cff.topDict], - output.length, - cff.isCIDFont); - output.add(compiled.output); - var topDictTracker = compiled.trackers[0]; - - var stringIndex = this.compileStringIndex(cff.strings.strings); - output.add(stringIndex); - - var globalSubrIndex = this.compileIndex(cff.globalSubrIndex); - output.add(globalSubrIndex); - - // Now start on the other entries that have no specfic order. - if (cff.encoding && cff.topDict.hasName('Encoding')) { - if (cff.encoding.predefined) { - topDictTracker.setEntryLocation('Encoding', [cff.encoding.format], - output); - } else { - var encoding = this.compileEncoding(cff.encoding); - topDictTracker.setEntryLocation('Encoding', [output.length], output); - output.add(encoding); - } - } - - if (cff.charset && cff.topDict.hasName('charset')) { - if (cff.charset.predefined) { - topDictTracker.setEntryLocation('charset', [cff.charset.format], - output); - } else { - var charset = this.compileCharset(cff.charset); - topDictTracker.setEntryLocation('charset', [output.length], output); - output.add(charset); - } - } - - var charStrings = this.compileCharStrings(cff.charStrings); - topDictTracker.setEntryLocation('CharStrings', [output.length], output); - output.add(charStrings); - - if (cff.isCIDFont) { - // For some reason FDSelect must be in front of FDArray on windows. OSX - // and linux don't seem to care. - topDictTracker.setEntryLocation('FDSelect', [output.length], output); - var fdSelect = this.compileFDSelect(cff.fdSelect.raw); - output.add(fdSelect); - // It is unclear if the sub font dictionary can have CID related - // dictionary keys, but the sanitizer doesn't like them so remove them. - compiled = this.compileTopDicts(cff.fdArray, output.length, true); - topDictTracker.setEntryLocation('FDArray', [output.length], output); - output.add(compiled.output); - var fontDictTrackers = compiled.trackers; - - this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output); - } - - this.compilePrivateDicts([cff.topDict], [topDictTracker], output); - - // If the font data ends with INDEX whose object data is zero-length, - // the sanitizer will bail out. Add a dummy byte to avoid that. - output.add([0]); - - return output.data; - }, - encodeNumber: function CFFCompiler_encodeNumber(value) { - if (parseFloat(value) === parseInt(value, 10) && !isNaN(value)) { // isInt - return this.encodeInteger(value); - } else { - return this.encodeFloat(value); - } - }, - encodeFloat: function CFFCompiler_encodeFloat(num) { - var value = num.toString(); - - // rounding inaccurate doubles - var m = /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(value); - if (m) { - var epsilon = parseFloat('1e' + ((m[2] ? +m[2] : 0) + m[1].length)); - value = (Math.round(num * epsilon) / epsilon).toString(); - } - - var nibbles = ''; - var i, ii; - for (i = 0, ii = value.length; i < ii; ++i) { - var a = value[i]; - if (a === 'e') { - nibbles += value[++i] === '-' ? 'c' : 'b'; - } else if (a === '.') { - nibbles += 'a'; - } else if (a === '-') { - nibbles += 'e'; - } else { - nibbles += a; - } - } - nibbles += (nibbles.length & 1) ? 'f' : 'ff'; - var out = [30]; - for (i = 0, ii = nibbles.length; i < ii; i += 2) { - out.push(parseInt(nibbles.substr(i, 2), 16)); - } - return out; - }, - encodeInteger: function CFFCompiler_encodeInteger(value) { - var code; - if (value >= -107 && value <= 107) { - code = [value + 139]; - } else if (value >= 108 && value <= 1131) { - value = [value - 108]; - code = [(value >> 8) + 247, value & 0xFF]; - } else if (value >= -1131 && value <= -108) { - value = -value - 108; - code = [(value >> 8) + 251, value & 0xFF]; - } else if (value >= -32768 && value <= 32767) { - code = [0x1c, (value >> 8) & 0xFF, value & 0xFF]; - } else { - code = [0x1d, - (value >> 24) & 0xFF, - (value >> 16) & 0xFF, - (value >> 8) & 0xFF, - value & 0xFF]; - } - return code; - }, - compileHeader: function CFFCompiler_compileHeader(header) { - return [ - header.major, - header.minor, - header.hdrSize, - header.offSize - ]; - }, - compileNameIndex: function CFFCompiler_compileNameIndex(names) { - var nameIndex = new CFFIndex(); - for (var i = 0, ii = names.length; i < ii; ++i) { - nameIndex.add(stringToBytes(names[i])); - } - return this.compileIndex(nameIndex); - }, - compileTopDicts: function CFFCompiler_compileTopDicts(dicts, - length, - removeCidKeys) { - var fontDictTrackers = []; - var fdArrayIndex = new CFFIndex(); - for (var i = 0, ii = dicts.length; i < ii; ++i) { - var fontDict = dicts[i]; - if (removeCidKeys) { - fontDict.removeByName('CIDFontVersion'); - fontDict.removeByName('CIDFontRevision'); - fontDict.removeByName('CIDFontType'); - fontDict.removeByName('CIDCount'); - fontDict.removeByName('UIDBase'); - } - var fontDictTracker = new CFFOffsetTracker(); - var fontDictData = this.compileDict(fontDict, fontDictTracker); - fontDictTrackers.push(fontDictTracker); - fdArrayIndex.add(fontDictData); - fontDictTracker.offset(length); - } - fdArrayIndex = this.compileIndex(fdArrayIndex, fontDictTrackers); - return { - trackers: fontDictTrackers, - output: fdArrayIndex - }; - }, - compilePrivateDicts: function CFFCompiler_compilePrivateDicts(dicts, - trackers, - output) { - for (var i = 0, ii = dicts.length; i < ii; ++i) { - var fontDict = dicts[i]; - assert(fontDict.privateDict && fontDict.hasName('Private'), - 'There must be an private dictionary.'); - var privateDict = fontDict.privateDict; - var privateDictTracker = new CFFOffsetTracker(); - var privateDictData = this.compileDict(privateDict, privateDictTracker); - - var outputLength = output.length; - privateDictTracker.offset(outputLength); - if (!privateDictData.length) { - // The private dictionary was empty, set the output length to zero to - // ensure the offset length isn't out of bounds in the eyes of the - // sanitizer. - outputLength = 0; - } - - trackers[i].setEntryLocation('Private', - [privateDictData.length, outputLength], - output); - output.add(privateDictData); - - if (privateDict.subrsIndex && privateDict.hasName('Subrs')) { - var subrs = this.compileIndex(privateDict.subrsIndex); - privateDictTracker.setEntryLocation('Subrs', [privateDictData.length], - output); - output.add(subrs); - } - } - }, - compileDict: function CFFCompiler_compileDict(dict, offsetTracker) { - var out = []; - // The dictionary keys must be in a certain order. - var order = dict.order; - for (var i = 0; i < order.length; ++i) { - var key = order[i]; - if (!(key in dict.values)) { - continue; - } - var values = dict.values[key]; - var types = dict.types[key]; - if (!isArray(types)) { - types = [types]; - } - if (!isArray(values)) { - values = [values]; - } - - // Remove any empty dict values. - if (values.length === 0) { - continue; - } - - for (var j = 0, jj = types.length; j < jj; ++j) { - var type = types[j]; - var value = values[j]; - switch (type) { - case 'num': - case 'sid': - out = out.concat(this.encodeNumber(value)); - break; - case 'offset': - // For offsets we just insert a 32bit integer so we don't have to - // deal with figuring out the length of the offset when it gets - // replaced later on by the compiler. - var name = dict.keyToNameMap[key]; - // Some offsets have the offset and the length, so just record the - // position of the first one. - if (!offsetTracker.isTracking(name)) { - offsetTracker.track(name, out.length); - } - out = out.concat([0x1d, 0, 0, 0, 0]); - break; - case 'array': - case 'delta': - out = out.concat(this.encodeNumber(value)); - for (var k = 1, kk = values.length; k < kk; ++k) { - out = out.concat(this.encodeNumber(values[k])); - } - break; - default: - error('Unknown data type of ' + type); - break; - } - } - out = out.concat(dict.opcodes[key]); - } - return out; - }, - compileStringIndex: function CFFCompiler_compileStringIndex(strings) { - var stringIndex = new CFFIndex(); - for (var i = 0, ii = strings.length; i < ii; ++i) { - stringIndex.add(stringToBytes(strings[i])); - } - return this.compileIndex(stringIndex); - }, - compileGlobalSubrIndex: function CFFCompiler_compileGlobalSubrIndex() { - var globalSubrIndex = this.cff.globalSubrIndex; - this.out.writeByteArray(this.compileIndex(globalSubrIndex)); - }, - compileCharStrings: function CFFCompiler_compileCharStrings(charStrings) { - return this.compileIndex(charStrings); - }, - compileCharset: function CFFCompiler_compileCharset(charset) { - return this.compileTypedArray(charset.raw); - }, - compileEncoding: function CFFCompiler_compileEncoding(encoding) { - return this.compileTypedArray(encoding.raw); - }, - compileFDSelect: function CFFCompiler_compileFDSelect(fdSelect) { - return this.compileTypedArray(fdSelect); - }, - compileTypedArray: function CFFCompiler_compileTypedArray(data) { - var out = []; - for (var i = 0, ii = data.length; i < ii; ++i) { - out[i] = data[i]; - } - return out; - }, - compileIndex: function CFFCompiler_compileIndex(index, trackers) { - trackers = trackers || []; - var objects = index.objects; - // First 2 bytes contains the number of objects contained into this index - var count = objects.length; - - // If there is no object, just create an index. This technically - // should just be [0, 0] but OTS has an issue with that. - if (count === 0) { - return [0, 0, 0]; - } - - var data = [(count >> 8) & 0xFF, count & 0xff]; - - var lastOffset = 1, i; - for (i = 0; i < count; ++i) { - lastOffset += objects[i].length; - } - - var offsetSize; - if (lastOffset < 0x100) { - offsetSize = 1; - } else if (lastOffset < 0x10000) { - offsetSize = 2; - } else if (lastOffset < 0x1000000) { - offsetSize = 3; - } else { - offsetSize = 4; - } - - // Next byte contains the offset size use to reference object in the file - data.push(offsetSize); - - // Add another offset after this one because we need a new offset - var relativeOffset = 1; - for (i = 0; i < count + 1; i++) { - if (offsetSize === 1) { - data.push(relativeOffset & 0xFF); - } else if (offsetSize === 2) { - data.push((relativeOffset >> 8) & 0xFF, - relativeOffset & 0xFF); - } else if (offsetSize === 3) { - data.push((relativeOffset >> 16) & 0xFF, - (relativeOffset >> 8) & 0xFF, - relativeOffset & 0xFF); - } else { - data.push((relativeOffset >>> 24) & 0xFF, - (relativeOffset >> 16) & 0xFF, - (relativeOffset >> 8) & 0xFF, - relativeOffset & 0xFF); - } - - if (objects[i]) { - relativeOffset += objects[i].length; - } - } - - for (i = 0; i < count; i++) { - // Notify the tracker where the object will be offset in the data. - if (trackers[i]) { - trackers[i].offset(data.length); - } - for (var j = 0, jj = objects[i].length; j < jj; j++) { - data.push(objects[i][j]); - } - } - return data; - } - }; - return CFFCompiler; -})(); - -// Workaround for seac on Windows. -(function checkSeacSupport() { - if (/Windows/.test(navigator.userAgent)) { - SEAC_ANALYSIS_ENABLED = true; - } -})(); - -// Workaround for Private Use Area characters in Chrome on Windows -// http://code.google.com/p/chromium/issues/detail?id=122465 -// https://github.com/mozilla/pdf.js/issues/1689 -(function checkChromeWindows() { - if (/Windows.*Chrome/.test(navigator.userAgent)) { - SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = true; - } -})(); - - -var FontRendererFactory = (function FontRendererFactoryClosure() { - function getLong(data, offset) { - return (data[offset] << 24) | (data[offset + 1] << 16) | - (data[offset + 2] << 8) | data[offset + 3]; - } - - function getUshort(data, offset) { - return (data[offset] << 8) | data[offset + 1]; - } - - function parseCmap(data, start, end) { - var offset = (getUshort(data, start + 2) === 1 ? - getLong(data, start + 8) : getLong(data, start + 16)); - var format = getUshort(data, start + offset); - var length, ranges, p, i; - if (format === 4) { - length = getUshort(data, start + offset + 2); - var segCount = getUshort(data, start + offset + 6) >> 1; - p = start + offset + 14; - ranges = []; - for (i = 0; i < segCount; i++, p += 2) { - ranges[i] = {end: getUshort(data, p)}; - } - p += 2; - for (i = 0; i < segCount; i++, p += 2) { - ranges[i].start = getUshort(data, p); - } - for (i = 0; i < segCount; i++, p += 2) { - ranges[i].idDelta = getUshort(data, p); - } - for (i = 0; i < segCount; i++, p += 2) { - var idOffset = getUshort(data, p); - if (idOffset === 0) { - continue; - } - ranges[i].ids = []; - for (var j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) { - ranges[i].ids[j] = getUshort(data, p + idOffset); - idOffset += 2; - } - } - return ranges; - } else if (format === 12) { - length = getLong(data, start + offset + 4); - var groups = getLong(data, start + offset + 12); - p = start + offset + 16; - ranges = []; - for (i = 0; i < groups; i++) { - ranges.push({ - start: getLong(data, p), - end: getLong(data, p + 4), - idDelta: getLong(data, p + 8) - getLong(data, p) - }); - p += 12; - } - return ranges; - } - error('not supported cmap: ' + format); - } - - function parseCff(data, start, end) { - var properties = {}; - var parser = new CFFParser(new Stream(data, start, end - start), - properties); - var cff = parser.parse(); - return { - glyphs: cff.charStrings.objects, - subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex && - cff.topDict.privateDict.subrsIndex.objects), - gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects - }; - } - - function parseGlyfTable(glyf, loca, isGlyphLocationsLong) { - var itemSize, itemDecode; - if (isGlyphLocationsLong) { - itemSize = 4; - itemDecode = function fontItemDecodeLong(data, offset) { - return (data[offset] << 24) | (data[offset + 1] << 16) | - (data[offset + 2] << 8) | data[offset + 3]; - }; - } else { - itemSize = 2; - itemDecode = function fontItemDecode(data, offset) { - return (data[offset] << 9) | (data[offset + 1] << 1); - }; - } - var glyphs = []; - var startOffset = itemDecode(loca, 0); - for (var j = itemSize; j < loca.length; j += itemSize) { - var endOffset = itemDecode(loca, j); - glyphs.push(glyf.subarray(startOffset, endOffset)); - startOffset = endOffset; - } - return glyphs; - } - - function lookupCmap(ranges, unicode) { - var code = unicode.charCodeAt(0); - var l = 0, r = ranges.length - 1; - while (l < r) { - var c = (l + r + 1) >> 1; - if (code < ranges[c].start) { - r = c - 1; - } else { - l = c; - } - } - if (ranges[l].start <= code && code <= ranges[l].end) { - return (ranges[l].idDelta + (ranges[l].ids ? - ranges[l].ids[code - ranges[l].start] : code)) & 0xFFFF; - } - return 0; - } - - function compileGlyf(code, js, font) { - function moveTo(x, y) { - js.push('c.moveTo(' + x + ',' + y + ');'); - } - function lineTo(x, y) { - js.push('c.lineTo(' + x + ',' + y + ');'); - } - function quadraticCurveTo(xa, ya, x, y) { - js.push('c.quadraticCurveTo(' + xa + ',' + ya + ',' + - x + ',' + y + ');'); - } - - var i = 0; - var numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16; - var flags; - var x = 0, y = 0; - i += 10; - if (numberOfContours < 0) { - // composite glyph - do { - flags = (code[i] << 8) | code[i + 1]; - var glyphIndex = (code[i + 2] << 8) | code[i + 3]; - i += 4; - var arg1, arg2; - if ((flags & 0x01)) { - arg1 = ((code[i] << 24) | (code[i + 1] << 16)) >> 16; - arg2 = ((code[i + 2] << 24) | (code[i + 3] << 16)) >> 16; - i += 4; - } else { - arg1 = code[i++]; arg2 = code[i++]; - } - if ((flags & 0x02)) { - x = arg1; - y = arg2; - } else { - x = 0; y = 0; // TODO "they are points" ? - } - var scaleX = 1, scaleY = 1, scale01 = 0, scale10 = 0; - if ((flags & 0x08)) { - scaleX = - scaleY = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824; - i += 2; - } else if ((flags & 0x40)) { - scaleX = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824; - scaleY = ((code[i + 2] << 24) | (code[i + 3] << 16)) / 1073741824; - i += 4; - } else if ((flags & 0x80)) { - scaleX = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824; - scale01 = ((code[i + 2] << 24) | (code[i + 3] << 16)) / 1073741824; - scale10 = ((code[i + 4] << 24) | (code[i + 5] << 16)) / 1073741824; - scaleY = ((code[i + 6] << 24) | (code[i + 7] << 16)) / 1073741824; - i += 8; - } - var subglyph = font.glyphs[glyphIndex]; - if (subglyph) { - js.push('c.save();'); - js.push('c.transform(' + scaleX + ',' + scale01 + ',' + - scale10 + ',' + scaleY + ',' + x + ',' + y + ');'); - compileGlyf(subglyph, js, font); - js.push('c.restore();'); - } - } while ((flags & 0x20)); - } else { - // simple glyph - var endPtsOfContours = []; - var j, jj; - for (j = 0; j < numberOfContours; j++) { - endPtsOfContours.push((code[i] << 8) | code[i + 1]); - i += 2; - } - var instructionLength = (code[i] << 8) | code[i + 1]; - i += 2 + instructionLength; // skipping the instructions - var numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1; - var points = []; - while (points.length < numberOfPoints) { - flags = code[i++]; - var repeat = 1; - if ((flags & 0x08)) { - repeat += code[i++]; - } - while (repeat-- > 0) { - points.push({flags: flags}); - } - } - for (j = 0; j < numberOfPoints; j++) { - switch (points[j].flags & 0x12) { - case 0x00: - x += ((code[i] << 24) | (code[i + 1] << 16)) >> 16; - i += 2; - break; - case 0x02: - x -= code[i++]; - break; - case 0x12: - x += code[i++]; - break; - } - points[j].x = x; - } - for (j = 0; j < numberOfPoints; j++) { - switch (points[j].flags & 0x24) { - case 0x00: - y += ((code[i] << 24) | (code[i + 1] << 16)) >> 16; - i += 2; - break; - case 0x04: - y -= code[i++]; - break; - case 0x24: - y += code[i++]; - break; - } - points[j].y = y; - } - - var startPoint = 0; - for (i = 0; i < numberOfContours; i++) { - var endPoint = endPtsOfContours[i]; - // contours might have implicit points, which is located in the middle - // between two neighboring off-curve points - var contour = points.slice(startPoint, endPoint + 1); - if ((contour[0].flags & 1)) { - contour.push(contour[0]); // using start point at the contour end - } else if ((contour[contour.length - 1].flags & 1)) { - // first is off-curve point, trying to use one from the end - contour.unshift(contour[contour.length - 1]); - } else { - // start and end are off-curve points, creating implicit one - var p = { - flags: 1, - x: (contour[0].x + contour[contour.length - 1].x) / 2, - y: (contour[0].y + contour[contour.length - 1].y) / 2 - }; - contour.unshift(p); - contour.push(p); - } - moveTo(contour[0].x, contour[0].y); - for (j = 1, jj = contour.length; j < jj; j++) { - if ((contour[j].flags & 1)) { - lineTo(contour[j].x, contour[j].y); - } else if ((contour[j + 1].flags & 1)){ - quadraticCurveTo(contour[j].x, contour[j].y, - contour[j + 1].x, contour[j + 1].y); - j++; - } else { - quadraticCurveTo(contour[j].x, contour[j].y, - (contour[j].x + contour[j + 1].x) / 2, - (contour[j].y + contour[j + 1].y) / 2); - } - } - startPoint = endPoint + 1; - } - } - } - - function compileCharString(code, js, font) { - var stack = []; - var x = 0, y = 0; - var stems = 0; - - function moveTo(x, y) { - js.push('c.moveTo(' + x + ',' + y + ');'); - } - function lineTo(x, y) { - js.push('c.lineTo(' + x + ',' + y + ');'); - } - function bezierCurveTo(x1, y1, x2, y2, x, y) { - js.push('c.bezierCurveTo(' + x1 + ',' + y1 + ',' + x2 + ',' + y2 + ',' + - x + ',' + y + ');'); - } - - function parse(code) { - var i = 0; - while (i < code.length) { - var stackClean = false; - var v = code[i++]; - var xa, xb, ya, yb, y1, y2, y3, n, subrCode; - switch (v) { - case 1: // hstem - stems += stack.length >> 1; - stackClean = true; - break; - case 3: // vstem - stems += stack.length >> 1; - stackClean = true; - break; - case 4: // vmoveto - y += stack.pop(); - moveTo(x, y); - stackClean = true; - break; - case 5: // rlineto - while (stack.length > 0) { - x += stack.shift(); - y += stack.shift(); - lineTo(x, y); - } - break; - case 6: // hlineto - while (stack.length > 0) { - x += stack.shift(); - lineTo(x, y); - if (stack.length === 0) { - break; - } - y += stack.shift(); - lineTo(x, y); - } - break; - case 7: // vlineto - while (stack.length > 0) { - y += stack.shift(); - lineTo(x, y); - if (stack.length === 0) { - break; - } - x += stack.shift(); - lineTo(x, y); - } - break; - case 8: // rrcurveto - while (stack.length > 0) { - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - } - break; - case 10: // callsubr - n = stack.pop() + font.subrsBias; - subrCode = font.subrs[n]; - if (subrCode) { - parse(subrCode); - } - break; - case 11: // return - return; - case 12: - v = code[i++]; - switch (v) { - case 34: // flex - xa = x + stack.shift(); - xb = xa + stack.shift(); y1 = y + stack.shift(); - x = xb + stack.shift(); - bezierCurveTo(xa, y, xb, y1, x, y1); - xa = x + stack.shift(); - xb = xa + stack.shift(); - x = xb + stack.shift(); - bezierCurveTo(xa, y1, xb, y, x, y); - break; - case 35: // flex - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - stack.pop(); // fd - break; - case 36: // hflex1 - xa = x + stack.shift(); y1 = y + stack.shift(); - xb = xa + stack.shift(); y2 = y1 + stack.shift(); - x = xb + stack.shift(); - bezierCurveTo(xa, y1, xb, y2, x, y2); - xa = x + stack.shift(); - xb = xa + stack.shift(); y3 = y2 + stack.shift(); - x = xb + stack.shift(); - bezierCurveTo(xa, y2, xb, y3, x, y); - break; - case 37: // flex1 - var x0 = x, y0 = y; - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb; y = yb; - if (Math.abs(x - x0) > Math.abs(y - y0)) { - x += stack.shift(); - } else { - y += stack.shift(); - } - bezierCurveTo(xa, ya, xb, yb, x, y); - break; - default: - error('unknown operator: 12 ' + v); - } - break; - case 14: // endchar - if (stack.length >= 4) { - var achar = stack.pop(); - var bchar = stack.pop(); - y = stack.pop(); - x = stack.pop(); - js.push('c.save();'); - js.push('c.translate('+ x + ',' + y + ');'); - var gid = lookupCmap(font.cmap, String.fromCharCode( - font.glyphNameMap[Encodings.StandardEncoding[achar]])); - compileCharString(font.glyphs[gid], js, font); - js.push('c.restore();'); - - gid = lookupCmap(font.cmap, String.fromCharCode( - font.glyphNameMap[Encodings.StandardEncoding[bchar]])); - compileCharString(font.glyphs[gid], js, font); - } - return; - case 18: // hstemhm - stems += stack.length >> 1; - stackClean = true; - break; - case 19: // hintmask - stems += stack.length >> 1; - i += (stems + 7) >> 3; - stackClean = true; - break; - case 20: // cntrmask - stems += stack.length >> 1; - i += (stems + 7) >> 3; - stackClean = true; - break; - case 21: // rmoveto - y += stack.pop(); - x += stack.pop(); - moveTo(x, y); - stackClean = true; - break; - case 22: // hmoveto - x += stack.pop(); - moveTo(x, y); - stackClean = true; - break; - case 23: // vstemhm - stems += stack.length >> 1; - stackClean = true; - break; - case 24: // rcurveline - while (stack.length > 2) { - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - } - x += stack.shift(); - y += stack.shift(); - lineTo(x, y); - break; - case 25: // rlinecurve - while (stack.length > 6) { - x += stack.shift(); - y += stack.shift(); - lineTo(x, y); - } - xa = x + stack.shift(); ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - break; - case 26: // vvcurveto - if (stack.length % 2) { - x += stack.shift(); - } - while (stack.length > 0) { - xa = x; ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb; y = yb + stack.shift(); - bezierCurveTo(xa, ya, xb, yb, x, y); - } - break; - case 27: // hhcurveto - if (stack.length % 2) { - y += stack.shift(); - } - while (stack.length > 0) { - xa = x + stack.shift(); ya = y; - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); y = yb; - bezierCurveTo(xa, ya, xb, yb, x, y); - } - break; - case 28: - stack.push(((code[i] << 24) | (code[i + 1] << 16)) >> 16); - i += 2; - break; - case 29: // callgsubr - n = stack.pop() + font.gsubrsBias; - subrCode = font.gsubrs[n]; - if (subrCode) { - parse(subrCode); - } - break; - case 30: // vhcurveto - while (stack.length > 0) { - xa = x; ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); - y = yb + (stack.length === 1 ? stack.shift() : 0); - bezierCurveTo(xa, ya, xb, yb, x, y); - if (stack.length === 0) { - break; - } - - xa = x + stack.shift(); ya = y; - xb = xa + stack.shift(); yb = ya + stack.shift(); - y = yb + stack.shift(); - x = xb + (stack.length === 1 ? stack.shift() : 0); - bezierCurveTo(xa, ya, xb, yb, x, y); - } - break; - case 31: // hvcurveto - while (stack.length > 0) { - xa = x + stack.shift(); ya = y; - xb = xa + stack.shift(); yb = ya + stack.shift(); - y = yb + stack.shift(); - x = xb + (stack.length === 1 ? stack.shift() : 0); - bezierCurveTo(xa, ya, xb, yb, x, y); - if (stack.length === 0) { - break; - } - - xa = x; ya = y + stack.shift(); - xb = xa + stack.shift(); yb = ya + stack.shift(); - x = xb + stack.shift(); - y = yb + (stack.length === 1 ? stack.shift() : 0); - bezierCurveTo(xa, ya, xb, yb, x, y); - } - break; - default: - if (v < 32) { - error('unknown operator: ' + v); - } - if (v < 247) { - stack.push(v - 139); - } else if (v < 251) { - stack.push((v - 247) * 256 + code[i++] + 108); - } else if (v < 255) { - stack.push(-(v - 251) * 256 - code[i++] - 108); - } else { - stack.push(((code[i] << 24) | (code[i + 1] << 16) | - (code[i + 2] << 8) | code[i + 3]) / 65536); - i += 4; - } - break; - } - if (stackClean) { - stack.length = 0; - } - } - } - parse(code); - } - - var noop = ''; - - function CompiledFont(fontMatrix) { - this.compiledGlyphs = {}; - this.fontMatrix = fontMatrix; - } - CompiledFont.prototype = { - getPathJs: function (unicode) { - var gid = lookupCmap(this.cmap, unicode); - var fn = this.compiledGlyphs[gid]; - if (!fn) { - this.compiledGlyphs[gid] = fn = this.compileGlyph(this.glyphs[gid]); - } - return fn; - }, - - compileGlyph: function (code) { - if (!code || code.length === 0 || code[0] === 14) { - return noop; - } - - var js = []; - js.push('c.save();'); - js.push('c.transform(' + this.fontMatrix.join(',') + ');'); - js.push('c.scale(size, -size);'); - - this.compileGlyphImpl(code, js); - - js.push('c.restore();'); - - return js.join('\n'); - }, - - compileGlyphImpl: function () { - error('Children classes should implement this.'); - }, - - hasBuiltPath: function (unicode) { - var gid = lookupCmap(this.cmap, unicode); - return gid in this.compiledGlyphs; - } - }; - - function TrueTypeCompiled(glyphs, cmap, fontMatrix) { - fontMatrix = fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0]; - CompiledFont.call(this, fontMatrix); - - this.glyphs = glyphs; - this.cmap = cmap; - - this.compiledGlyphs = []; - } - - Util.inherit(TrueTypeCompiled, CompiledFont, { - compileGlyphImpl: function (code, js) { - compileGlyf(code, js, this); - } - }); - - function Type2Compiled(cffInfo, cmap, fontMatrix, glyphNameMap) { - fontMatrix = fontMatrix || [0.001, 0, 0, 0.001, 0, 0]; - CompiledFont.call(this, fontMatrix); - this.glyphs = cffInfo.glyphs; - this.gsubrs = cffInfo.gsubrs || []; - this.subrs = cffInfo.subrs || []; - this.cmap = cmap; - this.glyphNameMap = glyphNameMap || GlyphsUnicode; - - this.compiledGlyphs = []; - this.gsubrsBias = (this.gsubrs.length < 1240 ? - 107 : (this.gsubrs.length < 33900 ? 1131 : 32768)); - this.subrsBias = (this.subrs.length < 1240 ? - 107 : (this.subrs.length < 33900 ? 1131 : 32768)); - } - - Util.inherit(Type2Compiled, CompiledFont, { - compileGlyphImpl: function (code, js) { - compileCharString(code, js, this); - } - }); - - - return { - create: function FontRendererFactory_create(font) { - var data = new Uint8Array(font.data); - var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm; - var numTables = getUshort(data, 4); - for (var i = 0, p = 12; i < numTables; i++, p += 16) { - var tag = bytesToString(data.subarray(p, p + 4)); - var offset = getLong(data, p + 8); - var length = getLong(data, p + 12); - switch (tag) { - case 'cmap': - cmap = parseCmap(data, offset, offset + length); - break; - case 'glyf': - glyf = data.subarray(offset, offset + length); - break; - case 'loca': - loca = data.subarray(offset, offset + length); - break; - case 'head': - unitsPerEm = getUshort(data, offset + 18); - indexToLocFormat = getUshort(data, offset + 50); - break; - case 'CFF ': - cff = parseCff(data, offset, offset + length); - break; - } - } - - if (glyf) { - var fontMatrix = (!unitsPerEm ? font.fontMatrix : - [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0]); - return new TrueTypeCompiled( - parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix); - } else { - return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap); - } - } - }; -})(); - - -var GlyphsUnicode = { - A: 0x0041, - AE: 0x00C6, - AEacute: 0x01FC, - AEmacron: 0x01E2, - AEsmall: 0xF7E6, - Aacute: 0x00C1, - Aacutesmall: 0xF7E1, - Abreve: 0x0102, - Abreveacute: 0x1EAE, - Abrevecyrillic: 0x04D0, - Abrevedotbelow: 0x1EB6, - Abrevegrave: 0x1EB0, - Abrevehookabove: 0x1EB2, - Abrevetilde: 0x1EB4, - Acaron: 0x01CD, - Acircle: 0x24B6, - Acircumflex: 0x00C2, - Acircumflexacute: 0x1EA4, - Acircumflexdotbelow: 0x1EAC, - Acircumflexgrave: 0x1EA6, - Acircumflexhookabove: 0x1EA8, - Acircumflexsmall: 0xF7E2, - Acircumflextilde: 0x1EAA, - Acute: 0xF6C9, - Acutesmall: 0xF7B4, - Acyrillic: 0x0410, - Adblgrave: 0x0200, - Adieresis: 0x00C4, - Adieresiscyrillic: 0x04D2, - Adieresismacron: 0x01DE, - Adieresissmall: 0xF7E4, - Adotbelow: 0x1EA0, - Adotmacron: 0x01E0, - Agrave: 0x00C0, - Agravesmall: 0xF7E0, - Ahookabove: 0x1EA2, - Aiecyrillic: 0x04D4, - Ainvertedbreve: 0x0202, - Alpha: 0x0391, - Alphatonos: 0x0386, - Amacron: 0x0100, - Amonospace: 0xFF21, - Aogonek: 0x0104, - Aring: 0x00C5, - Aringacute: 0x01FA, - Aringbelow: 0x1E00, - Aringsmall: 0xF7E5, - Asmall: 0xF761, - Atilde: 0x00C3, - Atildesmall: 0xF7E3, - Aybarmenian: 0x0531, - B: 0x0042, - Bcircle: 0x24B7, - Bdotaccent: 0x1E02, - Bdotbelow: 0x1E04, - Becyrillic: 0x0411, - Benarmenian: 0x0532, - Beta: 0x0392, - Bhook: 0x0181, - Blinebelow: 0x1E06, - Bmonospace: 0xFF22, - Brevesmall: 0xF6F4, - Bsmall: 0xF762, - Btopbar: 0x0182, - C: 0x0043, - Caarmenian: 0x053E, - Cacute: 0x0106, - Caron: 0xF6CA, - Caronsmall: 0xF6F5, - Ccaron: 0x010C, - Ccedilla: 0x00C7, - Ccedillaacute: 0x1E08, - Ccedillasmall: 0xF7E7, - Ccircle: 0x24B8, - Ccircumflex: 0x0108, - Cdot: 0x010A, - Cdotaccent: 0x010A, - Cedillasmall: 0xF7B8, - Chaarmenian: 0x0549, - Cheabkhasiancyrillic: 0x04BC, - Checyrillic: 0x0427, - Chedescenderabkhasiancyrillic: 0x04BE, - Chedescendercyrillic: 0x04B6, - Chedieresiscyrillic: 0x04F4, - Cheharmenian: 0x0543, - Chekhakassiancyrillic: 0x04CB, - Cheverticalstrokecyrillic: 0x04B8, - Chi: 0x03A7, - Chook: 0x0187, - Circumflexsmall: 0xF6F6, - Cmonospace: 0xFF23, - Coarmenian: 0x0551, - Csmall: 0xF763, - D: 0x0044, - DZ: 0x01F1, - DZcaron: 0x01C4, - Daarmenian: 0x0534, - Dafrican: 0x0189, - Dcaron: 0x010E, - Dcedilla: 0x1E10, - Dcircle: 0x24B9, - Dcircumflexbelow: 0x1E12, - Dcroat: 0x0110, - Ddotaccent: 0x1E0A, - Ddotbelow: 0x1E0C, - Decyrillic: 0x0414, - Deicoptic: 0x03EE, - Delta: 0x2206, - Deltagreek: 0x0394, - Dhook: 0x018A, - Dieresis: 0xF6CB, - DieresisAcute: 0xF6CC, - DieresisGrave: 0xF6CD, - Dieresissmall: 0xF7A8, - Digammagreek: 0x03DC, - Djecyrillic: 0x0402, - Dlinebelow: 0x1E0E, - Dmonospace: 0xFF24, - Dotaccentsmall: 0xF6F7, - Dslash: 0x0110, - Dsmall: 0xF764, - Dtopbar: 0x018B, - Dz: 0x01F2, - Dzcaron: 0x01C5, - Dzeabkhasiancyrillic: 0x04E0, - Dzecyrillic: 0x0405, - Dzhecyrillic: 0x040F, - E: 0x0045, - Eacute: 0x00C9, - Eacutesmall: 0xF7E9, - Ebreve: 0x0114, - Ecaron: 0x011A, - Ecedillabreve: 0x1E1C, - Echarmenian: 0x0535, - Ecircle: 0x24BA, - Ecircumflex: 0x00CA, - Ecircumflexacute: 0x1EBE, - Ecircumflexbelow: 0x1E18, - Ecircumflexdotbelow: 0x1EC6, - Ecircumflexgrave: 0x1EC0, - Ecircumflexhookabove: 0x1EC2, - Ecircumflexsmall: 0xF7EA, - Ecircumflextilde: 0x1EC4, - Ecyrillic: 0x0404, - Edblgrave: 0x0204, - Edieresis: 0x00CB, - Edieresissmall: 0xF7EB, - Edot: 0x0116, - Edotaccent: 0x0116, - Edotbelow: 0x1EB8, - Efcyrillic: 0x0424, - Egrave: 0x00C8, - Egravesmall: 0xF7E8, - Eharmenian: 0x0537, - Ehookabove: 0x1EBA, - Eightroman: 0x2167, - Einvertedbreve: 0x0206, - Eiotifiedcyrillic: 0x0464, - Elcyrillic: 0x041B, - Elevenroman: 0x216A, - Emacron: 0x0112, - Emacronacute: 0x1E16, - Emacrongrave: 0x1E14, - Emcyrillic: 0x041C, - Emonospace: 0xFF25, - Encyrillic: 0x041D, - Endescendercyrillic: 0x04A2, - Eng: 0x014A, - Enghecyrillic: 0x04A4, - Enhookcyrillic: 0x04C7, - Eogonek: 0x0118, - Eopen: 0x0190, - Epsilon: 0x0395, - Epsilontonos: 0x0388, - Ercyrillic: 0x0420, - Ereversed: 0x018E, - Ereversedcyrillic: 0x042D, - Escyrillic: 0x0421, - Esdescendercyrillic: 0x04AA, - Esh: 0x01A9, - Esmall: 0xF765, - Eta: 0x0397, - Etarmenian: 0x0538, - Etatonos: 0x0389, - Eth: 0x00D0, - Ethsmall: 0xF7F0, - Etilde: 0x1EBC, - Etildebelow: 0x1E1A, - Euro: 0x20AC, - Ezh: 0x01B7, - Ezhcaron: 0x01EE, - Ezhreversed: 0x01B8, - F: 0x0046, - Fcircle: 0x24BB, - Fdotaccent: 0x1E1E, - Feharmenian: 0x0556, - Feicoptic: 0x03E4, - Fhook: 0x0191, - Fitacyrillic: 0x0472, - Fiveroman: 0x2164, - Fmonospace: 0xFF26, - Fourroman: 0x2163, - Fsmall: 0xF766, - G: 0x0047, - GBsquare: 0x3387, - Gacute: 0x01F4, - Gamma: 0x0393, - Gammaafrican: 0x0194, - Gangiacoptic: 0x03EA, - Gbreve: 0x011E, - Gcaron: 0x01E6, - Gcedilla: 0x0122, - Gcircle: 0x24BC, - Gcircumflex: 0x011C, - Gcommaaccent: 0x0122, - Gdot: 0x0120, - Gdotaccent: 0x0120, - Gecyrillic: 0x0413, - Ghadarmenian: 0x0542, - Ghemiddlehookcyrillic: 0x0494, - Ghestrokecyrillic: 0x0492, - Gheupturncyrillic: 0x0490, - Ghook: 0x0193, - Gimarmenian: 0x0533, - Gjecyrillic: 0x0403, - Gmacron: 0x1E20, - Gmonospace: 0xFF27, - Grave: 0xF6CE, - Gravesmall: 0xF760, - Gsmall: 0xF767, - Gsmallhook: 0x029B, - Gstroke: 0x01E4, - H: 0x0048, - H18533: 0x25CF, - H18543: 0x25AA, - H18551: 0x25AB, - H22073: 0x25A1, - HPsquare: 0x33CB, - Haabkhasiancyrillic: 0x04A8, - Hadescendercyrillic: 0x04B2, - Hardsigncyrillic: 0x042A, - Hbar: 0x0126, - Hbrevebelow: 0x1E2A, - Hcedilla: 0x1E28, - Hcircle: 0x24BD, - Hcircumflex: 0x0124, - Hdieresis: 0x1E26, - Hdotaccent: 0x1E22, - Hdotbelow: 0x1E24, - Hmonospace: 0xFF28, - Hoarmenian: 0x0540, - Horicoptic: 0x03E8, - Hsmall: 0xF768, - Hungarumlaut: 0xF6CF, - Hungarumlautsmall: 0xF6F8, - Hzsquare: 0x3390, - I: 0x0049, - IAcyrillic: 0x042F, - IJ: 0x0132, - IUcyrillic: 0x042E, - Iacute: 0x00CD, - Iacutesmall: 0xF7ED, - Ibreve: 0x012C, - Icaron: 0x01CF, - Icircle: 0x24BE, - Icircumflex: 0x00CE, - Icircumflexsmall: 0xF7EE, - Icyrillic: 0x0406, - Idblgrave: 0x0208, - Idieresis: 0x00CF, - Idieresisacute: 0x1E2E, - Idieresiscyrillic: 0x04E4, - Idieresissmall: 0xF7EF, - Idot: 0x0130, - Idotaccent: 0x0130, - Idotbelow: 0x1ECA, - Iebrevecyrillic: 0x04D6, - Iecyrillic: 0x0415, - Ifraktur: 0x2111, - Igrave: 0x00CC, - Igravesmall: 0xF7EC, - Ihookabove: 0x1EC8, - Iicyrillic: 0x0418, - Iinvertedbreve: 0x020A, - Iishortcyrillic: 0x0419, - Imacron: 0x012A, - Imacroncyrillic: 0x04E2, - Imonospace: 0xFF29, - Iniarmenian: 0x053B, - Iocyrillic: 0x0401, - Iogonek: 0x012E, - Iota: 0x0399, - Iotaafrican: 0x0196, - Iotadieresis: 0x03AA, - Iotatonos: 0x038A, - Ismall: 0xF769, - Istroke: 0x0197, - Itilde: 0x0128, - Itildebelow: 0x1E2C, - Izhitsacyrillic: 0x0474, - Izhitsadblgravecyrillic: 0x0476, - J: 0x004A, - Jaarmenian: 0x0541, - Jcircle: 0x24BF, - Jcircumflex: 0x0134, - Jecyrillic: 0x0408, - Jheharmenian: 0x054B, - Jmonospace: 0xFF2A, - Jsmall: 0xF76A, - K: 0x004B, - KBsquare: 0x3385, - KKsquare: 0x33CD, - Kabashkircyrillic: 0x04A0, - Kacute: 0x1E30, - Kacyrillic: 0x041A, - Kadescendercyrillic: 0x049A, - Kahookcyrillic: 0x04C3, - Kappa: 0x039A, - Kastrokecyrillic: 0x049E, - Kaverticalstrokecyrillic: 0x049C, - Kcaron: 0x01E8, - Kcedilla: 0x0136, - Kcircle: 0x24C0, - Kcommaaccent: 0x0136, - Kdotbelow: 0x1E32, - Keharmenian: 0x0554, - Kenarmenian: 0x053F, - Khacyrillic: 0x0425, - Kheicoptic: 0x03E6, - Khook: 0x0198, - Kjecyrillic: 0x040C, - Klinebelow: 0x1E34, - Kmonospace: 0xFF2B, - Koppacyrillic: 0x0480, - Koppagreek: 0x03DE, - Ksicyrillic: 0x046E, - Ksmall: 0xF76B, - L: 0x004C, - LJ: 0x01C7, - LL: 0xF6BF, - Lacute: 0x0139, - Lambda: 0x039B, - Lcaron: 0x013D, - Lcedilla: 0x013B, - Lcircle: 0x24C1, - Lcircumflexbelow: 0x1E3C, - Lcommaaccent: 0x013B, - Ldot: 0x013F, - Ldotaccent: 0x013F, - Ldotbelow: 0x1E36, - Ldotbelowmacron: 0x1E38, - Liwnarmenian: 0x053C, - Lj: 0x01C8, - Ljecyrillic: 0x0409, - Llinebelow: 0x1E3A, - Lmonospace: 0xFF2C, - Lslash: 0x0141, - Lslashsmall: 0xF6F9, - Lsmall: 0xF76C, - M: 0x004D, - MBsquare: 0x3386, - Macron: 0xF6D0, - Macronsmall: 0xF7AF, - Macute: 0x1E3E, - Mcircle: 0x24C2, - Mdotaccent: 0x1E40, - Mdotbelow: 0x1E42, - Menarmenian: 0x0544, - Mmonospace: 0xFF2D, - Msmall: 0xF76D, - Mturned: 0x019C, - Mu: 0x039C, - N: 0x004E, - NJ: 0x01CA, - Nacute: 0x0143, - Ncaron: 0x0147, - Ncedilla: 0x0145, - Ncircle: 0x24C3, - Ncircumflexbelow: 0x1E4A, - Ncommaaccent: 0x0145, - Ndotaccent: 0x1E44, - Ndotbelow: 0x1E46, - Nhookleft: 0x019D, - Nineroman: 0x2168, - Nj: 0x01CB, - Njecyrillic: 0x040A, - Nlinebelow: 0x1E48, - Nmonospace: 0xFF2E, - Nowarmenian: 0x0546, - Nsmall: 0xF76E, - Ntilde: 0x00D1, - Ntildesmall: 0xF7F1, - Nu: 0x039D, - O: 0x004F, - OE: 0x0152, - OEsmall: 0xF6FA, - Oacute: 0x00D3, - Oacutesmall: 0xF7F3, - Obarredcyrillic: 0x04E8, - Obarreddieresiscyrillic: 0x04EA, - Obreve: 0x014E, - Ocaron: 0x01D1, - Ocenteredtilde: 0x019F, - Ocircle: 0x24C4, - Ocircumflex: 0x00D4, - Ocircumflexacute: 0x1ED0, - Ocircumflexdotbelow: 0x1ED8, - Ocircumflexgrave: 0x1ED2, - Ocircumflexhookabove: 0x1ED4, - Ocircumflexsmall: 0xF7F4, - Ocircumflextilde: 0x1ED6, - Ocyrillic: 0x041E, - Odblacute: 0x0150, - Odblgrave: 0x020C, - Odieresis: 0x00D6, - Odieresiscyrillic: 0x04E6, - Odieresissmall: 0xF7F6, - Odotbelow: 0x1ECC, - Ogoneksmall: 0xF6FB, - Ograve: 0x00D2, - Ogravesmall: 0xF7F2, - Oharmenian: 0x0555, - Ohm: 0x2126, - Ohookabove: 0x1ECE, - Ohorn: 0x01A0, - Ohornacute: 0x1EDA, - Ohorndotbelow: 0x1EE2, - Ohorngrave: 0x1EDC, - Ohornhookabove: 0x1EDE, - Ohorntilde: 0x1EE0, - Ohungarumlaut: 0x0150, - Oi: 0x01A2, - Oinvertedbreve: 0x020E, - Omacron: 0x014C, - Omacronacute: 0x1E52, - Omacrongrave: 0x1E50, - Omega: 0x2126, - Omegacyrillic: 0x0460, - Omegagreek: 0x03A9, - Omegaroundcyrillic: 0x047A, - Omegatitlocyrillic: 0x047C, - Omegatonos: 0x038F, - Omicron: 0x039F, - Omicrontonos: 0x038C, - Omonospace: 0xFF2F, - Oneroman: 0x2160, - Oogonek: 0x01EA, - Oogonekmacron: 0x01EC, - Oopen: 0x0186, - Oslash: 0x00D8, - Oslashacute: 0x01FE, - Oslashsmall: 0xF7F8, - Osmall: 0xF76F, - Ostrokeacute: 0x01FE, - Otcyrillic: 0x047E, - Otilde: 0x00D5, - Otildeacute: 0x1E4C, - Otildedieresis: 0x1E4E, - Otildesmall: 0xF7F5, - P: 0x0050, - Pacute: 0x1E54, - Pcircle: 0x24C5, - Pdotaccent: 0x1E56, - Pecyrillic: 0x041F, - Peharmenian: 0x054A, - Pemiddlehookcyrillic: 0x04A6, - Phi: 0x03A6, - Phook: 0x01A4, - Pi: 0x03A0, - Piwrarmenian: 0x0553, - Pmonospace: 0xFF30, - Psi: 0x03A8, - Psicyrillic: 0x0470, - Psmall: 0xF770, - Q: 0x0051, - Qcircle: 0x24C6, - Qmonospace: 0xFF31, - Qsmall: 0xF771, - R: 0x0052, - Raarmenian: 0x054C, - Racute: 0x0154, - Rcaron: 0x0158, - Rcedilla: 0x0156, - Rcircle: 0x24C7, - Rcommaaccent: 0x0156, - Rdblgrave: 0x0210, - Rdotaccent: 0x1E58, - Rdotbelow: 0x1E5A, - Rdotbelowmacron: 0x1E5C, - Reharmenian: 0x0550, - Rfraktur: 0x211C, - Rho: 0x03A1, - Ringsmall: 0xF6FC, - Rinvertedbreve: 0x0212, - Rlinebelow: 0x1E5E, - Rmonospace: 0xFF32, - Rsmall: 0xF772, - Rsmallinverted: 0x0281, - Rsmallinvertedsuperior: 0x02B6, - S: 0x0053, - SF010000: 0x250C, - SF020000: 0x2514, - SF030000: 0x2510, - SF040000: 0x2518, - SF050000: 0x253C, - SF060000: 0x252C, - SF070000: 0x2534, - SF080000: 0x251C, - SF090000: 0x2524, - SF100000: 0x2500, - SF110000: 0x2502, - SF190000: 0x2561, - SF200000: 0x2562, - SF210000: 0x2556, - SF220000: 0x2555, - SF230000: 0x2563, - SF240000: 0x2551, - SF250000: 0x2557, - SF260000: 0x255D, - SF270000: 0x255C, - SF280000: 0x255B, - SF360000: 0x255E, - SF370000: 0x255F, - SF380000: 0x255A, - SF390000: 0x2554, - SF400000: 0x2569, - SF410000: 0x2566, - SF420000: 0x2560, - SF430000: 0x2550, - SF440000: 0x256C, - SF450000: 0x2567, - SF460000: 0x2568, - SF470000: 0x2564, - SF480000: 0x2565, - SF490000: 0x2559, - SF500000: 0x2558, - SF510000: 0x2552, - SF520000: 0x2553, - SF530000: 0x256B, - SF540000: 0x256A, - Sacute: 0x015A, - Sacutedotaccent: 0x1E64, - Sampigreek: 0x03E0, - Scaron: 0x0160, - Scarondotaccent: 0x1E66, - Scaronsmall: 0xF6FD, - Scedilla: 0x015E, - Schwa: 0x018F, - Schwacyrillic: 0x04D8, - Schwadieresiscyrillic: 0x04DA, - Scircle: 0x24C8, - Scircumflex: 0x015C, - Scommaaccent: 0x0218, - Sdotaccent: 0x1E60, - Sdotbelow: 0x1E62, - Sdotbelowdotaccent: 0x1E68, - Seharmenian: 0x054D, - Sevenroman: 0x2166, - Shaarmenian: 0x0547, - Shacyrillic: 0x0428, - Shchacyrillic: 0x0429, - Sheicoptic: 0x03E2, - Shhacyrillic: 0x04BA, - Shimacoptic: 0x03EC, - Sigma: 0x03A3, - Sixroman: 0x2165, - Smonospace: 0xFF33, - Softsigncyrillic: 0x042C, - Ssmall: 0xF773, - Stigmagreek: 0x03DA, - T: 0x0054, - Tau: 0x03A4, - Tbar: 0x0166, - Tcaron: 0x0164, - Tcedilla: 0x0162, - Tcircle: 0x24C9, - Tcircumflexbelow: 0x1E70, - Tcommaaccent: 0x0162, - Tdotaccent: 0x1E6A, - Tdotbelow: 0x1E6C, - Tecyrillic: 0x0422, - Tedescendercyrillic: 0x04AC, - Tenroman: 0x2169, - Tetsecyrillic: 0x04B4, - Theta: 0x0398, - Thook: 0x01AC, - Thorn: 0x00DE, - Thornsmall: 0xF7FE, - Threeroman: 0x2162, - Tildesmall: 0xF6FE, - Tiwnarmenian: 0x054F, - Tlinebelow: 0x1E6E, - Tmonospace: 0xFF34, - Toarmenian: 0x0539, - Tonefive: 0x01BC, - Tonesix: 0x0184, - Tonetwo: 0x01A7, - Tretroflexhook: 0x01AE, - Tsecyrillic: 0x0426, - Tshecyrillic: 0x040B, - Tsmall: 0xF774, - Twelveroman: 0x216B, - Tworoman: 0x2161, - U: 0x0055, - Uacute: 0x00DA, - Uacutesmall: 0xF7FA, - Ubreve: 0x016C, - Ucaron: 0x01D3, - Ucircle: 0x24CA, - Ucircumflex: 0x00DB, - Ucircumflexbelow: 0x1E76, - Ucircumflexsmall: 0xF7FB, - Ucyrillic: 0x0423, - Udblacute: 0x0170, - Udblgrave: 0x0214, - Udieresis: 0x00DC, - Udieresisacute: 0x01D7, - Udieresisbelow: 0x1E72, - Udieresiscaron: 0x01D9, - Udieresiscyrillic: 0x04F0, - Udieresisgrave: 0x01DB, - Udieresismacron: 0x01D5, - Udieresissmall: 0xF7FC, - Udotbelow: 0x1EE4, - Ugrave: 0x00D9, - Ugravesmall: 0xF7F9, - Uhookabove: 0x1EE6, - Uhorn: 0x01AF, - Uhornacute: 0x1EE8, - Uhorndotbelow: 0x1EF0, - Uhorngrave: 0x1EEA, - Uhornhookabove: 0x1EEC, - Uhorntilde: 0x1EEE, - Uhungarumlaut: 0x0170, - Uhungarumlautcyrillic: 0x04F2, - Uinvertedbreve: 0x0216, - Ukcyrillic: 0x0478, - Umacron: 0x016A, - Umacroncyrillic: 0x04EE, - Umacrondieresis: 0x1E7A, - Umonospace: 0xFF35, - Uogonek: 0x0172, - Upsilon: 0x03A5, - Upsilon1: 0x03D2, - Upsilonacutehooksymbolgreek: 0x03D3, - Upsilonafrican: 0x01B1, - Upsilondieresis: 0x03AB, - Upsilondieresishooksymbolgreek: 0x03D4, - Upsilonhooksymbol: 0x03D2, - Upsilontonos: 0x038E, - Uring: 0x016E, - Ushortcyrillic: 0x040E, - Usmall: 0xF775, - Ustraightcyrillic: 0x04AE, - Ustraightstrokecyrillic: 0x04B0, - Utilde: 0x0168, - Utildeacute: 0x1E78, - Utildebelow: 0x1E74, - V: 0x0056, - Vcircle: 0x24CB, - Vdotbelow: 0x1E7E, - Vecyrillic: 0x0412, - Vewarmenian: 0x054E, - Vhook: 0x01B2, - Vmonospace: 0xFF36, - Voarmenian: 0x0548, - Vsmall: 0xF776, - Vtilde: 0x1E7C, - W: 0x0057, - Wacute: 0x1E82, - Wcircle: 0x24CC, - Wcircumflex: 0x0174, - Wdieresis: 0x1E84, - Wdotaccent: 0x1E86, - Wdotbelow: 0x1E88, - Wgrave: 0x1E80, - Wmonospace: 0xFF37, - Wsmall: 0xF777, - X: 0x0058, - Xcircle: 0x24CD, - Xdieresis: 0x1E8C, - Xdotaccent: 0x1E8A, - Xeharmenian: 0x053D, - Xi: 0x039E, - Xmonospace: 0xFF38, - Xsmall: 0xF778, - Y: 0x0059, - Yacute: 0x00DD, - Yacutesmall: 0xF7FD, - Yatcyrillic: 0x0462, - Ycircle: 0x24CE, - Ycircumflex: 0x0176, - Ydieresis: 0x0178, - Ydieresissmall: 0xF7FF, - Ydotaccent: 0x1E8E, - Ydotbelow: 0x1EF4, - Yericyrillic: 0x042B, - Yerudieresiscyrillic: 0x04F8, - Ygrave: 0x1EF2, - Yhook: 0x01B3, - Yhookabove: 0x1EF6, - Yiarmenian: 0x0545, - Yicyrillic: 0x0407, - Yiwnarmenian: 0x0552, - Ymonospace: 0xFF39, - Ysmall: 0xF779, - Ytilde: 0x1EF8, - Yusbigcyrillic: 0x046A, - Yusbigiotifiedcyrillic: 0x046C, - Yuslittlecyrillic: 0x0466, - Yuslittleiotifiedcyrillic: 0x0468, - Z: 0x005A, - Zaarmenian: 0x0536, - Zacute: 0x0179, - Zcaron: 0x017D, - Zcaronsmall: 0xF6FF, - Zcircle: 0x24CF, - Zcircumflex: 0x1E90, - Zdot: 0x017B, - Zdotaccent: 0x017B, - Zdotbelow: 0x1E92, - Zecyrillic: 0x0417, - Zedescendercyrillic: 0x0498, - Zedieresiscyrillic: 0x04DE, - Zeta: 0x0396, - Zhearmenian: 0x053A, - Zhebrevecyrillic: 0x04C1, - Zhecyrillic: 0x0416, - Zhedescendercyrillic: 0x0496, - Zhedieresiscyrillic: 0x04DC, - Zlinebelow: 0x1E94, - Zmonospace: 0xFF3A, - Zsmall: 0xF77A, - Zstroke: 0x01B5, - a: 0x0061, - aabengali: 0x0986, - aacute: 0x00E1, - aadeva: 0x0906, - aagujarati: 0x0A86, - aagurmukhi: 0x0A06, - aamatragurmukhi: 0x0A3E, - aarusquare: 0x3303, - aavowelsignbengali: 0x09BE, - aavowelsigndeva: 0x093E, - aavowelsigngujarati: 0x0ABE, - abbreviationmarkarmenian: 0x055F, - abbreviationsigndeva: 0x0970, - abengali: 0x0985, - abopomofo: 0x311A, - abreve: 0x0103, - abreveacute: 0x1EAF, - abrevecyrillic: 0x04D1, - abrevedotbelow: 0x1EB7, - abrevegrave: 0x1EB1, - abrevehookabove: 0x1EB3, - abrevetilde: 0x1EB5, - acaron: 0x01CE, - acircle: 0x24D0, - acircumflex: 0x00E2, - acircumflexacute: 0x1EA5, - acircumflexdotbelow: 0x1EAD, - acircumflexgrave: 0x1EA7, - acircumflexhookabove: 0x1EA9, - acircumflextilde: 0x1EAB, - acute: 0x00B4, - acutebelowcmb: 0x0317, - acutecmb: 0x0301, - acutecomb: 0x0301, - acutedeva: 0x0954, - acutelowmod: 0x02CF, - acutetonecmb: 0x0341, - acyrillic: 0x0430, - adblgrave: 0x0201, - addakgurmukhi: 0x0A71, - adeva: 0x0905, - adieresis: 0x00E4, - adieresiscyrillic: 0x04D3, - adieresismacron: 0x01DF, - adotbelow: 0x1EA1, - adotmacron: 0x01E1, - ae: 0x00E6, - aeacute: 0x01FD, - aekorean: 0x3150, - aemacron: 0x01E3, - afii00208: 0x2015, - afii08941: 0x20A4, - afii10017: 0x0410, - afii10018: 0x0411, - afii10019: 0x0412, - afii10020: 0x0413, - afii10021: 0x0414, - afii10022: 0x0415, - afii10023: 0x0401, - afii10024: 0x0416, - afii10025: 0x0417, - afii10026: 0x0418, - afii10027: 0x0419, - afii10028: 0x041A, - afii10029: 0x041B, - afii10030: 0x041C, - afii10031: 0x041D, - afii10032: 0x041E, - afii10033: 0x041F, - afii10034: 0x0420, - afii10035: 0x0421, - afii10036: 0x0422, - afii10037: 0x0423, - afii10038: 0x0424, - afii10039: 0x0425, - afii10040: 0x0426, - afii10041: 0x0427, - afii10042: 0x0428, - afii10043: 0x0429, - afii10044: 0x042A, - afii10045: 0x042B, - afii10046: 0x042C, - afii10047: 0x042D, - afii10048: 0x042E, - afii10049: 0x042F, - afii10050: 0x0490, - afii10051: 0x0402, - afii10052: 0x0403, - afii10053: 0x0404, - afii10054: 0x0405, - afii10055: 0x0406, - afii10056: 0x0407, - afii10057: 0x0408, - afii10058: 0x0409, - afii10059: 0x040A, - afii10060: 0x040B, - afii10061: 0x040C, - afii10062: 0x040E, - afii10063: 0xF6C4, - afii10064: 0xF6C5, - afii10065: 0x0430, - afii10066: 0x0431, - afii10067: 0x0432, - afii10068: 0x0433, - afii10069: 0x0434, - afii10070: 0x0435, - afii10071: 0x0451, - afii10072: 0x0436, - afii10073: 0x0437, - afii10074: 0x0438, - afii10075: 0x0439, - afii10076: 0x043A, - afii10077: 0x043B, - afii10078: 0x043C, - afii10079: 0x043D, - afii10080: 0x043E, - afii10081: 0x043F, - afii10082: 0x0440, - afii10083: 0x0441, - afii10084: 0x0442, - afii10085: 0x0443, - afii10086: 0x0444, - afii10087: 0x0445, - afii10088: 0x0446, - afii10089: 0x0447, - afii10090: 0x0448, - afii10091: 0x0449, - afii10092: 0x044A, - afii10093: 0x044B, - afii10094: 0x044C, - afii10095: 0x044D, - afii10096: 0x044E, - afii10097: 0x044F, - afii10098: 0x0491, - afii10099: 0x0452, - afii10100: 0x0453, - afii10101: 0x0454, - afii10102: 0x0455, - afii10103: 0x0456, - afii10104: 0x0457, - afii10105: 0x0458, - afii10106: 0x0459, - afii10107: 0x045A, - afii10108: 0x045B, - afii10109: 0x045C, - afii10110: 0x045E, - afii10145: 0x040F, - afii10146: 0x0462, - afii10147: 0x0472, - afii10148: 0x0474, - afii10192: 0xF6C6, - afii10193: 0x045F, - afii10194: 0x0463, - afii10195: 0x0473, - afii10196: 0x0475, - afii10831: 0xF6C7, - afii10832: 0xF6C8, - afii10846: 0x04D9, - afii299: 0x200E, - afii300: 0x200F, - afii301: 0x200D, - afii57381: 0x066A, - afii57388: 0x060C, - afii57392: 0x0660, - afii57393: 0x0661, - afii57394: 0x0662, - afii57395: 0x0663, - afii57396: 0x0664, - afii57397: 0x0665, - afii57398: 0x0666, - afii57399: 0x0667, - afii57400: 0x0668, - afii57401: 0x0669, - afii57403: 0x061B, - afii57407: 0x061F, - afii57409: 0x0621, - afii57410: 0x0622, - afii57411: 0x0623, - afii57412: 0x0624, - afii57413: 0x0625, - afii57414: 0x0626, - afii57415: 0x0627, - afii57416: 0x0628, - afii57417: 0x0629, - afii57418: 0x062A, - afii57419: 0x062B, - afii57420: 0x062C, - afii57421: 0x062D, - afii57422: 0x062E, - afii57423: 0x062F, - afii57424: 0x0630, - afii57425: 0x0631, - afii57426: 0x0632, - afii57427: 0x0633, - afii57428: 0x0634, - afii57429: 0x0635, - afii57430: 0x0636, - afii57431: 0x0637, - afii57432: 0x0638, - afii57433: 0x0639, - afii57434: 0x063A, - afii57440: 0x0640, - afii57441: 0x0641, - afii57442: 0x0642, - afii57443: 0x0643, - afii57444: 0x0644, - afii57445: 0x0645, - afii57446: 0x0646, - afii57448: 0x0648, - afii57449: 0x0649, - afii57450: 0x064A, - afii57451: 0x064B, - afii57452: 0x064C, - afii57453: 0x064D, - afii57454: 0x064E, - afii57455: 0x064F, - afii57456: 0x0650, - afii57457: 0x0651, - afii57458: 0x0652, - afii57470: 0x0647, - afii57505: 0x06A4, - afii57506: 0x067E, - afii57507: 0x0686, - afii57508: 0x0698, - afii57509: 0x06AF, - afii57511: 0x0679, - afii57512: 0x0688, - afii57513: 0x0691, - afii57514: 0x06BA, - afii57519: 0x06D2, - afii57534: 0x06D5, - afii57636: 0x20AA, - afii57645: 0x05BE, - afii57658: 0x05C3, - afii57664: 0x05D0, - afii57665: 0x05D1, - afii57666: 0x05D2, - afii57667: 0x05D3, - afii57668: 0x05D4, - afii57669: 0x05D5, - afii57670: 0x05D6, - afii57671: 0x05D7, - afii57672: 0x05D8, - afii57673: 0x05D9, - afii57674: 0x05DA, - afii57675: 0x05DB, - afii57676: 0x05DC, - afii57677: 0x05DD, - afii57678: 0x05DE, - afii57679: 0x05DF, - afii57680: 0x05E0, - afii57681: 0x05E1, - afii57682: 0x05E2, - afii57683: 0x05E3, - afii57684: 0x05E4, - afii57685: 0x05E5, - afii57686: 0x05E6, - afii57687: 0x05E7, - afii57688: 0x05E8, - afii57689: 0x05E9, - afii57690: 0x05EA, - afii57694: 0xFB2A, - afii57695: 0xFB2B, - afii57700: 0xFB4B, - afii57705: 0xFB1F, - afii57716: 0x05F0, - afii57717: 0x05F1, - afii57718: 0x05F2, - afii57723: 0xFB35, - afii57793: 0x05B4, - afii57794: 0x05B5, - afii57795: 0x05B6, - afii57796: 0x05BB, - afii57797: 0x05B8, - afii57798: 0x05B7, - afii57799: 0x05B0, - afii57800: 0x05B2, - afii57801: 0x05B1, - afii57802: 0x05B3, - afii57803: 0x05C2, - afii57804: 0x05C1, - afii57806: 0x05B9, - afii57807: 0x05BC, - afii57839: 0x05BD, - afii57841: 0x05BF, - afii57842: 0x05C0, - afii57929: 0x02BC, - afii61248: 0x2105, - afii61289: 0x2113, - afii61352: 0x2116, - afii61573: 0x202C, - afii61574: 0x202D, - afii61575: 0x202E, - afii61664: 0x200C, - afii63167: 0x066D, - afii64937: 0x02BD, - agrave: 0x00E0, - agujarati: 0x0A85, - agurmukhi: 0x0A05, - ahiragana: 0x3042, - ahookabove: 0x1EA3, - aibengali: 0x0990, - aibopomofo: 0x311E, - aideva: 0x0910, - aiecyrillic: 0x04D5, - aigujarati: 0x0A90, - aigurmukhi: 0x0A10, - aimatragurmukhi: 0x0A48, - ainarabic: 0x0639, - ainfinalarabic: 0xFECA, - aininitialarabic: 0xFECB, - ainmedialarabic: 0xFECC, - ainvertedbreve: 0x0203, - aivowelsignbengali: 0x09C8, - aivowelsigndeva: 0x0948, - aivowelsigngujarati: 0x0AC8, - akatakana: 0x30A2, - akatakanahalfwidth: 0xFF71, - akorean: 0x314F, - alef: 0x05D0, - alefarabic: 0x0627, - alefdageshhebrew: 0xFB30, - aleffinalarabic: 0xFE8E, - alefhamzaabovearabic: 0x0623, - alefhamzaabovefinalarabic: 0xFE84, - alefhamzabelowarabic: 0x0625, - alefhamzabelowfinalarabic: 0xFE88, - alefhebrew: 0x05D0, - aleflamedhebrew: 0xFB4F, - alefmaddaabovearabic: 0x0622, - alefmaddaabovefinalarabic: 0xFE82, - alefmaksuraarabic: 0x0649, - alefmaksurafinalarabic: 0xFEF0, - alefmaksurainitialarabic: 0xFEF3, - alefmaksuramedialarabic: 0xFEF4, - alefpatahhebrew: 0xFB2E, - alefqamatshebrew: 0xFB2F, - aleph: 0x2135, - allequal: 0x224C, - alpha: 0x03B1, - alphatonos: 0x03AC, - amacron: 0x0101, - amonospace: 0xFF41, - ampersand: 0x0026, - ampersandmonospace: 0xFF06, - ampersandsmall: 0xF726, - amsquare: 0x33C2, - anbopomofo: 0x3122, - angbopomofo: 0x3124, - angbracketleft: 0x3008, // This glyph is missing from Adobe's original list. - angbracketright: 0x3009, // This glyph is missing from Adobe's original list. - angkhankhuthai: 0x0E5A, - angle: 0x2220, - anglebracketleft: 0x3008, - anglebracketleftvertical: 0xFE3F, - anglebracketright: 0x3009, - anglebracketrightvertical: 0xFE40, - angleleft: 0x2329, - angleright: 0x232A, - angstrom: 0x212B, - anoteleia: 0x0387, - anudattadeva: 0x0952, - anusvarabengali: 0x0982, - anusvaradeva: 0x0902, - anusvaragujarati: 0x0A82, - aogonek: 0x0105, - apaatosquare: 0x3300, - aparen: 0x249C, - apostrophearmenian: 0x055A, - apostrophemod: 0x02BC, - apple: 0xF8FF, - approaches: 0x2250, - approxequal: 0x2248, - approxequalorimage: 0x2252, - approximatelyequal: 0x2245, - araeaekorean: 0x318E, - araeakorean: 0x318D, - arc: 0x2312, - arighthalfring: 0x1E9A, - aring: 0x00E5, - aringacute: 0x01FB, - aringbelow: 0x1E01, - arrowboth: 0x2194, - arrowdashdown: 0x21E3, - arrowdashleft: 0x21E0, - arrowdashright: 0x21E2, - arrowdashup: 0x21E1, - arrowdblboth: 0x21D4, - arrowdbldown: 0x21D3, - arrowdblleft: 0x21D0, - arrowdblright: 0x21D2, - arrowdblup: 0x21D1, - arrowdown: 0x2193, - arrowdownleft: 0x2199, - arrowdownright: 0x2198, - arrowdownwhite: 0x21E9, - arrowheaddownmod: 0x02C5, - arrowheadleftmod: 0x02C2, - arrowheadrightmod: 0x02C3, - arrowheadupmod: 0x02C4, - arrowhorizex: 0xF8E7, - arrowleft: 0x2190, - arrowleftdbl: 0x21D0, - arrowleftdblstroke: 0x21CD, - arrowleftoverright: 0x21C6, - arrowleftwhite: 0x21E6, - arrowright: 0x2192, - arrowrightdblstroke: 0x21CF, - arrowrightheavy: 0x279E, - arrowrightoverleft: 0x21C4, - arrowrightwhite: 0x21E8, - arrowtableft: 0x21E4, - arrowtabright: 0x21E5, - arrowup: 0x2191, - arrowupdn: 0x2195, - arrowupdnbse: 0x21A8, - arrowupdownbase: 0x21A8, - arrowupleft: 0x2196, - arrowupleftofdown: 0x21C5, - arrowupright: 0x2197, - arrowupwhite: 0x21E7, - arrowvertex: 0xF8E6, - asciicircum: 0x005E, - asciicircummonospace: 0xFF3E, - asciitilde: 0x007E, - asciitildemonospace: 0xFF5E, - ascript: 0x0251, - ascriptturned: 0x0252, - asmallhiragana: 0x3041, - asmallkatakana: 0x30A1, - asmallkatakanahalfwidth: 0xFF67, - asterisk: 0x002A, - asteriskaltonearabic: 0x066D, - asteriskarabic: 0x066D, - asteriskmath: 0x2217, - asteriskmonospace: 0xFF0A, - asterisksmall: 0xFE61, - asterism: 0x2042, - asuperior: 0xF6E9, - asymptoticallyequal: 0x2243, - at: 0x0040, - atilde: 0x00E3, - atmonospace: 0xFF20, - atsmall: 0xFE6B, - aturned: 0x0250, - aubengali: 0x0994, - aubopomofo: 0x3120, - audeva: 0x0914, - augujarati: 0x0A94, - augurmukhi: 0x0A14, - aulengthmarkbengali: 0x09D7, - aumatragurmukhi: 0x0A4C, - auvowelsignbengali: 0x09CC, - auvowelsigndeva: 0x094C, - auvowelsigngujarati: 0x0ACC, - avagrahadeva: 0x093D, - aybarmenian: 0x0561, - ayin: 0x05E2, - ayinaltonehebrew: 0xFB20, - ayinhebrew: 0x05E2, - b: 0x0062, - babengali: 0x09AC, - backslash: 0x005C, - backslashmonospace: 0xFF3C, - badeva: 0x092C, - bagujarati: 0x0AAC, - bagurmukhi: 0x0A2C, - bahiragana: 0x3070, - bahtthai: 0x0E3F, - bakatakana: 0x30D0, - bar: 0x007C, - barmonospace: 0xFF5C, - bbopomofo: 0x3105, - bcircle: 0x24D1, - bdotaccent: 0x1E03, - bdotbelow: 0x1E05, - beamedsixteenthnotes: 0x266C, - because: 0x2235, - becyrillic: 0x0431, - beharabic: 0x0628, - behfinalarabic: 0xFE90, - behinitialarabic: 0xFE91, - behiragana: 0x3079, - behmedialarabic: 0xFE92, - behmeeminitialarabic: 0xFC9F, - behmeemisolatedarabic: 0xFC08, - behnoonfinalarabic: 0xFC6D, - bekatakana: 0x30D9, - benarmenian: 0x0562, - bet: 0x05D1, - beta: 0x03B2, - betasymbolgreek: 0x03D0, - betdagesh: 0xFB31, - betdageshhebrew: 0xFB31, - bethebrew: 0x05D1, - betrafehebrew: 0xFB4C, - bhabengali: 0x09AD, - bhadeva: 0x092D, - bhagujarati: 0x0AAD, - bhagurmukhi: 0x0A2D, - bhook: 0x0253, - bihiragana: 0x3073, - bikatakana: 0x30D3, - bilabialclick: 0x0298, - bindigurmukhi: 0x0A02, - birusquare: 0x3331, - blackcircle: 0x25CF, - blackdiamond: 0x25C6, - blackdownpointingtriangle: 0x25BC, - blackleftpointingpointer: 0x25C4, - blackleftpointingtriangle: 0x25C0, - blacklenticularbracketleft: 0x3010, - blacklenticularbracketleftvertical: 0xFE3B, - blacklenticularbracketright: 0x3011, - blacklenticularbracketrightvertical: 0xFE3C, - blacklowerlefttriangle: 0x25E3, - blacklowerrighttriangle: 0x25E2, - blackrectangle: 0x25AC, - blackrightpointingpointer: 0x25BA, - blackrightpointingtriangle: 0x25B6, - blacksmallsquare: 0x25AA, - blacksmilingface: 0x263B, - blacksquare: 0x25A0, - blackstar: 0x2605, - blackupperlefttriangle: 0x25E4, - blackupperrighttriangle: 0x25E5, - blackuppointingsmalltriangle: 0x25B4, - blackuppointingtriangle: 0x25B2, - blank: 0x2423, - blinebelow: 0x1E07, - block: 0x2588, - bmonospace: 0xFF42, - bobaimaithai: 0x0E1A, - bohiragana: 0x307C, - bokatakana: 0x30DC, - bparen: 0x249D, - bqsquare: 0x33C3, - braceex: 0xF8F4, - braceleft: 0x007B, - braceleftbt: 0xF8F3, - braceleftmid: 0xF8F2, - braceleftmonospace: 0xFF5B, - braceleftsmall: 0xFE5B, - bracelefttp: 0xF8F1, - braceleftvertical: 0xFE37, - braceright: 0x007D, - bracerightbt: 0xF8FE, - bracerightmid: 0xF8FD, - bracerightmonospace: 0xFF5D, - bracerightsmall: 0xFE5C, - bracerighttp: 0xF8FC, - bracerightvertical: 0xFE38, - bracketleft: 0x005B, - bracketleftbt: 0xF8F0, - bracketleftex: 0xF8EF, - bracketleftmonospace: 0xFF3B, - bracketlefttp: 0xF8EE, - bracketright: 0x005D, - bracketrightbt: 0xF8FB, - bracketrightex: 0xF8FA, - bracketrightmonospace: 0xFF3D, - bracketrighttp: 0xF8F9, - breve: 0x02D8, - brevebelowcmb: 0x032E, - brevecmb: 0x0306, - breveinvertedbelowcmb: 0x032F, - breveinvertedcmb: 0x0311, - breveinverteddoublecmb: 0x0361, - bridgebelowcmb: 0x032A, - bridgeinvertedbelowcmb: 0x033A, - brokenbar: 0x00A6, - bstroke: 0x0180, - bsuperior: 0xF6EA, - btopbar: 0x0183, - buhiragana: 0x3076, - bukatakana: 0x30D6, - bullet: 0x2022, - bulletinverse: 0x25D8, - bulletoperator: 0x2219, - bullseye: 0x25CE, - c: 0x0063, - caarmenian: 0x056E, - cabengali: 0x099A, - cacute: 0x0107, - cadeva: 0x091A, - cagujarati: 0x0A9A, - cagurmukhi: 0x0A1A, - calsquare: 0x3388, - candrabindubengali: 0x0981, - candrabinducmb: 0x0310, - candrabindudeva: 0x0901, - candrabindugujarati: 0x0A81, - capslock: 0x21EA, - careof: 0x2105, - caron: 0x02C7, - caronbelowcmb: 0x032C, - caroncmb: 0x030C, - carriagereturn: 0x21B5, - cbopomofo: 0x3118, - ccaron: 0x010D, - ccedilla: 0x00E7, - ccedillaacute: 0x1E09, - ccircle: 0x24D2, - ccircumflex: 0x0109, - ccurl: 0x0255, - cdot: 0x010B, - cdotaccent: 0x010B, - cdsquare: 0x33C5, - cedilla: 0x00B8, - cedillacmb: 0x0327, - cent: 0x00A2, - centigrade: 0x2103, - centinferior: 0xF6DF, - centmonospace: 0xFFE0, - centoldstyle: 0xF7A2, - centsuperior: 0xF6E0, - chaarmenian: 0x0579, - chabengali: 0x099B, - chadeva: 0x091B, - chagujarati: 0x0A9B, - chagurmukhi: 0x0A1B, - chbopomofo: 0x3114, - cheabkhasiancyrillic: 0x04BD, - checkmark: 0x2713, - checyrillic: 0x0447, - chedescenderabkhasiancyrillic: 0x04BF, - chedescendercyrillic: 0x04B7, - chedieresiscyrillic: 0x04F5, - cheharmenian: 0x0573, - chekhakassiancyrillic: 0x04CC, - cheverticalstrokecyrillic: 0x04B9, - chi: 0x03C7, - chieuchacirclekorean: 0x3277, - chieuchaparenkorean: 0x3217, - chieuchcirclekorean: 0x3269, - chieuchkorean: 0x314A, - chieuchparenkorean: 0x3209, - chochangthai: 0x0E0A, - chochanthai: 0x0E08, - chochingthai: 0x0E09, - chochoethai: 0x0E0C, - chook: 0x0188, - cieucacirclekorean: 0x3276, - cieucaparenkorean: 0x3216, - cieuccirclekorean: 0x3268, - cieuckorean: 0x3148, - cieucparenkorean: 0x3208, - cieucuparenkorean: 0x321C, - circle: 0x25CB, - circlecopyrt: 0x00A9, // This glyph is missing from Adobe's original list. - circlemultiply: 0x2297, - circleot: 0x2299, - circleplus: 0x2295, - circlepostalmark: 0x3036, - circlewithlefthalfblack: 0x25D0, - circlewithrighthalfblack: 0x25D1, - circumflex: 0x02C6, - circumflexbelowcmb: 0x032D, - circumflexcmb: 0x0302, - clear: 0x2327, - clickalveolar: 0x01C2, - clickdental: 0x01C0, - clicklateral: 0x01C1, - clickretroflex: 0x01C3, - club: 0x2663, - clubsuitblack: 0x2663, - clubsuitwhite: 0x2667, - cmcubedsquare: 0x33A4, - cmonospace: 0xFF43, - cmsquaredsquare: 0x33A0, - coarmenian: 0x0581, - colon: 0x003A, - colonmonetary: 0x20A1, - colonmonospace: 0xFF1A, - colonsign: 0x20A1, - colonsmall: 0xFE55, - colontriangularhalfmod: 0x02D1, - colontriangularmod: 0x02D0, - comma: 0x002C, - commaabovecmb: 0x0313, - commaaboverightcmb: 0x0315, - commaaccent: 0xF6C3, - commaarabic: 0x060C, - commaarmenian: 0x055D, - commainferior: 0xF6E1, - commamonospace: 0xFF0C, - commareversedabovecmb: 0x0314, - commareversedmod: 0x02BD, - commasmall: 0xFE50, - commasuperior: 0xF6E2, - commaturnedabovecmb: 0x0312, - commaturnedmod: 0x02BB, - compass: 0x263C, - congruent: 0x2245, - contourintegral: 0x222E, - control: 0x2303, - controlACK: 0x0006, - controlBEL: 0x0007, - controlBS: 0x0008, - controlCAN: 0x0018, - controlCR: 0x000D, - controlDC1: 0x0011, - controlDC2: 0x0012, - controlDC3: 0x0013, - controlDC4: 0x0014, - controlDEL: 0x007F, - controlDLE: 0x0010, - controlEM: 0x0019, - controlENQ: 0x0005, - controlEOT: 0x0004, - controlESC: 0x001B, - controlETB: 0x0017, - controlETX: 0x0003, - controlFF: 0x000C, - controlFS: 0x001C, - controlGS: 0x001D, - controlHT: 0x0009, - controlLF: 0x000A, - controlNAK: 0x0015, - controlRS: 0x001E, - controlSI: 0x000F, - controlSO: 0x000E, - controlSOT: 0x0002, - controlSTX: 0x0001, - controlSUB: 0x001A, - controlSYN: 0x0016, - controlUS: 0x001F, - controlVT: 0x000B, - copyright: 0x00A9, - copyrightsans: 0xF8E9, - copyrightserif: 0xF6D9, - cornerbracketleft: 0x300C, - cornerbracketlefthalfwidth: 0xFF62, - cornerbracketleftvertical: 0xFE41, - cornerbracketright: 0x300D, - cornerbracketrighthalfwidth: 0xFF63, - cornerbracketrightvertical: 0xFE42, - corporationsquare: 0x337F, - cosquare: 0x33C7, - coverkgsquare: 0x33C6, - cparen: 0x249E, - cruzeiro: 0x20A2, - cstretched: 0x0297, - curlyand: 0x22CF, - curlyor: 0x22CE, - currency: 0x00A4, - cyrBreve: 0xF6D1, - cyrFlex: 0xF6D2, - cyrbreve: 0xF6D4, - cyrflex: 0xF6D5, - d: 0x0064, - daarmenian: 0x0564, - dabengali: 0x09A6, - dadarabic: 0x0636, - dadeva: 0x0926, - dadfinalarabic: 0xFEBE, - dadinitialarabic: 0xFEBF, - dadmedialarabic: 0xFEC0, - dagesh: 0x05BC, - dageshhebrew: 0x05BC, - dagger: 0x2020, - daggerdbl: 0x2021, - dagujarati: 0x0AA6, - dagurmukhi: 0x0A26, - dahiragana: 0x3060, - dakatakana: 0x30C0, - dalarabic: 0x062F, - dalet: 0x05D3, - daletdagesh: 0xFB33, - daletdageshhebrew: 0xFB33, - dalethebrew: 0x05D3, - dalfinalarabic: 0xFEAA, - dammaarabic: 0x064F, - dammalowarabic: 0x064F, - dammatanaltonearabic: 0x064C, - dammatanarabic: 0x064C, - danda: 0x0964, - dargahebrew: 0x05A7, - dargalefthebrew: 0x05A7, - dasiapneumatacyrilliccmb: 0x0485, - dblGrave: 0xF6D3, - dblanglebracketleft: 0x300A, - dblanglebracketleftvertical: 0xFE3D, - dblanglebracketright: 0x300B, - dblanglebracketrightvertical: 0xFE3E, - dblarchinvertedbelowcmb: 0x032B, - dblarrowleft: 0x21D4, - dblarrowright: 0x21D2, - dbldanda: 0x0965, - dblgrave: 0xF6D6, - dblgravecmb: 0x030F, - dblintegral: 0x222C, - dbllowline: 0x2017, - dbllowlinecmb: 0x0333, - dbloverlinecmb: 0x033F, - dblprimemod: 0x02BA, - dblverticalbar: 0x2016, - dblverticallineabovecmb: 0x030E, - dbopomofo: 0x3109, - dbsquare: 0x33C8, - dcaron: 0x010F, - dcedilla: 0x1E11, - dcircle: 0x24D3, - dcircumflexbelow: 0x1E13, - dcroat: 0x0111, - ddabengali: 0x09A1, - ddadeva: 0x0921, - ddagujarati: 0x0AA1, - ddagurmukhi: 0x0A21, - ddalarabic: 0x0688, - ddalfinalarabic: 0xFB89, - dddhadeva: 0x095C, - ddhabengali: 0x09A2, - ddhadeva: 0x0922, - ddhagujarati: 0x0AA2, - ddhagurmukhi: 0x0A22, - ddotaccent: 0x1E0B, - ddotbelow: 0x1E0D, - decimalseparatorarabic: 0x066B, - decimalseparatorpersian: 0x066B, - decyrillic: 0x0434, - degree: 0x00B0, - dehihebrew: 0x05AD, - dehiragana: 0x3067, - deicoptic: 0x03EF, - dekatakana: 0x30C7, - deleteleft: 0x232B, - deleteright: 0x2326, - delta: 0x03B4, - deltaturned: 0x018D, - denominatorminusonenumeratorbengali: 0x09F8, - dezh: 0x02A4, - dhabengali: 0x09A7, - dhadeva: 0x0927, - dhagujarati: 0x0AA7, - dhagurmukhi: 0x0A27, - dhook: 0x0257, - dialytikatonos: 0x0385, - dialytikatonoscmb: 0x0344, - diamond: 0x2666, - diamondsuitwhite: 0x2662, - dieresis: 0x00A8, - dieresisacute: 0xF6D7, - dieresisbelowcmb: 0x0324, - dieresiscmb: 0x0308, - dieresisgrave: 0xF6D8, - dieresistonos: 0x0385, - dihiragana: 0x3062, - dikatakana: 0x30C2, - dittomark: 0x3003, - divide: 0x00F7, - divides: 0x2223, - divisionslash: 0x2215, - djecyrillic: 0x0452, - dkshade: 0x2593, - dlinebelow: 0x1E0F, - dlsquare: 0x3397, - dmacron: 0x0111, - dmonospace: 0xFF44, - dnblock: 0x2584, - dochadathai: 0x0E0E, - dodekthai: 0x0E14, - dohiragana: 0x3069, - dokatakana: 0x30C9, - dollar: 0x0024, - dollarinferior: 0xF6E3, - dollarmonospace: 0xFF04, - dollaroldstyle: 0xF724, - dollarsmall: 0xFE69, - dollarsuperior: 0xF6E4, - dong: 0x20AB, - dorusquare: 0x3326, - dotaccent: 0x02D9, - dotaccentcmb: 0x0307, - dotbelowcmb: 0x0323, - dotbelowcomb: 0x0323, - dotkatakana: 0x30FB, - dotlessi: 0x0131, - dotlessj: 0xF6BE, - dotlessjstrokehook: 0x0284, - dotmath: 0x22C5, - dottedcircle: 0x25CC, - doubleyodpatah: 0xFB1F, - doubleyodpatahhebrew: 0xFB1F, - downtackbelowcmb: 0x031E, - downtackmod: 0x02D5, - dparen: 0x249F, - dsuperior: 0xF6EB, - dtail: 0x0256, - dtopbar: 0x018C, - duhiragana: 0x3065, - dukatakana: 0x30C5, - dz: 0x01F3, - dzaltone: 0x02A3, - dzcaron: 0x01C6, - dzcurl: 0x02A5, - dzeabkhasiancyrillic: 0x04E1, - dzecyrillic: 0x0455, - dzhecyrillic: 0x045F, - e: 0x0065, - eacute: 0x00E9, - earth: 0x2641, - ebengali: 0x098F, - ebopomofo: 0x311C, - ebreve: 0x0115, - ecandradeva: 0x090D, - ecandragujarati: 0x0A8D, - ecandravowelsigndeva: 0x0945, - ecandravowelsigngujarati: 0x0AC5, - ecaron: 0x011B, - ecedillabreve: 0x1E1D, - echarmenian: 0x0565, - echyiwnarmenian: 0x0587, - ecircle: 0x24D4, - ecircumflex: 0x00EA, - ecircumflexacute: 0x1EBF, - ecircumflexbelow: 0x1E19, - ecircumflexdotbelow: 0x1EC7, - ecircumflexgrave: 0x1EC1, - ecircumflexhookabove: 0x1EC3, - ecircumflextilde: 0x1EC5, - ecyrillic: 0x0454, - edblgrave: 0x0205, - edeva: 0x090F, - edieresis: 0x00EB, - edot: 0x0117, - edotaccent: 0x0117, - edotbelow: 0x1EB9, - eegurmukhi: 0x0A0F, - eematragurmukhi: 0x0A47, - efcyrillic: 0x0444, - egrave: 0x00E8, - egujarati: 0x0A8F, - eharmenian: 0x0567, - ehbopomofo: 0x311D, - ehiragana: 0x3048, - ehookabove: 0x1EBB, - eibopomofo: 0x311F, - eight: 0x0038, - eightarabic: 0x0668, - eightbengali: 0x09EE, - eightcircle: 0x2467, - eightcircleinversesansserif: 0x2791, - eightdeva: 0x096E, - eighteencircle: 0x2471, - eighteenparen: 0x2485, - eighteenperiod: 0x2499, - eightgujarati: 0x0AEE, - eightgurmukhi: 0x0A6E, - eighthackarabic: 0x0668, - eighthangzhou: 0x3028, - eighthnotebeamed: 0x266B, - eightideographicparen: 0x3227, - eightinferior: 0x2088, - eightmonospace: 0xFF18, - eightoldstyle: 0xF738, - eightparen: 0x247B, - eightperiod: 0x248F, - eightpersian: 0x06F8, - eightroman: 0x2177, - eightsuperior: 0x2078, - eightthai: 0x0E58, - einvertedbreve: 0x0207, - eiotifiedcyrillic: 0x0465, - ekatakana: 0x30A8, - ekatakanahalfwidth: 0xFF74, - ekonkargurmukhi: 0x0A74, - ekorean: 0x3154, - elcyrillic: 0x043B, - element: 0x2208, - elevencircle: 0x246A, - elevenparen: 0x247E, - elevenperiod: 0x2492, - elevenroman: 0x217A, - ellipsis: 0x2026, - ellipsisvertical: 0x22EE, - emacron: 0x0113, - emacronacute: 0x1E17, - emacrongrave: 0x1E15, - emcyrillic: 0x043C, - emdash: 0x2014, - emdashvertical: 0xFE31, - emonospace: 0xFF45, - emphasismarkarmenian: 0x055B, - emptyset: 0x2205, - enbopomofo: 0x3123, - encyrillic: 0x043D, - endash: 0x2013, - endashvertical: 0xFE32, - endescendercyrillic: 0x04A3, - eng: 0x014B, - engbopomofo: 0x3125, - enghecyrillic: 0x04A5, - enhookcyrillic: 0x04C8, - enspace: 0x2002, - eogonek: 0x0119, - eokorean: 0x3153, - eopen: 0x025B, - eopenclosed: 0x029A, - eopenreversed: 0x025C, - eopenreversedclosed: 0x025E, - eopenreversedhook: 0x025D, - eparen: 0x24A0, - epsilon: 0x03B5, - epsilontonos: 0x03AD, - equal: 0x003D, - equalmonospace: 0xFF1D, - equalsmall: 0xFE66, - equalsuperior: 0x207C, - equivalence: 0x2261, - erbopomofo: 0x3126, - ercyrillic: 0x0440, - ereversed: 0x0258, - ereversedcyrillic: 0x044D, - escyrillic: 0x0441, - esdescendercyrillic: 0x04AB, - esh: 0x0283, - eshcurl: 0x0286, - eshortdeva: 0x090E, - eshortvowelsigndeva: 0x0946, - eshreversedloop: 0x01AA, - eshsquatreversed: 0x0285, - esmallhiragana: 0x3047, - esmallkatakana: 0x30A7, - esmallkatakanahalfwidth: 0xFF6A, - estimated: 0x212E, - esuperior: 0xF6EC, - eta: 0x03B7, - etarmenian: 0x0568, - etatonos: 0x03AE, - eth: 0x00F0, - etilde: 0x1EBD, - etildebelow: 0x1E1B, - etnahtafoukhhebrew: 0x0591, - etnahtafoukhlefthebrew: 0x0591, - etnahtahebrew: 0x0591, - etnahtalefthebrew: 0x0591, - eturned: 0x01DD, - eukorean: 0x3161, - euro: 0x20AC, - evowelsignbengali: 0x09C7, - evowelsigndeva: 0x0947, - evowelsigngujarati: 0x0AC7, - exclam: 0x0021, - exclamarmenian: 0x055C, - exclamdbl: 0x203C, - exclamdown: 0x00A1, - exclamdownsmall: 0xF7A1, - exclammonospace: 0xFF01, - exclamsmall: 0xF721, - existential: 0x2203, - ezh: 0x0292, - ezhcaron: 0x01EF, - ezhcurl: 0x0293, - ezhreversed: 0x01B9, - ezhtail: 0x01BA, - f: 0x0066, - fadeva: 0x095E, - fagurmukhi: 0x0A5E, - fahrenheit: 0x2109, - fathaarabic: 0x064E, - fathalowarabic: 0x064E, - fathatanarabic: 0x064B, - fbopomofo: 0x3108, - fcircle: 0x24D5, - fdotaccent: 0x1E1F, - feharabic: 0x0641, - feharmenian: 0x0586, - fehfinalarabic: 0xFED2, - fehinitialarabic: 0xFED3, - fehmedialarabic: 0xFED4, - feicoptic: 0x03E5, - female: 0x2640, - ff: 0xFB00, - ffi: 0xFB03, - ffl: 0xFB04, - fi: 0xFB01, - fifteencircle: 0x246E, - fifteenparen: 0x2482, - fifteenperiod: 0x2496, - figuredash: 0x2012, - filledbox: 0x25A0, - filledrect: 0x25AC, - finalkaf: 0x05DA, - finalkafdagesh: 0xFB3A, - finalkafdageshhebrew: 0xFB3A, - finalkafhebrew: 0x05DA, - finalmem: 0x05DD, - finalmemhebrew: 0x05DD, - finalnun: 0x05DF, - finalnunhebrew: 0x05DF, - finalpe: 0x05E3, - finalpehebrew: 0x05E3, - finaltsadi: 0x05E5, - finaltsadihebrew: 0x05E5, - firsttonechinese: 0x02C9, - fisheye: 0x25C9, - fitacyrillic: 0x0473, - five: 0x0035, - fivearabic: 0x0665, - fivebengali: 0x09EB, - fivecircle: 0x2464, - fivecircleinversesansserif: 0x278E, - fivedeva: 0x096B, - fiveeighths: 0x215D, - fivegujarati: 0x0AEB, - fivegurmukhi: 0x0A6B, - fivehackarabic: 0x0665, - fivehangzhou: 0x3025, - fiveideographicparen: 0x3224, - fiveinferior: 0x2085, - fivemonospace: 0xFF15, - fiveoldstyle: 0xF735, - fiveparen: 0x2478, - fiveperiod: 0x248C, - fivepersian: 0x06F5, - fiveroman: 0x2174, - fivesuperior: 0x2075, - fivethai: 0x0E55, - fl: 0xFB02, - florin: 0x0192, - fmonospace: 0xFF46, - fmsquare: 0x3399, - fofanthai: 0x0E1F, - fofathai: 0x0E1D, - fongmanthai: 0x0E4F, - forall: 0x2200, - four: 0x0034, - fourarabic: 0x0664, - fourbengali: 0x09EA, - fourcircle: 0x2463, - fourcircleinversesansserif: 0x278D, - fourdeva: 0x096A, - fourgujarati: 0x0AEA, - fourgurmukhi: 0x0A6A, - fourhackarabic: 0x0664, - fourhangzhou: 0x3024, - fourideographicparen: 0x3223, - fourinferior: 0x2084, - fourmonospace: 0xFF14, - fournumeratorbengali: 0x09F7, - fouroldstyle: 0xF734, - fourparen: 0x2477, - fourperiod: 0x248B, - fourpersian: 0x06F4, - fourroman: 0x2173, - foursuperior: 0x2074, - fourteencircle: 0x246D, - fourteenparen: 0x2481, - fourteenperiod: 0x2495, - fourthai: 0x0E54, - fourthtonechinese: 0x02CB, - fparen: 0x24A1, - fraction: 0x2044, - franc: 0x20A3, - g: 0x0067, - gabengali: 0x0997, - gacute: 0x01F5, - gadeva: 0x0917, - gafarabic: 0x06AF, - gaffinalarabic: 0xFB93, - gafinitialarabic: 0xFB94, - gafmedialarabic: 0xFB95, - gagujarati: 0x0A97, - gagurmukhi: 0x0A17, - gahiragana: 0x304C, - gakatakana: 0x30AC, - gamma: 0x03B3, - gammalatinsmall: 0x0263, - gammasuperior: 0x02E0, - gangiacoptic: 0x03EB, - gbopomofo: 0x310D, - gbreve: 0x011F, - gcaron: 0x01E7, - gcedilla: 0x0123, - gcircle: 0x24D6, - gcircumflex: 0x011D, - gcommaaccent: 0x0123, - gdot: 0x0121, - gdotaccent: 0x0121, - gecyrillic: 0x0433, - gehiragana: 0x3052, - gekatakana: 0x30B2, - geometricallyequal: 0x2251, - gereshaccenthebrew: 0x059C, - gereshhebrew: 0x05F3, - gereshmuqdamhebrew: 0x059D, - germandbls: 0x00DF, - gershayimaccenthebrew: 0x059E, - gershayimhebrew: 0x05F4, - getamark: 0x3013, - ghabengali: 0x0998, - ghadarmenian: 0x0572, - ghadeva: 0x0918, - ghagujarati: 0x0A98, - ghagurmukhi: 0x0A18, - ghainarabic: 0x063A, - ghainfinalarabic: 0xFECE, - ghaininitialarabic: 0xFECF, - ghainmedialarabic: 0xFED0, - ghemiddlehookcyrillic: 0x0495, - ghestrokecyrillic: 0x0493, - gheupturncyrillic: 0x0491, - ghhadeva: 0x095A, - ghhagurmukhi: 0x0A5A, - ghook: 0x0260, - ghzsquare: 0x3393, - gihiragana: 0x304E, - gikatakana: 0x30AE, - gimarmenian: 0x0563, - gimel: 0x05D2, - gimeldagesh: 0xFB32, - gimeldageshhebrew: 0xFB32, - gimelhebrew: 0x05D2, - gjecyrillic: 0x0453, - glottalinvertedstroke: 0x01BE, - glottalstop: 0x0294, - glottalstopinverted: 0x0296, - glottalstopmod: 0x02C0, - glottalstopreversed: 0x0295, - glottalstopreversedmod: 0x02C1, - glottalstopreversedsuperior: 0x02E4, - glottalstopstroke: 0x02A1, - glottalstopstrokereversed: 0x02A2, - gmacron: 0x1E21, - gmonospace: 0xFF47, - gohiragana: 0x3054, - gokatakana: 0x30B4, - gparen: 0x24A2, - gpasquare: 0x33AC, - gradient: 0x2207, - grave: 0x0060, - gravebelowcmb: 0x0316, - gravecmb: 0x0300, - gravecomb: 0x0300, - gravedeva: 0x0953, - gravelowmod: 0x02CE, - gravemonospace: 0xFF40, - gravetonecmb: 0x0340, - greater: 0x003E, - greaterequal: 0x2265, - greaterequalorless: 0x22DB, - greatermonospace: 0xFF1E, - greaterorequivalent: 0x2273, - greaterorless: 0x2277, - greateroverequal: 0x2267, - greatersmall: 0xFE65, - gscript: 0x0261, - gstroke: 0x01E5, - guhiragana: 0x3050, - guillemotleft: 0x00AB, - guillemotright: 0x00BB, - guilsinglleft: 0x2039, - guilsinglright: 0x203A, - gukatakana: 0x30B0, - guramusquare: 0x3318, - gysquare: 0x33C9, - h: 0x0068, - haabkhasiancyrillic: 0x04A9, - haaltonearabic: 0x06C1, - habengali: 0x09B9, - hadescendercyrillic: 0x04B3, - hadeva: 0x0939, - hagujarati: 0x0AB9, - hagurmukhi: 0x0A39, - haharabic: 0x062D, - hahfinalarabic: 0xFEA2, - hahinitialarabic: 0xFEA3, - hahiragana: 0x306F, - hahmedialarabic: 0xFEA4, - haitusquare: 0x332A, - hakatakana: 0x30CF, - hakatakanahalfwidth: 0xFF8A, - halantgurmukhi: 0x0A4D, - hamzaarabic: 0x0621, - hamzalowarabic: 0x0621, - hangulfiller: 0x3164, - hardsigncyrillic: 0x044A, - harpoonleftbarbup: 0x21BC, - harpoonrightbarbup: 0x21C0, - hasquare: 0x33CA, - hatafpatah: 0x05B2, - hatafpatah16: 0x05B2, - hatafpatah23: 0x05B2, - hatafpatah2f: 0x05B2, - hatafpatahhebrew: 0x05B2, - hatafpatahnarrowhebrew: 0x05B2, - hatafpatahquarterhebrew: 0x05B2, - hatafpatahwidehebrew: 0x05B2, - hatafqamats: 0x05B3, - hatafqamats1b: 0x05B3, - hatafqamats28: 0x05B3, - hatafqamats34: 0x05B3, - hatafqamatshebrew: 0x05B3, - hatafqamatsnarrowhebrew: 0x05B3, - hatafqamatsquarterhebrew: 0x05B3, - hatafqamatswidehebrew: 0x05B3, - hatafsegol: 0x05B1, - hatafsegol17: 0x05B1, - hatafsegol24: 0x05B1, - hatafsegol30: 0x05B1, - hatafsegolhebrew: 0x05B1, - hatafsegolnarrowhebrew: 0x05B1, - hatafsegolquarterhebrew: 0x05B1, - hatafsegolwidehebrew: 0x05B1, - hbar: 0x0127, - hbopomofo: 0x310F, - hbrevebelow: 0x1E2B, - hcedilla: 0x1E29, - hcircle: 0x24D7, - hcircumflex: 0x0125, - hdieresis: 0x1E27, - hdotaccent: 0x1E23, - hdotbelow: 0x1E25, - he: 0x05D4, - heart: 0x2665, - heartsuitblack: 0x2665, - heartsuitwhite: 0x2661, - hedagesh: 0xFB34, - hedageshhebrew: 0xFB34, - hehaltonearabic: 0x06C1, - heharabic: 0x0647, - hehebrew: 0x05D4, - hehfinalaltonearabic: 0xFBA7, - hehfinalalttwoarabic: 0xFEEA, - hehfinalarabic: 0xFEEA, - hehhamzaabovefinalarabic: 0xFBA5, - hehhamzaaboveisolatedarabic: 0xFBA4, - hehinitialaltonearabic: 0xFBA8, - hehinitialarabic: 0xFEEB, - hehiragana: 0x3078, - hehmedialaltonearabic: 0xFBA9, - hehmedialarabic: 0xFEEC, - heiseierasquare: 0x337B, - hekatakana: 0x30D8, - hekatakanahalfwidth: 0xFF8D, - hekutaarusquare: 0x3336, - henghook: 0x0267, - herutusquare: 0x3339, - het: 0x05D7, - hethebrew: 0x05D7, - hhook: 0x0266, - hhooksuperior: 0x02B1, - hieuhacirclekorean: 0x327B, - hieuhaparenkorean: 0x321B, - hieuhcirclekorean: 0x326D, - hieuhkorean: 0x314E, - hieuhparenkorean: 0x320D, - hihiragana: 0x3072, - hikatakana: 0x30D2, - hikatakanahalfwidth: 0xFF8B, - hiriq: 0x05B4, - hiriq14: 0x05B4, - hiriq21: 0x05B4, - hiriq2d: 0x05B4, - hiriqhebrew: 0x05B4, - hiriqnarrowhebrew: 0x05B4, - hiriqquarterhebrew: 0x05B4, - hiriqwidehebrew: 0x05B4, - hlinebelow: 0x1E96, - hmonospace: 0xFF48, - hoarmenian: 0x0570, - hohipthai: 0x0E2B, - hohiragana: 0x307B, - hokatakana: 0x30DB, - hokatakanahalfwidth: 0xFF8E, - holam: 0x05B9, - holam19: 0x05B9, - holam26: 0x05B9, - holam32: 0x05B9, - holamhebrew: 0x05B9, - holamnarrowhebrew: 0x05B9, - holamquarterhebrew: 0x05B9, - holamwidehebrew: 0x05B9, - honokhukthai: 0x0E2E, - hookabovecomb: 0x0309, - hookcmb: 0x0309, - hookpalatalizedbelowcmb: 0x0321, - hookretroflexbelowcmb: 0x0322, - hoonsquare: 0x3342, - horicoptic: 0x03E9, - horizontalbar: 0x2015, - horncmb: 0x031B, - hotsprings: 0x2668, - house: 0x2302, - hparen: 0x24A3, - hsuperior: 0x02B0, - hturned: 0x0265, - huhiragana: 0x3075, - huiitosquare: 0x3333, - hukatakana: 0x30D5, - hukatakanahalfwidth: 0xFF8C, - hungarumlaut: 0x02DD, - hungarumlautcmb: 0x030B, - hv: 0x0195, - hyphen: 0x002D, - hypheninferior: 0xF6E5, - hyphenmonospace: 0xFF0D, - hyphensmall: 0xFE63, - hyphensuperior: 0xF6E6, - hyphentwo: 0x2010, - i: 0x0069, - iacute: 0x00ED, - iacyrillic: 0x044F, - ibengali: 0x0987, - ibopomofo: 0x3127, - ibreve: 0x012D, - icaron: 0x01D0, - icircle: 0x24D8, - icircumflex: 0x00EE, - icyrillic: 0x0456, - idblgrave: 0x0209, - ideographearthcircle: 0x328F, - ideographfirecircle: 0x328B, - ideographicallianceparen: 0x323F, - ideographiccallparen: 0x323A, - ideographiccentrecircle: 0x32A5, - ideographicclose: 0x3006, - ideographiccomma: 0x3001, - ideographiccommaleft: 0xFF64, - ideographiccongratulationparen: 0x3237, - ideographiccorrectcircle: 0x32A3, - ideographicearthparen: 0x322F, - ideographicenterpriseparen: 0x323D, - ideographicexcellentcircle: 0x329D, - ideographicfestivalparen: 0x3240, - ideographicfinancialcircle: 0x3296, - ideographicfinancialparen: 0x3236, - ideographicfireparen: 0x322B, - ideographichaveparen: 0x3232, - ideographichighcircle: 0x32A4, - ideographiciterationmark: 0x3005, - ideographiclaborcircle: 0x3298, - ideographiclaborparen: 0x3238, - ideographicleftcircle: 0x32A7, - ideographiclowcircle: 0x32A6, - ideographicmedicinecircle: 0x32A9, - ideographicmetalparen: 0x322E, - ideographicmoonparen: 0x322A, - ideographicnameparen: 0x3234, - ideographicperiod: 0x3002, - ideographicprintcircle: 0x329E, - ideographicreachparen: 0x3243, - ideographicrepresentparen: 0x3239, - ideographicresourceparen: 0x323E, - ideographicrightcircle: 0x32A8, - ideographicsecretcircle: 0x3299, - ideographicselfparen: 0x3242, - ideographicsocietyparen: 0x3233, - ideographicspace: 0x3000, - ideographicspecialparen: 0x3235, - ideographicstockparen: 0x3231, - ideographicstudyparen: 0x323B, - ideographicsunparen: 0x3230, - ideographicsuperviseparen: 0x323C, - ideographicwaterparen: 0x322C, - ideographicwoodparen: 0x322D, - ideographiczero: 0x3007, - ideographmetalcircle: 0x328E, - ideographmooncircle: 0x328A, - ideographnamecircle: 0x3294, - ideographsuncircle: 0x3290, - ideographwatercircle: 0x328C, - ideographwoodcircle: 0x328D, - ideva: 0x0907, - idieresis: 0x00EF, - idieresisacute: 0x1E2F, - idieresiscyrillic: 0x04E5, - idotbelow: 0x1ECB, - iebrevecyrillic: 0x04D7, - iecyrillic: 0x0435, - ieungacirclekorean: 0x3275, - ieungaparenkorean: 0x3215, - ieungcirclekorean: 0x3267, - ieungkorean: 0x3147, - ieungparenkorean: 0x3207, - igrave: 0x00EC, - igujarati: 0x0A87, - igurmukhi: 0x0A07, - ihiragana: 0x3044, - ihookabove: 0x1EC9, - iibengali: 0x0988, - iicyrillic: 0x0438, - iideva: 0x0908, - iigujarati: 0x0A88, - iigurmukhi: 0x0A08, - iimatragurmukhi: 0x0A40, - iinvertedbreve: 0x020B, - iishortcyrillic: 0x0439, - iivowelsignbengali: 0x09C0, - iivowelsigndeva: 0x0940, - iivowelsigngujarati: 0x0AC0, - ij: 0x0133, - ikatakana: 0x30A4, - ikatakanahalfwidth: 0xFF72, - ikorean: 0x3163, - ilde: 0x02DC, - iluyhebrew: 0x05AC, - imacron: 0x012B, - imacroncyrillic: 0x04E3, - imageorapproximatelyequal: 0x2253, - imatragurmukhi: 0x0A3F, - imonospace: 0xFF49, - increment: 0x2206, - infinity: 0x221E, - iniarmenian: 0x056B, - integral: 0x222B, - integralbottom: 0x2321, - integralbt: 0x2321, - integralex: 0xF8F5, - integraltop: 0x2320, - integraltp: 0x2320, - intersection: 0x2229, - intisquare: 0x3305, - invbullet: 0x25D8, - invcircle: 0x25D9, - invsmileface: 0x263B, - iocyrillic: 0x0451, - iogonek: 0x012F, - iota: 0x03B9, - iotadieresis: 0x03CA, - iotadieresistonos: 0x0390, - iotalatin: 0x0269, - iotatonos: 0x03AF, - iparen: 0x24A4, - irigurmukhi: 0x0A72, - ismallhiragana: 0x3043, - ismallkatakana: 0x30A3, - ismallkatakanahalfwidth: 0xFF68, - issharbengali: 0x09FA, - istroke: 0x0268, - isuperior: 0xF6ED, - iterationhiragana: 0x309D, - iterationkatakana: 0x30FD, - itilde: 0x0129, - itildebelow: 0x1E2D, - iubopomofo: 0x3129, - iucyrillic: 0x044E, - ivowelsignbengali: 0x09BF, - ivowelsigndeva: 0x093F, - ivowelsigngujarati: 0x0ABF, - izhitsacyrillic: 0x0475, - izhitsadblgravecyrillic: 0x0477, - j: 0x006A, - jaarmenian: 0x0571, - jabengali: 0x099C, - jadeva: 0x091C, - jagujarati: 0x0A9C, - jagurmukhi: 0x0A1C, - jbopomofo: 0x3110, - jcaron: 0x01F0, - jcircle: 0x24D9, - jcircumflex: 0x0135, - jcrossedtail: 0x029D, - jdotlessstroke: 0x025F, - jecyrillic: 0x0458, - jeemarabic: 0x062C, - jeemfinalarabic: 0xFE9E, - jeeminitialarabic: 0xFE9F, - jeemmedialarabic: 0xFEA0, - jeharabic: 0x0698, - jehfinalarabic: 0xFB8B, - jhabengali: 0x099D, - jhadeva: 0x091D, - jhagujarati: 0x0A9D, - jhagurmukhi: 0x0A1D, - jheharmenian: 0x057B, - jis: 0x3004, - jmonospace: 0xFF4A, - jparen: 0x24A5, - jsuperior: 0x02B2, - k: 0x006B, - kabashkircyrillic: 0x04A1, - kabengali: 0x0995, - kacute: 0x1E31, - kacyrillic: 0x043A, - kadescendercyrillic: 0x049B, - kadeva: 0x0915, - kaf: 0x05DB, - kafarabic: 0x0643, - kafdagesh: 0xFB3B, - kafdageshhebrew: 0xFB3B, - kaffinalarabic: 0xFEDA, - kafhebrew: 0x05DB, - kafinitialarabic: 0xFEDB, - kafmedialarabic: 0xFEDC, - kafrafehebrew: 0xFB4D, - kagujarati: 0x0A95, - kagurmukhi: 0x0A15, - kahiragana: 0x304B, - kahookcyrillic: 0x04C4, - kakatakana: 0x30AB, - kakatakanahalfwidth: 0xFF76, - kappa: 0x03BA, - kappasymbolgreek: 0x03F0, - kapyeounmieumkorean: 0x3171, - kapyeounphieuphkorean: 0x3184, - kapyeounpieupkorean: 0x3178, - kapyeounssangpieupkorean: 0x3179, - karoriisquare: 0x330D, - kashidaautoarabic: 0x0640, - kashidaautonosidebearingarabic: 0x0640, - kasmallkatakana: 0x30F5, - kasquare: 0x3384, - kasraarabic: 0x0650, - kasratanarabic: 0x064D, - kastrokecyrillic: 0x049F, - katahiraprolongmarkhalfwidth: 0xFF70, - kaverticalstrokecyrillic: 0x049D, - kbopomofo: 0x310E, - kcalsquare: 0x3389, - kcaron: 0x01E9, - kcedilla: 0x0137, - kcircle: 0x24DA, - kcommaaccent: 0x0137, - kdotbelow: 0x1E33, - keharmenian: 0x0584, - kehiragana: 0x3051, - kekatakana: 0x30B1, - kekatakanahalfwidth: 0xFF79, - kenarmenian: 0x056F, - kesmallkatakana: 0x30F6, - kgreenlandic: 0x0138, - khabengali: 0x0996, - khacyrillic: 0x0445, - khadeva: 0x0916, - khagujarati: 0x0A96, - khagurmukhi: 0x0A16, - khaharabic: 0x062E, - khahfinalarabic: 0xFEA6, - khahinitialarabic: 0xFEA7, - khahmedialarabic: 0xFEA8, - kheicoptic: 0x03E7, - khhadeva: 0x0959, - khhagurmukhi: 0x0A59, - khieukhacirclekorean: 0x3278, - khieukhaparenkorean: 0x3218, - khieukhcirclekorean: 0x326A, - khieukhkorean: 0x314B, - khieukhparenkorean: 0x320A, - khokhaithai: 0x0E02, - khokhonthai: 0x0E05, - khokhuatthai: 0x0E03, - khokhwaithai: 0x0E04, - khomutthai: 0x0E5B, - khook: 0x0199, - khorakhangthai: 0x0E06, - khzsquare: 0x3391, - kihiragana: 0x304D, - kikatakana: 0x30AD, - kikatakanahalfwidth: 0xFF77, - kiroguramusquare: 0x3315, - kiromeetorusquare: 0x3316, - kirosquare: 0x3314, - kiyeokacirclekorean: 0x326E, - kiyeokaparenkorean: 0x320E, - kiyeokcirclekorean: 0x3260, - kiyeokkorean: 0x3131, - kiyeokparenkorean: 0x3200, - kiyeoksioskorean: 0x3133, - kjecyrillic: 0x045C, - klinebelow: 0x1E35, - klsquare: 0x3398, - kmcubedsquare: 0x33A6, - kmonospace: 0xFF4B, - kmsquaredsquare: 0x33A2, - kohiragana: 0x3053, - kohmsquare: 0x33C0, - kokaithai: 0x0E01, - kokatakana: 0x30B3, - kokatakanahalfwidth: 0xFF7A, - kooposquare: 0x331E, - koppacyrillic: 0x0481, - koreanstandardsymbol: 0x327F, - koroniscmb: 0x0343, - kparen: 0x24A6, - kpasquare: 0x33AA, - ksicyrillic: 0x046F, - ktsquare: 0x33CF, - kturned: 0x029E, - kuhiragana: 0x304F, - kukatakana: 0x30AF, - kukatakanahalfwidth: 0xFF78, - kvsquare: 0x33B8, - kwsquare: 0x33BE, - l: 0x006C, - labengali: 0x09B2, - lacute: 0x013A, - ladeva: 0x0932, - lagujarati: 0x0AB2, - lagurmukhi: 0x0A32, - lakkhangyaothai: 0x0E45, - lamaleffinalarabic: 0xFEFC, - lamalefhamzaabovefinalarabic: 0xFEF8, - lamalefhamzaaboveisolatedarabic: 0xFEF7, - lamalefhamzabelowfinalarabic: 0xFEFA, - lamalefhamzabelowisolatedarabic: 0xFEF9, - lamalefisolatedarabic: 0xFEFB, - lamalefmaddaabovefinalarabic: 0xFEF6, - lamalefmaddaaboveisolatedarabic: 0xFEF5, - lamarabic: 0x0644, - lambda: 0x03BB, - lambdastroke: 0x019B, - lamed: 0x05DC, - lameddagesh: 0xFB3C, - lameddageshhebrew: 0xFB3C, - lamedhebrew: 0x05DC, - lamfinalarabic: 0xFEDE, - lamhahinitialarabic: 0xFCCA, - laminitialarabic: 0xFEDF, - lamjeeminitialarabic: 0xFCC9, - lamkhahinitialarabic: 0xFCCB, - lamlamhehisolatedarabic: 0xFDF2, - lammedialarabic: 0xFEE0, - lammeemhahinitialarabic: 0xFD88, - lammeeminitialarabic: 0xFCCC, - largecircle: 0x25EF, - lbar: 0x019A, - lbelt: 0x026C, - lbopomofo: 0x310C, - lcaron: 0x013E, - lcedilla: 0x013C, - lcircle: 0x24DB, - lcircumflexbelow: 0x1E3D, - lcommaaccent: 0x013C, - ldot: 0x0140, - ldotaccent: 0x0140, - ldotbelow: 0x1E37, - ldotbelowmacron: 0x1E39, - leftangleabovecmb: 0x031A, - lefttackbelowcmb: 0x0318, - less: 0x003C, - lessequal: 0x2264, - lessequalorgreater: 0x22DA, - lessmonospace: 0xFF1C, - lessorequivalent: 0x2272, - lessorgreater: 0x2276, - lessoverequal: 0x2266, - lesssmall: 0xFE64, - lezh: 0x026E, - lfblock: 0x258C, - lhookretroflex: 0x026D, - lira: 0x20A4, - liwnarmenian: 0x056C, - lj: 0x01C9, - ljecyrillic: 0x0459, - ll: 0xF6C0, - lladeva: 0x0933, - llagujarati: 0x0AB3, - llinebelow: 0x1E3B, - llladeva: 0x0934, - llvocalicbengali: 0x09E1, - llvocalicdeva: 0x0961, - llvocalicvowelsignbengali: 0x09E3, - llvocalicvowelsigndeva: 0x0963, - lmiddletilde: 0x026B, - lmonospace: 0xFF4C, - lmsquare: 0x33D0, - lochulathai: 0x0E2C, - logicaland: 0x2227, - logicalnot: 0x00AC, - logicalnotreversed: 0x2310, - logicalor: 0x2228, - lolingthai: 0x0E25, - longs: 0x017F, - lowlinecenterline: 0xFE4E, - lowlinecmb: 0x0332, - lowlinedashed: 0xFE4D, - lozenge: 0x25CA, - lparen: 0x24A7, - lslash: 0x0142, - lsquare: 0x2113, - lsuperior: 0xF6EE, - ltshade: 0x2591, - luthai: 0x0E26, - lvocalicbengali: 0x098C, - lvocalicdeva: 0x090C, - lvocalicvowelsignbengali: 0x09E2, - lvocalicvowelsigndeva: 0x0962, - lxsquare: 0x33D3, - m: 0x006D, - mabengali: 0x09AE, - macron: 0x00AF, - macronbelowcmb: 0x0331, - macroncmb: 0x0304, - macronlowmod: 0x02CD, - macronmonospace: 0xFFE3, - macute: 0x1E3F, - madeva: 0x092E, - magujarati: 0x0AAE, - magurmukhi: 0x0A2E, - mahapakhhebrew: 0x05A4, - mahapakhlefthebrew: 0x05A4, - mahiragana: 0x307E, - maichattawalowleftthai: 0xF895, - maichattawalowrightthai: 0xF894, - maichattawathai: 0x0E4B, - maichattawaupperleftthai: 0xF893, - maieklowleftthai: 0xF88C, - maieklowrightthai: 0xF88B, - maiekthai: 0x0E48, - maiekupperleftthai: 0xF88A, - maihanakatleftthai: 0xF884, - maihanakatthai: 0x0E31, - maitaikhuleftthai: 0xF889, - maitaikhuthai: 0x0E47, - maitholowleftthai: 0xF88F, - maitholowrightthai: 0xF88E, - maithothai: 0x0E49, - maithoupperleftthai: 0xF88D, - maitrilowleftthai: 0xF892, - maitrilowrightthai: 0xF891, - maitrithai: 0x0E4A, - maitriupperleftthai: 0xF890, - maiyamokthai: 0x0E46, - makatakana: 0x30DE, - makatakanahalfwidth: 0xFF8F, - male: 0x2642, - mansyonsquare: 0x3347, - maqafhebrew: 0x05BE, - mars: 0x2642, - masoracirclehebrew: 0x05AF, - masquare: 0x3383, - mbopomofo: 0x3107, - mbsquare: 0x33D4, - mcircle: 0x24DC, - mcubedsquare: 0x33A5, - mdotaccent: 0x1E41, - mdotbelow: 0x1E43, - meemarabic: 0x0645, - meemfinalarabic: 0xFEE2, - meeminitialarabic: 0xFEE3, - meemmedialarabic: 0xFEE4, - meemmeeminitialarabic: 0xFCD1, - meemmeemisolatedarabic: 0xFC48, - meetorusquare: 0x334D, - mehiragana: 0x3081, - meizierasquare: 0x337E, - mekatakana: 0x30E1, - mekatakanahalfwidth: 0xFF92, - mem: 0x05DE, - memdagesh: 0xFB3E, - memdageshhebrew: 0xFB3E, - memhebrew: 0x05DE, - menarmenian: 0x0574, - merkhahebrew: 0x05A5, - merkhakefulahebrew: 0x05A6, - merkhakefulalefthebrew: 0x05A6, - merkhalefthebrew: 0x05A5, - mhook: 0x0271, - mhzsquare: 0x3392, - middledotkatakanahalfwidth: 0xFF65, - middot: 0x00B7, - mieumacirclekorean: 0x3272, - mieumaparenkorean: 0x3212, - mieumcirclekorean: 0x3264, - mieumkorean: 0x3141, - mieumpansioskorean: 0x3170, - mieumparenkorean: 0x3204, - mieumpieupkorean: 0x316E, - mieumsioskorean: 0x316F, - mihiragana: 0x307F, - mikatakana: 0x30DF, - mikatakanahalfwidth: 0xFF90, - minus: 0x2212, - minusbelowcmb: 0x0320, - minuscircle: 0x2296, - minusmod: 0x02D7, - minusplus: 0x2213, - minute: 0x2032, - miribaarusquare: 0x334A, - mirisquare: 0x3349, - mlonglegturned: 0x0270, - mlsquare: 0x3396, - mmcubedsquare: 0x33A3, - mmonospace: 0xFF4D, - mmsquaredsquare: 0x339F, - mohiragana: 0x3082, - mohmsquare: 0x33C1, - mokatakana: 0x30E2, - mokatakanahalfwidth: 0xFF93, - molsquare: 0x33D6, - momathai: 0x0E21, - moverssquare: 0x33A7, - moverssquaredsquare: 0x33A8, - mparen: 0x24A8, - mpasquare: 0x33AB, - mssquare: 0x33B3, - msuperior: 0xF6EF, - mturned: 0x026F, - mu: 0x00B5, - mu1: 0x00B5, - muasquare: 0x3382, - muchgreater: 0x226B, - muchless: 0x226A, - mufsquare: 0x338C, - mugreek: 0x03BC, - mugsquare: 0x338D, - muhiragana: 0x3080, - mukatakana: 0x30E0, - mukatakanahalfwidth: 0xFF91, - mulsquare: 0x3395, - multiply: 0x00D7, - mumsquare: 0x339B, - munahhebrew: 0x05A3, - munahlefthebrew: 0x05A3, - musicalnote: 0x266A, - musicalnotedbl: 0x266B, - musicflatsign: 0x266D, - musicsharpsign: 0x266F, - mussquare: 0x33B2, - muvsquare: 0x33B6, - muwsquare: 0x33BC, - mvmegasquare: 0x33B9, - mvsquare: 0x33B7, - mwmegasquare: 0x33BF, - mwsquare: 0x33BD, - n: 0x006E, - nabengali: 0x09A8, - nabla: 0x2207, - nacute: 0x0144, - nadeva: 0x0928, - nagujarati: 0x0AA8, - nagurmukhi: 0x0A28, - nahiragana: 0x306A, - nakatakana: 0x30CA, - nakatakanahalfwidth: 0xFF85, - napostrophe: 0x0149, - nasquare: 0x3381, - nbopomofo: 0x310B, - nbspace: 0x00A0, - ncaron: 0x0148, - ncedilla: 0x0146, - ncircle: 0x24DD, - ncircumflexbelow: 0x1E4B, - ncommaaccent: 0x0146, - ndotaccent: 0x1E45, - ndotbelow: 0x1E47, - nehiragana: 0x306D, - nekatakana: 0x30CD, - nekatakanahalfwidth: 0xFF88, - newsheqelsign: 0x20AA, - nfsquare: 0x338B, - ngabengali: 0x0999, - ngadeva: 0x0919, - ngagujarati: 0x0A99, - ngagurmukhi: 0x0A19, - ngonguthai: 0x0E07, - nhiragana: 0x3093, - nhookleft: 0x0272, - nhookretroflex: 0x0273, - nieunacirclekorean: 0x326F, - nieunaparenkorean: 0x320F, - nieuncieuckorean: 0x3135, - nieuncirclekorean: 0x3261, - nieunhieuhkorean: 0x3136, - nieunkorean: 0x3134, - nieunpansioskorean: 0x3168, - nieunparenkorean: 0x3201, - nieunsioskorean: 0x3167, - nieuntikeutkorean: 0x3166, - nihiragana: 0x306B, - nikatakana: 0x30CB, - nikatakanahalfwidth: 0xFF86, - nikhahitleftthai: 0xF899, - nikhahitthai: 0x0E4D, - nine: 0x0039, - ninearabic: 0x0669, - ninebengali: 0x09EF, - ninecircle: 0x2468, - ninecircleinversesansserif: 0x2792, - ninedeva: 0x096F, - ninegujarati: 0x0AEF, - ninegurmukhi: 0x0A6F, - ninehackarabic: 0x0669, - ninehangzhou: 0x3029, - nineideographicparen: 0x3228, - nineinferior: 0x2089, - ninemonospace: 0xFF19, - nineoldstyle: 0xF739, - nineparen: 0x247C, - nineperiod: 0x2490, - ninepersian: 0x06F9, - nineroman: 0x2178, - ninesuperior: 0x2079, - nineteencircle: 0x2472, - nineteenparen: 0x2486, - nineteenperiod: 0x249A, - ninethai: 0x0E59, - nj: 0x01CC, - njecyrillic: 0x045A, - nkatakana: 0x30F3, - nkatakanahalfwidth: 0xFF9D, - nlegrightlong: 0x019E, - nlinebelow: 0x1E49, - nmonospace: 0xFF4E, - nmsquare: 0x339A, - nnabengali: 0x09A3, - nnadeva: 0x0923, - nnagujarati: 0x0AA3, - nnagurmukhi: 0x0A23, - nnnadeva: 0x0929, - nohiragana: 0x306E, - nokatakana: 0x30CE, - nokatakanahalfwidth: 0xFF89, - nonbreakingspace: 0x00A0, - nonenthai: 0x0E13, - nonuthai: 0x0E19, - noonarabic: 0x0646, - noonfinalarabic: 0xFEE6, - noonghunnaarabic: 0x06BA, - noonghunnafinalarabic: 0xFB9F, - nooninitialarabic: 0xFEE7, - noonjeeminitialarabic: 0xFCD2, - noonjeemisolatedarabic: 0xFC4B, - noonmedialarabic: 0xFEE8, - noonmeeminitialarabic: 0xFCD5, - noonmeemisolatedarabic: 0xFC4E, - noonnoonfinalarabic: 0xFC8D, - notcontains: 0x220C, - notelement: 0x2209, - notelementof: 0x2209, - notequal: 0x2260, - notgreater: 0x226F, - notgreaternorequal: 0x2271, - notgreaternorless: 0x2279, - notidentical: 0x2262, - notless: 0x226E, - notlessnorequal: 0x2270, - notparallel: 0x2226, - notprecedes: 0x2280, - notsubset: 0x2284, - notsucceeds: 0x2281, - notsuperset: 0x2285, - nowarmenian: 0x0576, - nparen: 0x24A9, - nssquare: 0x33B1, - nsuperior: 0x207F, - ntilde: 0x00F1, - nu: 0x03BD, - nuhiragana: 0x306C, - nukatakana: 0x30CC, - nukatakanahalfwidth: 0xFF87, - nuktabengali: 0x09BC, - nuktadeva: 0x093C, - nuktagujarati: 0x0ABC, - nuktagurmukhi: 0x0A3C, - numbersign: 0x0023, - numbersignmonospace: 0xFF03, - numbersignsmall: 0xFE5F, - numeralsigngreek: 0x0374, - numeralsignlowergreek: 0x0375, - numero: 0x2116, - nun: 0x05E0, - nundagesh: 0xFB40, - nundageshhebrew: 0xFB40, - nunhebrew: 0x05E0, - nvsquare: 0x33B5, - nwsquare: 0x33BB, - nyabengali: 0x099E, - nyadeva: 0x091E, - nyagujarati: 0x0A9E, - nyagurmukhi: 0x0A1E, - o: 0x006F, - oacute: 0x00F3, - oangthai: 0x0E2D, - obarred: 0x0275, - obarredcyrillic: 0x04E9, - obarreddieresiscyrillic: 0x04EB, - obengali: 0x0993, - obopomofo: 0x311B, - obreve: 0x014F, - ocandradeva: 0x0911, - ocandragujarati: 0x0A91, - ocandravowelsigndeva: 0x0949, - ocandravowelsigngujarati: 0x0AC9, - ocaron: 0x01D2, - ocircle: 0x24DE, - ocircumflex: 0x00F4, - ocircumflexacute: 0x1ED1, - ocircumflexdotbelow: 0x1ED9, - ocircumflexgrave: 0x1ED3, - ocircumflexhookabove: 0x1ED5, - ocircumflextilde: 0x1ED7, - ocyrillic: 0x043E, - odblacute: 0x0151, - odblgrave: 0x020D, - odeva: 0x0913, - odieresis: 0x00F6, - odieresiscyrillic: 0x04E7, - odotbelow: 0x1ECD, - oe: 0x0153, - oekorean: 0x315A, - ogonek: 0x02DB, - ogonekcmb: 0x0328, - ograve: 0x00F2, - ogujarati: 0x0A93, - oharmenian: 0x0585, - ohiragana: 0x304A, - ohookabove: 0x1ECF, - ohorn: 0x01A1, - ohornacute: 0x1EDB, - ohorndotbelow: 0x1EE3, - ohorngrave: 0x1EDD, - ohornhookabove: 0x1EDF, - ohorntilde: 0x1EE1, - ohungarumlaut: 0x0151, - oi: 0x01A3, - oinvertedbreve: 0x020F, - okatakana: 0x30AA, - okatakanahalfwidth: 0xFF75, - okorean: 0x3157, - olehebrew: 0x05AB, - omacron: 0x014D, - omacronacute: 0x1E53, - omacrongrave: 0x1E51, - omdeva: 0x0950, - omega: 0x03C9, - omega1: 0x03D6, - omegacyrillic: 0x0461, - omegalatinclosed: 0x0277, - omegaroundcyrillic: 0x047B, - omegatitlocyrillic: 0x047D, - omegatonos: 0x03CE, - omgujarati: 0x0AD0, - omicron: 0x03BF, - omicrontonos: 0x03CC, - omonospace: 0xFF4F, - one: 0x0031, - onearabic: 0x0661, - onebengali: 0x09E7, - onecircle: 0x2460, - onecircleinversesansserif: 0x278A, - onedeva: 0x0967, - onedotenleader: 0x2024, - oneeighth: 0x215B, - onefitted: 0xF6DC, - onegujarati: 0x0AE7, - onegurmukhi: 0x0A67, - onehackarabic: 0x0661, - onehalf: 0x00BD, - onehangzhou: 0x3021, - oneideographicparen: 0x3220, - oneinferior: 0x2081, - onemonospace: 0xFF11, - onenumeratorbengali: 0x09F4, - oneoldstyle: 0xF731, - oneparen: 0x2474, - oneperiod: 0x2488, - onepersian: 0x06F1, - onequarter: 0x00BC, - oneroman: 0x2170, - onesuperior: 0x00B9, - onethai: 0x0E51, - onethird: 0x2153, - oogonek: 0x01EB, - oogonekmacron: 0x01ED, - oogurmukhi: 0x0A13, - oomatragurmukhi: 0x0A4B, - oopen: 0x0254, - oparen: 0x24AA, - openbullet: 0x25E6, - option: 0x2325, - ordfeminine: 0x00AA, - ordmasculine: 0x00BA, - orthogonal: 0x221F, - oshortdeva: 0x0912, - oshortvowelsigndeva: 0x094A, - oslash: 0x00F8, - oslashacute: 0x01FF, - osmallhiragana: 0x3049, - osmallkatakana: 0x30A9, - osmallkatakanahalfwidth: 0xFF6B, - ostrokeacute: 0x01FF, - osuperior: 0xF6F0, - otcyrillic: 0x047F, - otilde: 0x00F5, - otildeacute: 0x1E4D, - otildedieresis: 0x1E4F, - oubopomofo: 0x3121, - overline: 0x203E, - overlinecenterline: 0xFE4A, - overlinecmb: 0x0305, - overlinedashed: 0xFE49, - overlinedblwavy: 0xFE4C, - overlinewavy: 0xFE4B, - overscore: 0x00AF, - ovowelsignbengali: 0x09CB, - ovowelsigndeva: 0x094B, - ovowelsigngujarati: 0x0ACB, - p: 0x0070, - paampssquare: 0x3380, - paasentosquare: 0x332B, - pabengali: 0x09AA, - pacute: 0x1E55, - padeva: 0x092A, - pagedown: 0x21DF, - pageup: 0x21DE, - pagujarati: 0x0AAA, - pagurmukhi: 0x0A2A, - pahiragana: 0x3071, - paiyannoithai: 0x0E2F, - pakatakana: 0x30D1, - palatalizationcyrilliccmb: 0x0484, - palochkacyrillic: 0x04C0, - pansioskorean: 0x317F, - paragraph: 0x00B6, - parallel: 0x2225, - parenleft: 0x0028, - parenleftaltonearabic: 0xFD3E, - parenleftbt: 0xF8ED, - parenleftex: 0xF8EC, - parenleftinferior: 0x208D, - parenleftmonospace: 0xFF08, - parenleftsmall: 0xFE59, - parenleftsuperior: 0x207D, - parenlefttp: 0xF8EB, - parenleftvertical: 0xFE35, - parenright: 0x0029, - parenrightaltonearabic: 0xFD3F, - parenrightbt: 0xF8F8, - parenrightex: 0xF8F7, - parenrightinferior: 0x208E, - parenrightmonospace: 0xFF09, - parenrightsmall: 0xFE5A, - parenrightsuperior: 0x207E, - parenrighttp: 0xF8F6, - parenrightvertical: 0xFE36, - partialdiff: 0x2202, - paseqhebrew: 0x05C0, - pashtahebrew: 0x0599, - pasquare: 0x33A9, - patah: 0x05B7, - patah11: 0x05B7, - patah1d: 0x05B7, - patah2a: 0x05B7, - patahhebrew: 0x05B7, - patahnarrowhebrew: 0x05B7, - patahquarterhebrew: 0x05B7, - patahwidehebrew: 0x05B7, - pazerhebrew: 0x05A1, - pbopomofo: 0x3106, - pcircle: 0x24DF, - pdotaccent: 0x1E57, - pe: 0x05E4, - pecyrillic: 0x043F, - pedagesh: 0xFB44, - pedageshhebrew: 0xFB44, - peezisquare: 0x333B, - pefinaldageshhebrew: 0xFB43, - peharabic: 0x067E, - peharmenian: 0x057A, - pehebrew: 0x05E4, - pehfinalarabic: 0xFB57, - pehinitialarabic: 0xFB58, - pehiragana: 0x307A, - pehmedialarabic: 0xFB59, - pekatakana: 0x30DA, - pemiddlehookcyrillic: 0x04A7, - perafehebrew: 0xFB4E, - percent: 0x0025, - percentarabic: 0x066A, - percentmonospace: 0xFF05, - percentsmall: 0xFE6A, - period: 0x002E, - periodarmenian: 0x0589, - periodcentered: 0x00B7, - periodhalfwidth: 0xFF61, - periodinferior: 0xF6E7, - periodmonospace: 0xFF0E, - periodsmall: 0xFE52, - periodsuperior: 0xF6E8, - perispomenigreekcmb: 0x0342, - perpendicular: 0x22A5, - perthousand: 0x2030, - peseta: 0x20A7, - pfsquare: 0x338A, - phabengali: 0x09AB, - phadeva: 0x092B, - phagujarati: 0x0AAB, - phagurmukhi: 0x0A2B, - phi: 0x03C6, - phi1: 0x03D5, - phieuphacirclekorean: 0x327A, - phieuphaparenkorean: 0x321A, - phieuphcirclekorean: 0x326C, - phieuphkorean: 0x314D, - phieuphparenkorean: 0x320C, - philatin: 0x0278, - phinthuthai: 0x0E3A, - phisymbolgreek: 0x03D5, - phook: 0x01A5, - phophanthai: 0x0E1E, - phophungthai: 0x0E1C, - phosamphaothai: 0x0E20, - pi: 0x03C0, - pieupacirclekorean: 0x3273, - pieupaparenkorean: 0x3213, - pieupcieuckorean: 0x3176, - pieupcirclekorean: 0x3265, - pieupkiyeokkorean: 0x3172, - pieupkorean: 0x3142, - pieupparenkorean: 0x3205, - pieupsioskiyeokkorean: 0x3174, - pieupsioskorean: 0x3144, - pieupsiostikeutkorean: 0x3175, - pieupthieuthkorean: 0x3177, - pieuptikeutkorean: 0x3173, - pihiragana: 0x3074, - pikatakana: 0x30D4, - pisymbolgreek: 0x03D6, - piwrarmenian: 0x0583, - plus: 0x002B, - plusbelowcmb: 0x031F, - pluscircle: 0x2295, - plusminus: 0x00B1, - plusmod: 0x02D6, - plusmonospace: 0xFF0B, - plussmall: 0xFE62, - plussuperior: 0x207A, - pmonospace: 0xFF50, - pmsquare: 0x33D8, - pohiragana: 0x307D, - pointingindexdownwhite: 0x261F, - pointingindexleftwhite: 0x261C, - pointingindexrightwhite: 0x261E, - pointingindexupwhite: 0x261D, - pokatakana: 0x30DD, - poplathai: 0x0E1B, - postalmark: 0x3012, - postalmarkface: 0x3020, - pparen: 0x24AB, - precedes: 0x227A, - prescription: 0x211E, - primemod: 0x02B9, - primereversed: 0x2035, - product: 0x220F, - projective: 0x2305, - prolongedkana: 0x30FC, - propellor: 0x2318, - propersubset: 0x2282, - propersuperset: 0x2283, - proportion: 0x2237, - proportional: 0x221D, - psi: 0x03C8, - psicyrillic: 0x0471, - psilipneumatacyrilliccmb: 0x0486, - pssquare: 0x33B0, - puhiragana: 0x3077, - pukatakana: 0x30D7, - pvsquare: 0x33B4, - pwsquare: 0x33BA, - q: 0x0071, - qadeva: 0x0958, - qadmahebrew: 0x05A8, - qafarabic: 0x0642, - qaffinalarabic: 0xFED6, - qafinitialarabic: 0xFED7, - qafmedialarabic: 0xFED8, - qamats: 0x05B8, - qamats10: 0x05B8, - qamats1a: 0x05B8, - qamats1c: 0x05B8, - qamats27: 0x05B8, - qamats29: 0x05B8, - qamats33: 0x05B8, - qamatsde: 0x05B8, - qamatshebrew: 0x05B8, - qamatsnarrowhebrew: 0x05B8, - qamatsqatanhebrew: 0x05B8, - qamatsqatannarrowhebrew: 0x05B8, - qamatsqatanquarterhebrew: 0x05B8, - qamatsqatanwidehebrew: 0x05B8, - qamatsquarterhebrew: 0x05B8, - qamatswidehebrew: 0x05B8, - qarneyparahebrew: 0x059F, - qbopomofo: 0x3111, - qcircle: 0x24E0, - qhook: 0x02A0, - qmonospace: 0xFF51, - qof: 0x05E7, - qofdagesh: 0xFB47, - qofdageshhebrew: 0xFB47, - qofhebrew: 0x05E7, - qparen: 0x24AC, - quarternote: 0x2669, - qubuts: 0x05BB, - qubuts18: 0x05BB, - qubuts25: 0x05BB, - qubuts31: 0x05BB, - qubutshebrew: 0x05BB, - qubutsnarrowhebrew: 0x05BB, - qubutsquarterhebrew: 0x05BB, - qubutswidehebrew: 0x05BB, - question: 0x003F, - questionarabic: 0x061F, - questionarmenian: 0x055E, - questiondown: 0x00BF, - questiondownsmall: 0xF7BF, - questiongreek: 0x037E, - questionmonospace: 0xFF1F, - questionsmall: 0xF73F, - quotedbl: 0x0022, - quotedblbase: 0x201E, - quotedblleft: 0x201C, - quotedblmonospace: 0xFF02, - quotedblprime: 0x301E, - quotedblprimereversed: 0x301D, - quotedblright: 0x201D, - quoteleft: 0x2018, - quoteleftreversed: 0x201B, - quotereversed: 0x201B, - quoteright: 0x2019, - quoterightn: 0x0149, - quotesinglbase: 0x201A, - quotesingle: 0x0027, - quotesinglemonospace: 0xFF07, - r: 0x0072, - raarmenian: 0x057C, - rabengali: 0x09B0, - racute: 0x0155, - radeva: 0x0930, - radical: 0x221A, - radicalex: 0xF8E5, - radoverssquare: 0x33AE, - radoverssquaredsquare: 0x33AF, - radsquare: 0x33AD, - rafe: 0x05BF, - rafehebrew: 0x05BF, - ragujarati: 0x0AB0, - ragurmukhi: 0x0A30, - rahiragana: 0x3089, - rakatakana: 0x30E9, - rakatakanahalfwidth: 0xFF97, - ralowerdiagonalbengali: 0x09F1, - ramiddlediagonalbengali: 0x09F0, - ramshorn: 0x0264, - ratio: 0x2236, - rbopomofo: 0x3116, - rcaron: 0x0159, - rcedilla: 0x0157, - rcircle: 0x24E1, - rcommaaccent: 0x0157, - rdblgrave: 0x0211, - rdotaccent: 0x1E59, - rdotbelow: 0x1E5B, - rdotbelowmacron: 0x1E5D, - referencemark: 0x203B, - reflexsubset: 0x2286, - reflexsuperset: 0x2287, - registered: 0x00AE, - registersans: 0xF8E8, - registerserif: 0xF6DA, - reharabic: 0x0631, - reharmenian: 0x0580, - rehfinalarabic: 0xFEAE, - rehiragana: 0x308C, - rekatakana: 0x30EC, - rekatakanahalfwidth: 0xFF9A, - resh: 0x05E8, - reshdageshhebrew: 0xFB48, - reshhebrew: 0x05E8, - reversedtilde: 0x223D, - reviahebrew: 0x0597, - reviamugrashhebrew: 0x0597, - revlogicalnot: 0x2310, - rfishhook: 0x027E, - rfishhookreversed: 0x027F, - rhabengali: 0x09DD, - rhadeva: 0x095D, - rho: 0x03C1, - rhook: 0x027D, - rhookturned: 0x027B, - rhookturnedsuperior: 0x02B5, - rhosymbolgreek: 0x03F1, - rhotichookmod: 0x02DE, - rieulacirclekorean: 0x3271, - rieulaparenkorean: 0x3211, - rieulcirclekorean: 0x3263, - rieulhieuhkorean: 0x3140, - rieulkiyeokkorean: 0x313A, - rieulkiyeoksioskorean: 0x3169, - rieulkorean: 0x3139, - rieulmieumkorean: 0x313B, - rieulpansioskorean: 0x316C, - rieulparenkorean: 0x3203, - rieulphieuphkorean: 0x313F, - rieulpieupkorean: 0x313C, - rieulpieupsioskorean: 0x316B, - rieulsioskorean: 0x313D, - rieulthieuthkorean: 0x313E, - rieultikeutkorean: 0x316A, - rieulyeorinhieuhkorean: 0x316D, - rightangle: 0x221F, - righttackbelowcmb: 0x0319, - righttriangle: 0x22BF, - rihiragana: 0x308A, - rikatakana: 0x30EA, - rikatakanahalfwidth: 0xFF98, - ring: 0x02DA, - ringbelowcmb: 0x0325, - ringcmb: 0x030A, - ringhalfleft: 0x02BF, - ringhalfleftarmenian: 0x0559, - ringhalfleftbelowcmb: 0x031C, - ringhalfleftcentered: 0x02D3, - ringhalfright: 0x02BE, - ringhalfrightbelowcmb: 0x0339, - ringhalfrightcentered: 0x02D2, - rinvertedbreve: 0x0213, - rittorusquare: 0x3351, - rlinebelow: 0x1E5F, - rlongleg: 0x027C, - rlonglegturned: 0x027A, - rmonospace: 0xFF52, - rohiragana: 0x308D, - rokatakana: 0x30ED, - rokatakanahalfwidth: 0xFF9B, - roruathai: 0x0E23, - rparen: 0x24AD, - rrabengali: 0x09DC, - rradeva: 0x0931, - rragurmukhi: 0x0A5C, - rreharabic: 0x0691, - rrehfinalarabic: 0xFB8D, - rrvocalicbengali: 0x09E0, - rrvocalicdeva: 0x0960, - rrvocalicgujarati: 0x0AE0, - rrvocalicvowelsignbengali: 0x09C4, - rrvocalicvowelsigndeva: 0x0944, - rrvocalicvowelsigngujarati: 0x0AC4, - rsuperior: 0xF6F1, - rtblock: 0x2590, - rturned: 0x0279, - rturnedsuperior: 0x02B4, - ruhiragana: 0x308B, - rukatakana: 0x30EB, - rukatakanahalfwidth: 0xFF99, - rupeemarkbengali: 0x09F2, - rupeesignbengali: 0x09F3, - rupiah: 0xF6DD, - ruthai: 0x0E24, - rvocalicbengali: 0x098B, - rvocalicdeva: 0x090B, - rvocalicgujarati: 0x0A8B, - rvocalicvowelsignbengali: 0x09C3, - rvocalicvowelsigndeva: 0x0943, - rvocalicvowelsigngujarati: 0x0AC3, - s: 0x0073, - sabengali: 0x09B8, - sacute: 0x015B, - sacutedotaccent: 0x1E65, - sadarabic: 0x0635, - sadeva: 0x0938, - sadfinalarabic: 0xFEBA, - sadinitialarabic: 0xFEBB, - sadmedialarabic: 0xFEBC, - sagujarati: 0x0AB8, - sagurmukhi: 0x0A38, - sahiragana: 0x3055, - sakatakana: 0x30B5, - sakatakanahalfwidth: 0xFF7B, - sallallahoualayhewasallamarabic: 0xFDFA, - samekh: 0x05E1, - samekhdagesh: 0xFB41, - samekhdageshhebrew: 0xFB41, - samekhhebrew: 0x05E1, - saraaathai: 0x0E32, - saraaethai: 0x0E41, - saraaimaimalaithai: 0x0E44, - saraaimaimuanthai: 0x0E43, - saraamthai: 0x0E33, - saraathai: 0x0E30, - saraethai: 0x0E40, - saraiileftthai: 0xF886, - saraiithai: 0x0E35, - saraileftthai: 0xF885, - saraithai: 0x0E34, - saraothai: 0x0E42, - saraueeleftthai: 0xF888, - saraueethai: 0x0E37, - saraueleftthai: 0xF887, - sarauethai: 0x0E36, - sarauthai: 0x0E38, - sarauuthai: 0x0E39, - sbopomofo: 0x3119, - scaron: 0x0161, - scarondotaccent: 0x1E67, - scedilla: 0x015F, - schwa: 0x0259, - schwacyrillic: 0x04D9, - schwadieresiscyrillic: 0x04DB, - schwahook: 0x025A, - scircle: 0x24E2, - scircumflex: 0x015D, - scommaaccent: 0x0219, - sdotaccent: 0x1E61, - sdotbelow: 0x1E63, - sdotbelowdotaccent: 0x1E69, - seagullbelowcmb: 0x033C, - second: 0x2033, - secondtonechinese: 0x02CA, - section: 0x00A7, - seenarabic: 0x0633, - seenfinalarabic: 0xFEB2, - seeninitialarabic: 0xFEB3, - seenmedialarabic: 0xFEB4, - segol: 0x05B6, - segol13: 0x05B6, - segol1f: 0x05B6, - segol2c: 0x05B6, - segolhebrew: 0x05B6, - segolnarrowhebrew: 0x05B6, - segolquarterhebrew: 0x05B6, - segoltahebrew: 0x0592, - segolwidehebrew: 0x05B6, - seharmenian: 0x057D, - sehiragana: 0x305B, - sekatakana: 0x30BB, - sekatakanahalfwidth: 0xFF7E, - semicolon: 0x003B, - semicolonarabic: 0x061B, - semicolonmonospace: 0xFF1B, - semicolonsmall: 0xFE54, - semivoicedmarkkana: 0x309C, - semivoicedmarkkanahalfwidth: 0xFF9F, - sentisquare: 0x3322, - sentosquare: 0x3323, - seven: 0x0037, - sevenarabic: 0x0667, - sevenbengali: 0x09ED, - sevencircle: 0x2466, - sevencircleinversesansserif: 0x2790, - sevendeva: 0x096D, - seveneighths: 0x215E, - sevengujarati: 0x0AED, - sevengurmukhi: 0x0A6D, - sevenhackarabic: 0x0667, - sevenhangzhou: 0x3027, - sevenideographicparen: 0x3226, - seveninferior: 0x2087, - sevenmonospace: 0xFF17, - sevenoldstyle: 0xF737, - sevenparen: 0x247A, - sevenperiod: 0x248E, - sevenpersian: 0x06F7, - sevenroman: 0x2176, - sevensuperior: 0x2077, - seventeencircle: 0x2470, - seventeenparen: 0x2484, - seventeenperiod: 0x2498, - seventhai: 0x0E57, - sfthyphen: 0x00AD, - shaarmenian: 0x0577, - shabengali: 0x09B6, - shacyrillic: 0x0448, - shaddaarabic: 0x0651, - shaddadammaarabic: 0xFC61, - shaddadammatanarabic: 0xFC5E, - shaddafathaarabic: 0xFC60, - shaddakasraarabic: 0xFC62, - shaddakasratanarabic: 0xFC5F, - shade: 0x2592, - shadedark: 0x2593, - shadelight: 0x2591, - shademedium: 0x2592, - shadeva: 0x0936, - shagujarati: 0x0AB6, - shagurmukhi: 0x0A36, - shalshelethebrew: 0x0593, - shbopomofo: 0x3115, - shchacyrillic: 0x0449, - sheenarabic: 0x0634, - sheenfinalarabic: 0xFEB6, - sheeninitialarabic: 0xFEB7, - sheenmedialarabic: 0xFEB8, - sheicoptic: 0x03E3, - sheqel: 0x20AA, - sheqelhebrew: 0x20AA, - sheva: 0x05B0, - sheva115: 0x05B0, - sheva15: 0x05B0, - sheva22: 0x05B0, - sheva2e: 0x05B0, - shevahebrew: 0x05B0, - shevanarrowhebrew: 0x05B0, - shevaquarterhebrew: 0x05B0, - shevawidehebrew: 0x05B0, - shhacyrillic: 0x04BB, - shimacoptic: 0x03ED, - shin: 0x05E9, - shindagesh: 0xFB49, - shindageshhebrew: 0xFB49, - shindageshshindot: 0xFB2C, - shindageshshindothebrew: 0xFB2C, - shindageshsindot: 0xFB2D, - shindageshsindothebrew: 0xFB2D, - shindothebrew: 0x05C1, - shinhebrew: 0x05E9, - shinshindot: 0xFB2A, - shinshindothebrew: 0xFB2A, - shinsindot: 0xFB2B, - shinsindothebrew: 0xFB2B, - shook: 0x0282, - sigma: 0x03C3, - sigma1: 0x03C2, - sigmafinal: 0x03C2, - sigmalunatesymbolgreek: 0x03F2, - sihiragana: 0x3057, - sikatakana: 0x30B7, - sikatakanahalfwidth: 0xFF7C, - siluqhebrew: 0x05BD, - siluqlefthebrew: 0x05BD, - similar: 0x223C, - sindothebrew: 0x05C2, - siosacirclekorean: 0x3274, - siosaparenkorean: 0x3214, - sioscieuckorean: 0x317E, - sioscirclekorean: 0x3266, - sioskiyeokkorean: 0x317A, - sioskorean: 0x3145, - siosnieunkorean: 0x317B, - siosparenkorean: 0x3206, - siospieupkorean: 0x317D, - siostikeutkorean: 0x317C, - six: 0x0036, - sixarabic: 0x0666, - sixbengali: 0x09EC, - sixcircle: 0x2465, - sixcircleinversesansserif: 0x278F, - sixdeva: 0x096C, - sixgujarati: 0x0AEC, - sixgurmukhi: 0x0A6C, - sixhackarabic: 0x0666, - sixhangzhou: 0x3026, - sixideographicparen: 0x3225, - sixinferior: 0x2086, - sixmonospace: 0xFF16, - sixoldstyle: 0xF736, - sixparen: 0x2479, - sixperiod: 0x248D, - sixpersian: 0x06F6, - sixroman: 0x2175, - sixsuperior: 0x2076, - sixteencircle: 0x246F, - sixteencurrencydenominatorbengali: 0x09F9, - sixteenparen: 0x2483, - sixteenperiod: 0x2497, - sixthai: 0x0E56, - slash: 0x002F, - slashmonospace: 0xFF0F, - slong: 0x017F, - slongdotaccent: 0x1E9B, - smileface: 0x263A, - smonospace: 0xFF53, - sofpasuqhebrew: 0x05C3, - softhyphen: 0x00AD, - softsigncyrillic: 0x044C, - sohiragana: 0x305D, - sokatakana: 0x30BD, - sokatakanahalfwidth: 0xFF7F, - soliduslongoverlaycmb: 0x0338, - solidusshortoverlaycmb: 0x0337, - sorusithai: 0x0E29, - sosalathai: 0x0E28, - sosothai: 0x0E0B, - sosuathai: 0x0E2A, - space: 0x0020, - spacehackarabic: 0x0020, - spade: 0x2660, - spadesuitblack: 0x2660, - spadesuitwhite: 0x2664, - sparen: 0x24AE, - squarebelowcmb: 0x033B, - squarecc: 0x33C4, - squarecm: 0x339D, - squarediagonalcrosshatchfill: 0x25A9, - squarehorizontalfill: 0x25A4, - squarekg: 0x338F, - squarekm: 0x339E, - squarekmcapital: 0x33CE, - squareln: 0x33D1, - squarelog: 0x33D2, - squaremg: 0x338E, - squaremil: 0x33D5, - squaremm: 0x339C, - squaremsquared: 0x33A1, - squareorthogonalcrosshatchfill: 0x25A6, - squareupperlefttolowerrightfill: 0x25A7, - squareupperrighttolowerleftfill: 0x25A8, - squareverticalfill: 0x25A5, - squarewhitewithsmallblack: 0x25A3, - srsquare: 0x33DB, - ssabengali: 0x09B7, - ssadeva: 0x0937, - ssagujarati: 0x0AB7, - ssangcieuckorean: 0x3149, - ssanghieuhkorean: 0x3185, - ssangieungkorean: 0x3180, - ssangkiyeokkorean: 0x3132, - ssangnieunkorean: 0x3165, - ssangpieupkorean: 0x3143, - ssangsioskorean: 0x3146, - ssangtikeutkorean: 0x3138, - ssuperior: 0xF6F2, - sterling: 0x00A3, - sterlingmonospace: 0xFFE1, - strokelongoverlaycmb: 0x0336, - strokeshortoverlaycmb: 0x0335, - subset: 0x2282, - subsetnotequal: 0x228A, - subsetorequal: 0x2286, - succeeds: 0x227B, - suchthat: 0x220B, - suhiragana: 0x3059, - sukatakana: 0x30B9, - sukatakanahalfwidth: 0xFF7D, - sukunarabic: 0x0652, - summation: 0x2211, - sun: 0x263C, - superset: 0x2283, - supersetnotequal: 0x228B, - supersetorequal: 0x2287, - svsquare: 0x33DC, - syouwaerasquare: 0x337C, - t: 0x0074, - tabengali: 0x09A4, - tackdown: 0x22A4, - tackleft: 0x22A3, - tadeva: 0x0924, - tagujarati: 0x0AA4, - tagurmukhi: 0x0A24, - taharabic: 0x0637, - tahfinalarabic: 0xFEC2, - tahinitialarabic: 0xFEC3, - tahiragana: 0x305F, - tahmedialarabic: 0xFEC4, - taisyouerasquare: 0x337D, - takatakana: 0x30BF, - takatakanahalfwidth: 0xFF80, - tatweelarabic: 0x0640, - tau: 0x03C4, - tav: 0x05EA, - tavdages: 0xFB4A, - tavdagesh: 0xFB4A, - tavdageshhebrew: 0xFB4A, - tavhebrew: 0x05EA, - tbar: 0x0167, - tbopomofo: 0x310A, - tcaron: 0x0165, - tccurl: 0x02A8, - tcedilla: 0x0163, - tcheharabic: 0x0686, - tchehfinalarabic: 0xFB7B, - tchehinitialarabic: 0xFB7C, - tchehmedialarabic: 0xFB7D, - tcircle: 0x24E3, - tcircumflexbelow: 0x1E71, - tcommaaccent: 0x0163, - tdieresis: 0x1E97, - tdotaccent: 0x1E6B, - tdotbelow: 0x1E6D, - tecyrillic: 0x0442, - tedescendercyrillic: 0x04AD, - teharabic: 0x062A, - tehfinalarabic: 0xFE96, - tehhahinitialarabic: 0xFCA2, - tehhahisolatedarabic: 0xFC0C, - tehinitialarabic: 0xFE97, - tehiragana: 0x3066, - tehjeeminitialarabic: 0xFCA1, - tehjeemisolatedarabic: 0xFC0B, - tehmarbutaarabic: 0x0629, - tehmarbutafinalarabic: 0xFE94, - tehmedialarabic: 0xFE98, - tehmeeminitialarabic: 0xFCA4, - tehmeemisolatedarabic: 0xFC0E, - tehnoonfinalarabic: 0xFC73, - tekatakana: 0x30C6, - tekatakanahalfwidth: 0xFF83, - telephone: 0x2121, - telephoneblack: 0x260E, - telishagedolahebrew: 0x05A0, - telishaqetanahebrew: 0x05A9, - tencircle: 0x2469, - tenideographicparen: 0x3229, - tenparen: 0x247D, - tenperiod: 0x2491, - tenroman: 0x2179, - tesh: 0x02A7, - tet: 0x05D8, - tetdagesh: 0xFB38, - tetdageshhebrew: 0xFB38, - tethebrew: 0x05D8, - tetsecyrillic: 0x04B5, - tevirhebrew: 0x059B, - tevirlefthebrew: 0x059B, - thabengali: 0x09A5, - thadeva: 0x0925, - thagujarati: 0x0AA5, - thagurmukhi: 0x0A25, - thalarabic: 0x0630, - thalfinalarabic: 0xFEAC, - thanthakhatlowleftthai: 0xF898, - thanthakhatlowrightthai: 0xF897, - thanthakhatthai: 0x0E4C, - thanthakhatupperleftthai: 0xF896, - theharabic: 0x062B, - thehfinalarabic: 0xFE9A, - thehinitialarabic: 0xFE9B, - thehmedialarabic: 0xFE9C, - thereexists: 0x2203, - therefore: 0x2234, - theta: 0x03B8, - theta1: 0x03D1, - thetasymbolgreek: 0x03D1, - thieuthacirclekorean: 0x3279, - thieuthaparenkorean: 0x3219, - thieuthcirclekorean: 0x326B, - thieuthkorean: 0x314C, - thieuthparenkorean: 0x320B, - thirteencircle: 0x246C, - thirteenparen: 0x2480, - thirteenperiod: 0x2494, - thonangmonthothai: 0x0E11, - thook: 0x01AD, - thophuthaothai: 0x0E12, - thorn: 0x00FE, - thothahanthai: 0x0E17, - thothanthai: 0x0E10, - thothongthai: 0x0E18, - thothungthai: 0x0E16, - thousandcyrillic: 0x0482, - thousandsseparatorarabic: 0x066C, - thousandsseparatorpersian: 0x066C, - three: 0x0033, - threearabic: 0x0663, - threebengali: 0x09E9, - threecircle: 0x2462, - threecircleinversesansserif: 0x278C, - threedeva: 0x0969, - threeeighths: 0x215C, - threegujarati: 0x0AE9, - threegurmukhi: 0x0A69, - threehackarabic: 0x0663, - threehangzhou: 0x3023, - threeideographicparen: 0x3222, - threeinferior: 0x2083, - threemonospace: 0xFF13, - threenumeratorbengali: 0x09F6, - threeoldstyle: 0xF733, - threeparen: 0x2476, - threeperiod: 0x248A, - threepersian: 0x06F3, - threequarters: 0x00BE, - threequartersemdash: 0xF6DE, - threeroman: 0x2172, - threesuperior: 0x00B3, - threethai: 0x0E53, - thzsquare: 0x3394, - tihiragana: 0x3061, - tikatakana: 0x30C1, - tikatakanahalfwidth: 0xFF81, - tikeutacirclekorean: 0x3270, - tikeutaparenkorean: 0x3210, - tikeutcirclekorean: 0x3262, - tikeutkorean: 0x3137, - tikeutparenkorean: 0x3202, - tilde: 0x02DC, - tildebelowcmb: 0x0330, - tildecmb: 0x0303, - tildecomb: 0x0303, - tildedoublecmb: 0x0360, - tildeoperator: 0x223C, - tildeoverlaycmb: 0x0334, - tildeverticalcmb: 0x033E, - timescircle: 0x2297, - tipehahebrew: 0x0596, - tipehalefthebrew: 0x0596, - tippigurmukhi: 0x0A70, - titlocyrilliccmb: 0x0483, - tiwnarmenian: 0x057F, - tlinebelow: 0x1E6F, - tmonospace: 0xFF54, - toarmenian: 0x0569, - tohiragana: 0x3068, - tokatakana: 0x30C8, - tokatakanahalfwidth: 0xFF84, - tonebarextrahighmod: 0x02E5, - tonebarextralowmod: 0x02E9, - tonebarhighmod: 0x02E6, - tonebarlowmod: 0x02E8, - tonebarmidmod: 0x02E7, - tonefive: 0x01BD, - tonesix: 0x0185, - tonetwo: 0x01A8, - tonos: 0x0384, - tonsquare: 0x3327, - topatakthai: 0x0E0F, - tortoiseshellbracketleft: 0x3014, - tortoiseshellbracketleftsmall: 0xFE5D, - tortoiseshellbracketleftvertical: 0xFE39, - tortoiseshellbracketright: 0x3015, - tortoiseshellbracketrightsmall: 0xFE5E, - tortoiseshellbracketrightvertical: 0xFE3A, - totaothai: 0x0E15, - tpalatalhook: 0x01AB, - tparen: 0x24AF, - trademark: 0x2122, - trademarksans: 0xF8EA, - trademarkserif: 0xF6DB, - tretroflexhook: 0x0288, - triagdn: 0x25BC, - triaglf: 0x25C4, - triagrt: 0x25BA, - triagup: 0x25B2, - ts: 0x02A6, - tsadi: 0x05E6, - tsadidagesh: 0xFB46, - tsadidageshhebrew: 0xFB46, - tsadihebrew: 0x05E6, - tsecyrillic: 0x0446, - tsere: 0x05B5, - tsere12: 0x05B5, - tsere1e: 0x05B5, - tsere2b: 0x05B5, - tserehebrew: 0x05B5, - tserenarrowhebrew: 0x05B5, - tserequarterhebrew: 0x05B5, - tserewidehebrew: 0x05B5, - tshecyrillic: 0x045B, - tsuperior: 0xF6F3, - ttabengali: 0x099F, - ttadeva: 0x091F, - ttagujarati: 0x0A9F, - ttagurmukhi: 0x0A1F, - tteharabic: 0x0679, - ttehfinalarabic: 0xFB67, - ttehinitialarabic: 0xFB68, - ttehmedialarabic: 0xFB69, - tthabengali: 0x09A0, - tthadeva: 0x0920, - tthagujarati: 0x0AA0, - tthagurmukhi: 0x0A20, - tturned: 0x0287, - tuhiragana: 0x3064, - tukatakana: 0x30C4, - tukatakanahalfwidth: 0xFF82, - tusmallhiragana: 0x3063, - tusmallkatakana: 0x30C3, - tusmallkatakanahalfwidth: 0xFF6F, - twelvecircle: 0x246B, - twelveparen: 0x247F, - twelveperiod: 0x2493, - twelveroman: 0x217B, - twentycircle: 0x2473, - twentyhangzhou: 0x5344, - twentyparen: 0x2487, - twentyperiod: 0x249B, - two: 0x0032, - twoarabic: 0x0662, - twobengali: 0x09E8, - twocircle: 0x2461, - twocircleinversesansserif: 0x278B, - twodeva: 0x0968, - twodotenleader: 0x2025, - twodotleader: 0x2025, - twodotleadervertical: 0xFE30, - twogujarati: 0x0AE8, - twogurmukhi: 0x0A68, - twohackarabic: 0x0662, - twohangzhou: 0x3022, - twoideographicparen: 0x3221, - twoinferior: 0x2082, - twomonospace: 0xFF12, - twonumeratorbengali: 0x09F5, - twooldstyle: 0xF732, - twoparen: 0x2475, - twoperiod: 0x2489, - twopersian: 0x06F2, - tworoman: 0x2171, - twostroke: 0x01BB, - twosuperior: 0x00B2, - twothai: 0x0E52, - twothirds: 0x2154, - u: 0x0075, - uacute: 0x00FA, - ubar: 0x0289, - ubengali: 0x0989, - ubopomofo: 0x3128, - ubreve: 0x016D, - ucaron: 0x01D4, - ucircle: 0x24E4, - ucircumflex: 0x00FB, - ucircumflexbelow: 0x1E77, - ucyrillic: 0x0443, - udattadeva: 0x0951, - udblacute: 0x0171, - udblgrave: 0x0215, - udeva: 0x0909, - udieresis: 0x00FC, - udieresisacute: 0x01D8, - udieresisbelow: 0x1E73, - udieresiscaron: 0x01DA, - udieresiscyrillic: 0x04F1, - udieresisgrave: 0x01DC, - udieresismacron: 0x01D6, - udotbelow: 0x1EE5, - ugrave: 0x00F9, - ugujarati: 0x0A89, - ugurmukhi: 0x0A09, - uhiragana: 0x3046, - uhookabove: 0x1EE7, - uhorn: 0x01B0, - uhornacute: 0x1EE9, - uhorndotbelow: 0x1EF1, - uhorngrave: 0x1EEB, - uhornhookabove: 0x1EED, - uhorntilde: 0x1EEF, - uhungarumlaut: 0x0171, - uhungarumlautcyrillic: 0x04F3, - uinvertedbreve: 0x0217, - ukatakana: 0x30A6, - ukatakanahalfwidth: 0xFF73, - ukcyrillic: 0x0479, - ukorean: 0x315C, - umacron: 0x016B, - umacroncyrillic: 0x04EF, - umacrondieresis: 0x1E7B, - umatragurmukhi: 0x0A41, - umonospace: 0xFF55, - underscore: 0x005F, - underscoredbl: 0x2017, - underscoremonospace: 0xFF3F, - underscorevertical: 0xFE33, - underscorewavy: 0xFE4F, - union: 0x222A, - universal: 0x2200, - uogonek: 0x0173, - uparen: 0x24B0, - upblock: 0x2580, - upperdothebrew: 0x05C4, - upsilon: 0x03C5, - upsilondieresis: 0x03CB, - upsilondieresistonos: 0x03B0, - upsilonlatin: 0x028A, - upsilontonos: 0x03CD, - uptackbelowcmb: 0x031D, - uptackmod: 0x02D4, - uragurmukhi: 0x0A73, - uring: 0x016F, - ushortcyrillic: 0x045E, - usmallhiragana: 0x3045, - usmallkatakana: 0x30A5, - usmallkatakanahalfwidth: 0xFF69, - ustraightcyrillic: 0x04AF, - ustraightstrokecyrillic: 0x04B1, - utilde: 0x0169, - utildeacute: 0x1E79, - utildebelow: 0x1E75, - uubengali: 0x098A, - uudeva: 0x090A, - uugujarati: 0x0A8A, - uugurmukhi: 0x0A0A, - uumatragurmukhi: 0x0A42, - uuvowelsignbengali: 0x09C2, - uuvowelsigndeva: 0x0942, - uuvowelsigngujarati: 0x0AC2, - uvowelsignbengali: 0x09C1, - uvowelsigndeva: 0x0941, - uvowelsigngujarati: 0x0AC1, - v: 0x0076, - vadeva: 0x0935, - vagujarati: 0x0AB5, - vagurmukhi: 0x0A35, - vakatakana: 0x30F7, - vav: 0x05D5, - vavdagesh: 0xFB35, - vavdagesh65: 0xFB35, - vavdageshhebrew: 0xFB35, - vavhebrew: 0x05D5, - vavholam: 0xFB4B, - vavholamhebrew: 0xFB4B, - vavvavhebrew: 0x05F0, - vavyodhebrew: 0x05F1, - vcircle: 0x24E5, - vdotbelow: 0x1E7F, - vecyrillic: 0x0432, - veharabic: 0x06A4, - vehfinalarabic: 0xFB6B, - vehinitialarabic: 0xFB6C, - vehmedialarabic: 0xFB6D, - vekatakana: 0x30F9, - venus: 0x2640, - verticalbar: 0x007C, - verticallineabovecmb: 0x030D, - verticallinebelowcmb: 0x0329, - verticallinelowmod: 0x02CC, - verticallinemod: 0x02C8, - vewarmenian: 0x057E, - vhook: 0x028B, - vikatakana: 0x30F8, - viramabengali: 0x09CD, - viramadeva: 0x094D, - viramagujarati: 0x0ACD, - visargabengali: 0x0983, - visargadeva: 0x0903, - visargagujarati: 0x0A83, - vmonospace: 0xFF56, - voarmenian: 0x0578, - voicediterationhiragana: 0x309E, - voicediterationkatakana: 0x30FE, - voicedmarkkana: 0x309B, - voicedmarkkanahalfwidth: 0xFF9E, - vokatakana: 0x30FA, - vparen: 0x24B1, - vtilde: 0x1E7D, - vturned: 0x028C, - vuhiragana: 0x3094, - vukatakana: 0x30F4, - w: 0x0077, - wacute: 0x1E83, - waekorean: 0x3159, - wahiragana: 0x308F, - wakatakana: 0x30EF, - wakatakanahalfwidth: 0xFF9C, - wakorean: 0x3158, - wasmallhiragana: 0x308E, - wasmallkatakana: 0x30EE, - wattosquare: 0x3357, - wavedash: 0x301C, - wavyunderscorevertical: 0xFE34, - wawarabic: 0x0648, - wawfinalarabic: 0xFEEE, - wawhamzaabovearabic: 0x0624, - wawhamzaabovefinalarabic: 0xFE86, - wbsquare: 0x33DD, - wcircle: 0x24E6, - wcircumflex: 0x0175, - wdieresis: 0x1E85, - wdotaccent: 0x1E87, - wdotbelow: 0x1E89, - wehiragana: 0x3091, - weierstrass: 0x2118, - wekatakana: 0x30F1, - wekorean: 0x315E, - weokorean: 0x315D, - wgrave: 0x1E81, - whitebullet: 0x25E6, - whitecircle: 0x25CB, - whitecircleinverse: 0x25D9, - whitecornerbracketleft: 0x300E, - whitecornerbracketleftvertical: 0xFE43, - whitecornerbracketright: 0x300F, - whitecornerbracketrightvertical: 0xFE44, - whitediamond: 0x25C7, - whitediamondcontainingblacksmalldiamond: 0x25C8, - whitedownpointingsmalltriangle: 0x25BF, - whitedownpointingtriangle: 0x25BD, - whiteleftpointingsmalltriangle: 0x25C3, - whiteleftpointingtriangle: 0x25C1, - whitelenticularbracketleft: 0x3016, - whitelenticularbracketright: 0x3017, - whiterightpointingsmalltriangle: 0x25B9, - whiterightpointingtriangle: 0x25B7, - whitesmallsquare: 0x25AB, - whitesmilingface: 0x263A, - whitesquare: 0x25A1, - whitestar: 0x2606, - whitetelephone: 0x260F, - whitetortoiseshellbracketleft: 0x3018, - whitetortoiseshellbracketright: 0x3019, - whiteuppointingsmalltriangle: 0x25B5, - whiteuppointingtriangle: 0x25B3, - wihiragana: 0x3090, - wikatakana: 0x30F0, - wikorean: 0x315F, - wmonospace: 0xFF57, - wohiragana: 0x3092, - wokatakana: 0x30F2, - wokatakanahalfwidth: 0xFF66, - won: 0x20A9, - wonmonospace: 0xFFE6, - wowaenthai: 0x0E27, - wparen: 0x24B2, - wring: 0x1E98, - wsuperior: 0x02B7, - wturned: 0x028D, - wynn: 0x01BF, - x: 0x0078, - xabovecmb: 0x033D, - xbopomofo: 0x3112, - xcircle: 0x24E7, - xdieresis: 0x1E8D, - xdotaccent: 0x1E8B, - xeharmenian: 0x056D, - xi: 0x03BE, - xmonospace: 0xFF58, - xparen: 0x24B3, - xsuperior: 0x02E3, - y: 0x0079, - yaadosquare: 0x334E, - yabengali: 0x09AF, - yacute: 0x00FD, - yadeva: 0x092F, - yaekorean: 0x3152, - yagujarati: 0x0AAF, - yagurmukhi: 0x0A2F, - yahiragana: 0x3084, - yakatakana: 0x30E4, - yakatakanahalfwidth: 0xFF94, - yakorean: 0x3151, - yamakkanthai: 0x0E4E, - yasmallhiragana: 0x3083, - yasmallkatakana: 0x30E3, - yasmallkatakanahalfwidth: 0xFF6C, - yatcyrillic: 0x0463, - ycircle: 0x24E8, - ycircumflex: 0x0177, - ydieresis: 0x00FF, - ydotaccent: 0x1E8F, - ydotbelow: 0x1EF5, - yeharabic: 0x064A, - yehbarreearabic: 0x06D2, - yehbarreefinalarabic: 0xFBAF, - yehfinalarabic: 0xFEF2, - yehhamzaabovearabic: 0x0626, - yehhamzaabovefinalarabic: 0xFE8A, - yehhamzaaboveinitialarabic: 0xFE8B, - yehhamzaabovemedialarabic: 0xFE8C, - yehinitialarabic: 0xFEF3, - yehmedialarabic: 0xFEF4, - yehmeeminitialarabic: 0xFCDD, - yehmeemisolatedarabic: 0xFC58, - yehnoonfinalarabic: 0xFC94, - yehthreedotsbelowarabic: 0x06D1, - yekorean: 0x3156, - yen: 0x00A5, - yenmonospace: 0xFFE5, - yeokorean: 0x3155, - yeorinhieuhkorean: 0x3186, - yerahbenyomohebrew: 0x05AA, - yerahbenyomolefthebrew: 0x05AA, - yericyrillic: 0x044B, - yerudieresiscyrillic: 0x04F9, - yesieungkorean: 0x3181, - yesieungpansioskorean: 0x3183, - yesieungsioskorean: 0x3182, - yetivhebrew: 0x059A, - ygrave: 0x1EF3, - yhook: 0x01B4, - yhookabove: 0x1EF7, - yiarmenian: 0x0575, - yicyrillic: 0x0457, - yikorean: 0x3162, - yinyang: 0x262F, - yiwnarmenian: 0x0582, - ymonospace: 0xFF59, - yod: 0x05D9, - yoddagesh: 0xFB39, - yoddageshhebrew: 0xFB39, - yodhebrew: 0x05D9, - yodyodhebrew: 0x05F2, - yodyodpatahhebrew: 0xFB1F, - yohiragana: 0x3088, - yoikorean: 0x3189, - yokatakana: 0x30E8, - yokatakanahalfwidth: 0xFF96, - yokorean: 0x315B, - yosmallhiragana: 0x3087, - yosmallkatakana: 0x30E7, - yosmallkatakanahalfwidth: 0xFF6E, - yotgreek: 0x03F3, - yoyaekorean: 0x3188, - yoyakorean: 0x3187, - yoyakthai: 0x0E22, - yoyingthai: 0x0E0D, - yparen: 0x24B4, - ypogegrammeni: 0x037A, - ypogegrammenigreekcmb: 0x0345, - yr: 0x01A6, - yring: 0x1E99, - ysuperior: 0x02B8, - ytilde: 0x1EF9, - yturned: 0x028E, - yuhiragana: 0x3086, - yuikorean: 0x318C, - yukatakana: 0x30E6, - yukatakanahalfwidth: 0xFF95, - yukorean: 0x3160, - yusbigcyrillic: 0x046B, - yusbigiotifiedcyrillic: 0x046D, - yuslittlecyrillic: 0x0467, - yuslittleiotifiedcyrillic: 0x0469, - yusmallhiragana: 0x3085, - yusmallkatakana: 0x30E5, - yusmallkatakanahalfwidth: 0xFF6D, - yuyekorean: 0x318B, - yuyeokorean: 0x318A, - yyabengali: 0x09DF, - yyadeva: 0x095F, - z: 0x007A, - zaarmenian: 0x0566, - zacute: 0x017A, - zadeva: 0x095B, - zagurmukhi: 0x0A5B, - zaharabic: 0x0638, - zahfinalarabic: 0xFEC6, - zahinitialarabic: 0xFEC7, - zahiragana: 0x3056, - zahmedialarabic: 0xFEC8, - zainarabic: 0x0632, - zainfinalarabic: 0xFEB0, - zakatakana: 0x30B6, - zaqefgadolhebrew: 0x0595, - zaqefqatanhebrew: 0x0594, - zarqahebrew: 0x0598, - zayin: 0x05D6, - zayindagesh: 0xFB36, - zayindageshhebrew: 0xFB36, - zayinhebrew: 0x05D6, - zbopomofo: 0x3117, - zcaron: 0x017E, - zcircle: 0x24E9, - zcircumflex: 0x1E91, - zcurl: 0x0291, - zdot: 0x017C, - zdotaccent: 0x017C, - zdotbelow: 0x1E93, - zecyrillic: 0x0437, - zedescendercyrillic: 0x0499, - zedieresiscyrillic: 0x04DF, - zehiragana: 0x305C, - zekatakana: 0x30BC, - zero: 0x0030, - zeroarabic: 0x0660, - zerobengali: 0x09E6, - zerodeva: 0x0966, - zerogujarati: 0x0AE6, - zerogurmukhi: 0x0A66, - zerohackarabic: 0x0660, - zeroinferior: 0x2080, - zeromonospace: 0xFF10, - zerooldstyle: 0xF730, - zeropersian: 0x06F0, - zerosuperior: 0x2070, - zerothai: 0x0E50, - zerowidthjoiner: 0xFEFF, - zerowidthnonjoiner: 0x200C, - zerowidthspace: 0x200B, - zeta: 0x03B6, - zhbopomofo: 0x3113, - zhearmenian: 0x056A, - zhebrevecyrillic: 0x04C2, - zhecyrillic: 0x0436, - zhedescendercyrillic: 0x0497, - zhedieresiscyrillic: 0x04DD, - zihiragana: 0x3058, - zikatakana: 0x30B8, - zinorhebrew: 0x05AE, - zlinebelow: 0x1E95, - zmonospace: 0xFF5A, - zohiragana: 0x305E, - zokatakana: 0x30BE, - zparen: 0x24B5, - zretroflexhook: 0x0290, - zstroke: 0x01B6, - zuhiragana: 0x305A, - zukatakana: 0x30BA, - '.notdef': 0x0000 -}; - -var DingbatsGlyphsUnicode = { - space: 0x0020, - a1: 0x2701, - a2: 0x2702, - a202: 0x2703, - a3: 0x2704, - a4: 0x260E, - a5: 0x2706, - a119: 0x2707, - a118: 0x2708, - a117: 0x2709, - a11: 0x261B, - a12: 0x261E, - a13: 0x270C, - a14: 0x270D, - a15: 0x270E, - a16: 0x270F, - a105: 0x2710, - a17: 0x2711, - a18: 0x2712, - a19: 0x2713, - a20: 0x2714, - a21: 0x2715, - a22: 0x2716, - a23: 0x2717, - a24: 0x2718, - a25: 0x2719, - a26: 0x271A, - a27: 0x271B, - a28: 0x271C, - a6: 0x271D, - a7: 0x271E, - a8: 0x271F, - a9: 0x2720, - a10: 0x2721, - a29: 0x2722, - a30: 0x2723, - a31: 0x2724, - a32: 0x2725, - a33: 0x2726, - a34: 0x2727, - a35: 0x2605, - a36: 0x2729, - a37: 0x272A, - a38: 0x272B, - a39: 0x272C, - a40: 0x272D, - a41: 0x272E, - a42: 0x272F, - a43: 0x2730, - a44: 0x2731, - a45: 0x2732, - a46: 0x2733, - a47: 0x2734, - a48: 0x2735, - a49: 0x2736, - a50: 0x2737, - a51: 0x2738, - a52: 0x2739, - a53: 0x273A, - a54: 0x273B, - a55: 0x273C, - a56: 0x273D, - a57: 0x273E, - a58: 0x273F, - a59: 0x2740, - a60: 0x2741, - a61: 0x2742, - a62: 0x2743, - a63: 0x2744, - a64: 0x2745, - a65: 0x2746, - a66: 0x2747, - a67: 0x2748, - a68: 0x2749, - a69: 0x274A, - a70: 0x274B, - a71: 0x25CF, - a72: 0x274D, - a73: 0x25A0, - a74: 0x274F, - a203: 0x2750, - a75: 0x2751, - a204: 0x2752, - a76: 0x25B2, - a77: 0x25BC, - a78: 0x25C6, - a79: 0x2756, - a81: 0x25D7, - a82: 0x2758, - a83: 0x2759, - a84: 0x275A, - a97: 0x275B, - a98: 0x275C, - a99: 0x275D, - a100: 0x275E, - a101: 0x2761, - a102: 0x2762, - a103: 0x2763, - a104: 0x2764, - a106: 0x2765, - a107: 0x2766, - a108: 0x2767, - a112: 0x2663, - a111: 0x2666, - a110: 0x2665, - a109: 0x2660, - a120: 0x2460, - a121: 0x2461, - a122: 0x2462, - a123: 0x2463, - a124: 0x2464, - a125: 0x2465, - a126: 0x2466, - a127: 0x2467, - a128: 0x2468, - a129: 0x2469, - a130: 0x2776, - a131: 0x2777, - a132: 0x2778, - a133: 0x2779, - a134: 0x277A, - a135: 0x277B, - a136: 0x277C, - a137: 0x277D, - a138: 0x277E, - a139: 0x277F, - a140: 0x2780, - a141: 0x2781, - a142: 0x2782, - a143: 0x2783, - a144: 0x2784, - a145: 0x2785, - a146: 0x2786, - a147: 0x2787, - a148: 0x2788, - a149: 0x2789, - a150: 0x278A, - a151: 0x278B, - a152: 0x278C, - a153: 0x278D, - a154: 0x278E, - a155: 0x278F, - a156: 0x2790, - a157: 0x2791, - a158: 0x2792, - a159: 0x2793, - a160: 0x2794, - a161: 0x2192, - a163: 0x2194, - a164: 0x2195, - a196: 0x2798, - a165: 0x2799, - a192: 0x279A, - a166: 0x279B, - a167: 0x279C, - a168: 0x279D, - a169: 0x279E, - a170: 0x279F, - a171: 0x27A0, - a172: 0x27A1, - a173: 0x27A2, - a162: 0x27A3, - a174: 0x27A4, - a175: 0x27A5, - a176: 0x27A6, - a177: 0x27A7, - a178: 0x27A8, - a179: 0x27A9, - a193: 0x27AA, - a180: 0x27AB, - a199: 0x27AC, - a181: 0x27AD, - a200: 0x27AE, - a182: 0x27AF, - a201: 0x27B1, - a183: 0x27B2, - a184: 0x27B3, - a197: 0x27B4, - a185: 0x27B5, - a194: 0x27B6, - a198: 0x27B7, - a186: 0x27B8, - a195: 0x27B9, - a187: 0x27BA, - a188: 0x27BB, - a189: 0x27BC, - a190: 0x27BD, - a191: 0x27BE, - a89: 0x2768, // 0xF8D7 - a90: 0x2769, // 0xF8D8 - a93: 0x276A, // 0xF8D9 - a94: 0x276B, // 0xF8DA - a91: 0x276C, // 0xF8DB - a92: 0x276D, // 0xF8DC - a205: 0x276E, // 0xF8DD - a85: 0x276F, // 0xF8DE - a206: 0x2770, // 0xF8DF - a86: 0x2771, // 0xF8E0 - a87: 0x2772, // 0xF8E1 - a88: 0x2773, // 0xF8E2 - a95: 0x2774, // 0xF8E3 - a96: 0x2775, // 0xF8E4 - '.notdef': 0x0000 -}; - - -var PDFImage = (function PDFImageClosure() { - /** - * Decode the image in the main thread if it supported. Resovles the promise - * when the image data is ready. - */ - function handleImageData(handler, xref, res, image) { - if (image instanceof JpegStream && image.isNativelyDecodable(xref, res)) { - // For natively supported jpegs send them to the main thread for decoding. - var dict = image.dict; - var colorSpace = dict.get('ColorSpace', 'CS'); - colorSpace = ColorSpace.parse(colorSpace, xref, res); - var numComps = colorSpace.numComps; - var decodePromise = handler.sendWithPromise('JpegDecode', - [image.getIR(), numComps]); - return decodePromise.then(function (message) { - var data = message.data; - return new Stream(data, 0, data.length, image.dict); - }); - } else { - return Promise.resolve(image); - } - } - - /** - * Decode and clamp a value. The formula is different from the spec because we - * don't decode to float range [0,1], we decode it in the [0,max] range. - */ - function decodeAndClamp(value, addend, coefficient, max) { - value = addend + value * coefficient; - // Clamp the value to the range - return (value < 0 ? 0 : (value > max ? max : value)); - } - - function PDFImage(xref, res, image, inline, smask, mask, isMask) { - this.image = image; - var dict = image.dict; - if (dict.has('Filter')) { - var filter = dict.get('Filter').name; - if (filter === 'JPXDecode') { - var jpxImage = new JpxImage(); - jpxImage.parseImageProperties(image.stream); - image.stream.reset(); - image.bitsPerComponent = jpxImage.bitsPerComponent; - image.numComps = jpxImage.componentsCount; - } else if (filter === 'JBIG2Decode') { - image.bitsPerComponent = 1; - image.numComps = 1; - } - } - // TODO cache rendered images? - - this.width = dict.get('Width', 'W'); - this.height = dict.get('Height', 'H'); - - if (this.width < 1 || this.height < 1) { - error('Invalid image width: ' + this.width + ' or height: ' + - this.height); - } - - this.interpolate = dict.get('Interpolate', 'I') || false; - this.imageMask = dict.get('ImageMask', 'IM') || false; - this.matte = dict.get('Matte') || false; - - var bitsPerComponent = image.bitsPerComponent; - if (!bitsPerComponent) { - bitsPerComponent = dict.get('BitsPerComponent', 'BPC'); - if (!bitsPerComponent) { - if (this.imageMask) { - bitsPerComponent = 1; - } else { - error('Bits per component missing in image: ' + this.imageMask); - } - } - } - this.bpc = bitsPerComponent; - - if (!this.imageMask) { - var colorSpace = dict.get('ColorSpace', 'CS'); - if (!colorSpace) { - info('JPX images (which do not require color spaces)'); - switch (image.numComps) { - case 1: - colorSpace = Name.get('DeviceGray'); - break; - case 3: - colorSpace = Name.get('DeviceRGB'); - break; - case 4: - colorSpace = Name.get('DeviceCMYK'); - break; - default: - error('JPX images with ' + this.numComps + - ' color components not supported.'); - } - } - this.colorSpace = ColorSpace.parse(colorSpace, xref, res); - this.numComps = this.colorSpace.numComps; - } - - this.decode = dict.get('Decode', 'D'); - this.needsDecode = false; - if (this.decode && - ((this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode)) || - (isMask && !ColorSpace.isDefaultDecode(this.decode, 1)))) { - this.needsDecode = true; - // Do some preprocessing to avoid more math. - var max = (1 << bitsPerComponent) - 1; - this.decodeCoefficients = []; - this.decodeAddends = []; - for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) { - var dmin = this.decode[i]; - var dmax = this.decode[i + 1]; - this.decodeCoefficients[j] = dmax - dmin; - this.decodeAddends[j] = max * dmin; - } - } - - if (smask) { - this.smask = new PDFImage(xref, res, smask, false); - } else if (mask) { - if (isStream(mask)) { - this.mask = new PDFImage(xref, res, mask, false, null, null, true); - } else { - // Color key mask (just an array). - this.mask = mask; - } - } - } - /** - * Handles processing of image data and returns the Promise that is resolved - * with a PDFImage when the image is ready to be used. - */ - PDFImage.buildImage = function PDFImage_buildImage(handler, xref, - res, image, inline) { - var imagePromise = handleImageData(handler, xref, res, image); - var smaskPromise; - var maskPromise; - - var smask = image.dict.get('SMask'); - var mask = image.dict.get('Mask'); - - if (smask) { - smaskPromise = handleImageData(handler, xref, res, smask); - maskPromise = Promise.resolve(null); - } else { - smaskPromise = Promise.resolve(null); - if (mask) { - if (isStream(mask)) { - maskPromise = handleImageData(handler, xref, res, mask); - } else if (isArray(mask)) { - maskPromise = Promise.resolve(mask); - } else { - warn('Unsupported mask format.'); - maskPromise = Promise.resolve(null); - } - } else { - maskPromise = Promise.resolve(null); - } - } - return Promise.all([imagePromise, smaskPromise, maskPromise]).then( - function(results) { - var imageData = results[0]; - var smaskData = results[1]; - var maskData = results[2]; - return new PDFImage(xref, res, imageData, inline, smaskData, maskData); - }); - }; - - /** - * Resize an image using the nearest neighbor algorithm. Currently only - * supports one and three component images. - * @param {TypedArray} pixels The original image with one component. - * @param {Number} bpc Number of bits per component. - * @param {Number} components Number of color components, 1 or 3 is supported. - * @param {Number} w1 Original width. - * @param {Number} h1 Original height. - * @param {Number} w2 New width. - * @param {Number} h2 New height. - * @param {TypedArray} dest (Optional) The destination buffer. - * @param {Number} alpha01 (Optional) Size reserved for the alpha channel. - * @return {TypedArray} Resized image data. - */ - PDFImage.resize = function PDFImage_resize(pixels, bpc, components, - w1, h1, w2, h2, dest, alpha01) { - - if (components !== 1 && components !== 3) { - error('Unsupported component count for resizing.'); - } - - var length = w2 * h2 * components; - var temp = dest ? dest : (bpc <= 8 ? new Uint8Array(length) : - (bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length))); - var xRatio = w1 / w2; - var yRatio = h1 / h2; - var i, j, py, newIndex = 0, oldIndex; - var xScaled = new Uint16Array(w2); - var w1Scanline = w1 * components; - if (alpha01 !== 1) { - alpha01 = 0; - } - - for (j = 0; j < w2; j++) { - xScaled[j] = Math.floor(j * xRatio) * components; - } - - if (components === 1) { - for (i = 0; i < h2; i++) { - py = Math.floor(i * yRatio) * w1Scanline; - for (j = 0; j < w2; j++) { - oldIndex = py + xScaled[j]; - temp[newIndex++] = pixels[oldIndex]; - } - } - } else if (components === 3) { - for (i = 0; i < h2; i++) { - py = Math.floor(i * yRatio) * w1Scanline; - for (j = 0; j < w2; j++) { - oldIndex = py + xScaled[j]; - temp[newIndex++] = pixels[oldIndex++]; - temp[newIndex++] = pixels[oldIndex++]; - temp[newIndex++] = pixels[oldIndex++]; - newIndex += alpha01; - } - } - } - return temp; - }; - - PDFImage.createMask = - function PDFImage_createMask(imgArray, width, height, - imageIsFromDecodeStream, inverseDecode) { - - // |imgArray| might not contain full data for every pixel of the mask, so - // we need to distinguish between |computedLength| and |actualLength|. - // In particular, if inverseDecode is true, then the array we return must - // have a length of |computedLength|. - - var computedLength = ((width + 7) >> 3) * height; - var actualLength = imgArray.byteLength; - var haveFullData = computedLength === actualLength; - var data, i; - - if (imageIsFromDecodeStream && (!inverseDecode || haveFullData)) { - // imgArray came from a DecodeStream and its data is in an appropriate - // form, so we can just transfer it. - data = imgArray; - } else if (!inverseDecode) { - data = new Uint8Array(actualLength); - data.set(imgArray); - } else { - data = new Uint8Array(computedLength); - data.set(imgArray); - for (i = actualLength; i < computedLength; i++) { - data[i] = 0xff; - } - } - - // If necessary, invert the original mask data (but not any extra we might - // have added above). It's safe to modify the array -- whether it's the - // original or a copy, we're about to transfer it anyway, so nothing else - // in this thread can be relying on its contents. - if (inverseDecode) { - for (i = 0; i < actualLength; i++) { - data[i] = ~data[i]; - } - } - - return {data: data, width: width, height: height}; - }; - - PDFImage.prototype = { - get drawWidth() { - return Math.max(this.width, - this.smask && this.smask.width || 0, - this.mask && this.mask.width || 0); - }, - - get drawHeight() { - return Math.max(this.height, - this.smask && this.smask.height || 0, - this.mask && this.mask.height || 0); - }, - - decodeBuffer: function PDFImage_decodeBuffer(buffer) { - var bpc = this.bpc; - var numComps = this.numComps; - - var decodeAddends = this.decodeAddends; - var decodeCoefficients = this.decodeCoefficients; - var max = (1 << bpc) - 1; - var i, ii; - - if (bpc === 1) { - // If the buffer needed decode that means it just needs to be inverted. - for (i = 0, ii = buffer.length; i < ii; i++) { - buffer[i] = +!(buffer[i]); - } - return; - } - var index = 0; - for (i = 0, ii = this.width * this.height; i < ii; i++) { - for (var j = 0; j < numComps; j++) { - buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j], - decodeCoefficients[j], max); - index++; - } - } - }, - - getComponents: function PDFImage_getComponents(buffer) { - var bpc = this.bpc; - - // This image doesn't require any extra work. - if (bpc === 8) { - return buffer; - } - - var width = this.width; - var height = this.height; - var numComps = this.numComps; - - var length = width * height * numComps; - var bufferPos = 0; - var output = (bpc <= 8 ? new Uint8Array(length) : - (bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length))); - var rowComps = width * numComps; - - var max = (1 << bpc) - 1; - var i = 0, ii, buf; - - if (bpc === 1) { - // Optimization for reading 1 bpc images. - var mask, loop1End, loop2End; - for (var j = 0; j < height; j++) { - loop1End = i + (rowComps & ~7); - loop2End = i + rowComps; - - // unroll loop for all full bytes - while (i < loop1End) { - buf = buffer[bufferPos++]; - output[i] = (buf >> 7) & 1; - output[i + 1] = (buf >> 6) & 1; - output[i + 2] = (buf >> 5) & 1; - output[i + 3] = (buf >> 4) & 1; - output[i + 4] = (buf >> 3) & 1; - output[i + 5] = (buf >> 2) & 1; - output[i + 6] = (buf >> 1) & 1; - output[i + 7] = buf & 1; - i += 8; - } - - // handle remaing bits - if (i < loop2End) { - buf = buffer[bufferPos++]; - mask = 128; - while (i < loop2End) { - output[i++] = +!!(buf & mask); - mask >>= 1; - } - } - } - } else { - // The general case that handles all other bpc values. - var bits = 0; - buf = 0; - for (i = 0, ii = length; i < ii; ++i) { - if (i % rowComps === 0) { - buf = 0; - bits = 0; - } - - while (bits < bpc) { - buf = (buf << 8) | buffer[bufferPos++]; - bits += 8; - } - - var remainingBits = bits - bpc; - var value = buf >> remainingBits; - output[i] = (value < 0 ? 0 : (value > max ? max : value)); - buf = buf & ((1 << remainingBits) - 1); - bits = remainingBits; - } - } - return output; - }, - - fillOpacity: function PDFImage_fillOpacity(rgbaBuf, width, height, - actualHeight, image) { - var smask = this.smask; - var mask = this.mask; - var alphaBuf, sw, sh, i, ii, j; - - if (smask) { - sw = smask.width; - sh = smask.height; - alphaBuf = new Uint8Array(sw * sh); - smask.fillGrayBuffer(alphaBuf); - if (sw !== width || sh !== height) { - alphaBuf = PDFImage.resize(alphaBuf, smask.bpc, 1, sw, sh, width, - height); - } - } else if (mask) { - if (mask instanceof PDFImage) { - sw = mask.width; - sh = mask.height; - alphaBuf = new Uint8Array(sw * sh); - mask.numComps = 1; - mask.fillGrayBuffer(alphaBuf); - - // Need to invert values in rgbaBuf - for (i = 0, ii = sw * sh; i < ii; ++i) { - alphaBuf[i] = 255 - alphaBuf[i]; - } - - if (sw !== width || sh !== height) { - alphaBuf = PDFImage.resize(alphaBuf, mask.bpc, 1, sw, sh, width, - height); - } - } else if (isArray(mask)) { - // Color key mask: if any of the compontents are outside the range - // then they should be painted. - alphaBuf = new Uint8Array(width * height); - var numComps = this.numComps; - for (i = 0, ii = width * height; i < ii; ++i) { - var opacity = 0; - var imageOffset = i * numComps; - for (j = 0; j < numComps; ++j) { - var color = image[imageOffset + j]; - var maskOffset = j * 2; - if (color < mask[maskOffset] || color > mask[maskOffset + 1]) { - opacity = 255; - break; - } - } - alphaBuf[i] = opacity; - } - } else { - error('Unknown mask format.'); - } - } - - if (alphaBuf) { - for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) { - rgbaBuf[j] = alphaBuf[i]; - } - } else { - // No mask. - for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) { - rgbaBuf[j] = 255; - } - } - }, - - undoPreblend: function PDFImage_undoPreblend(buffer, width, height) { - var matte = this.smask && this.smask.matte; - if (!matte) { - return; - } - var matteRgb = this.colorSpace.getRgb(matte, 0); - var matteR = matteRgb[0]; - var matteG = matteRgb[1]; - var matteB = matteRgb[2]; - var length = width * height * 4; - var r, g, b; - for (var i = 0; i < length; i += 4) { - var alpha = buffer[i + 3]; - if (alpha === 0) { - // according formula we have to get Infinity in all components - // making it white (typical paper color) should be okay - buffer[i] = 255; - buffer[i + 1] = 255; - buffer[i + 2] = 255; - continue; - } - var k = 255 / alpha; - r = (buffer[i] - matteR) * k + matteR; - g = (buffer[i + 1] - matteG) * k + matteG; - b = (buffer[i + 2] - matteB) * k + matteB; - buffer[i] = r <= 0 ? 0 : r >= 255 ? 255 : r | 0; - buffer[i + 1] = g <= 0 ? 0 : g >= 255 ? 255 : g | 0; - buffer[i + 2] = b <= 0 ? 0 : b >= 255 ? 255 : b | 0; - } - }, - - createImageData: function PDFImage_createImageData(forceRGBA) { - var drawWidth = this.drawWidth; - var drawHeight = this.drawHeight; - var imgData = { // other fields are filled in below - width: drawWidth, - height: drawHeight - }; - - var numComps = this.numComps; - var originalWidth = this.width; - var originalHeight = this.height; - var bpc = this.bpc; - - // Rows start at byte boundary. - var rowBytes = (originalWidth * numComps * bpc + 7) >> 3; - var imgArray; - - if (!forceRGBA) { - // If it is a 1-bit-per-pixel grayscale (i.e. black-and-white) image - // without any complications, we pass a same-sized copy to the main - // thread rather than expanding by 32x to RGBA form. This saves *lots* - // of memory for many scanned documents. It's also much faster. - // - // Similarly, if it is a 24-bit-per pixel RGB image without any - // complications, we avoid expanding by 1.333x to RGBA form. - var kind; - if (this.colorSpace.name === 'DeviceGray' && bpc === 1) { - kind = ImageKind.GRAYSCALE_1BPP; - } else if (this.colorSpace.name === 'DeviceRGB' && bpc === 8 && - !this.needsDecode) { - kind = ImageKind.RGB_24BPP; - } - if (kind && !this.smask && !this.mask && - drawWidth === originalWidth && drawHeight === originalHeight) { - imgData.kind = kind; - - imgArray = this.getImageBytes(originalHeight * rowBytes); - // If imgArray came from a DecodeStream, we're safe to transfer it - // (and thus neuter it) because it will constitute the entire - // DecodeStream's data. But if it came from a Stream, we need to - // copy it because it'll only be a portion of the Stream's data, and - // the rest will be read later on. - if (this.image instanceof DecodeStream) { - imgData.data = imgArray; - } else { - var newArray = new Uint8Array(imgArray.length); - newArray.set(imgArray); - imgData.data = newArray; - } - if (this.needsDecode) { - // Invert the buffer (which must be grayscale if we reached here). - assert(kind === ImageKind.GRAYSCALE_1BPP); - var buffer = imgData.data; - for (var i = 0, ii = buffer.length; i < ii; i++) { - buffer[i] ^= 0xff; - } - } - return imgData; - } - if (this.image instanceof JpegStream && !this.smask && !this.mask) { - imgData.kind = ImageKind.RGB_24BPP; - imgData.data = this.getImageBytes(originalHeight * rowBytes, - drawWidth, drawHeight, true); - return imgData; - } - } - - imgArray = this.getImageBytes(originalHeight * rowBytes); - // imgArray can be incomplete (e.g. after CCITT fax encoding). - var actualHeight = 0 | (imgArray.length / rowBytes * - drawHeight / originalHeight); - - var comps = this.getComponents(imgArray); - - // If opacity data is present, use RGBA_32BPP form. Otherwise, use the - // more compact RGB_24BPP form if allowable. - var alpha01, maybeUndoPreblend; - if (!forceRGBA && !this.smask && !this.mask) { - imgData.kind = ImageKind.RGB_24BPP; - imgData.data = new Uint8Array(drawWidth * drawHeight * 3); - alpha01 = 0; - maybeUndoPreblend = false; - } else { - imgData.kind = ImageKind.RGBA_32BPP; - imgData.data = new Uint8Array(drawWidth * drawHeight * 4); - alpha01 = 1; - maybeUndoPreblend = true; - - // Color key masking (opacity) must be performed before decoding. - this.fillOpacity(imgData.data, drawWidth, drawHeight, actualHeight, - comps); - } - - if (this.needsDecode) { - this.decodeBuffer(comps); - } - this.colorSpace.fillRgb(imgData.data, originalWidth, originalHeight, - drawWidth, drawHeight, actualHeight, bpc, comps, - alpha01); - if (maybeUndoPreblend) { - this.undoPreblend(imgData.data, drawWidth, actualHeight); - } - - return imgData; - }, - - fillGrayBuffer: function PDFImage_fillGrayBuffer(buffer) { - var numComps = this.numComps; - if (numComps !== 1) { - error('Reading gray scale from a color image: ' + numComps); - } - - var width = this.width; - var height = this.height; - var bpc = this.bpc; - - // rows start at byte boundary - var rowBytes = (width * numComps * bpc + 7) >> 3; - var imgArray = this.getImageBytes(height * rowBytes); - - var comps = this.getComponents(imgArray); - var i, length; - - if (bpc === 1) { - // inline decoding (= inversion) for 1 bpc images - length = width * height; - if (this.needsDecode) { - // invert and scale to {0, 255} - for (i = 0; i < length; ++i) { - buffer[i] = (comps[i] - 1) & 255; - } - } else { - // scale to {0, 255} - for (i = 0; i < length; ++i) { - buffer[i] = (-comps[i]) & 255; - } - } - return; - } - - if (this.needsDecode) { - this.decodeBuffer(comps); - } - length = width * height; - // we aren't using a colorspace so we need to scale the value - var scale = 255 / ((1 << bpc) - 1); - for (i = 0; i < length; ++i) { - buffer[i] = (scale * comps[i]) | 0; - } - }, - - getImageBytes: function PDFImage_getImageBytes(length, - drawWidth, drawHeight, - forceRGB) { - this.image.reset(); - this.image.drawWidth = drawWidth || this.width; - this.image.drawHeight = drawHeight || this.height; - this.image.forceRGB = !!forceRGB; - return this.image.getBytes(length); - } - }; - return PDFImage; -})(); - - -// The Metrics object contains glyph widths (in glyph space units). -// As per PDF spec, for most fonts (Type 3 being an exception) a glyph -// space unit corresponds to 1/1000th of text space unit. -var Metrics = { - 'Courier': 600, - 'Courier-Bold': 600, - 'Courier-BoldOblique': 600, - 'Courier-Oblique': 600, - 'Helvetica' : { - 'space': 278, - 'exclam': 278, - 'quotedbl': 355, - 'numbersign': 556, - 'dollar': 556, - 'percent': 889, - 'ampersand': 667, - 'quoteright': 222, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 389, - 'plus': 584, - 'comma': 278, - 'hyphen': 333, - 'period': 278, - 'slash': 278, - 'zero': 556, - 'one': 556, - 'two': 556, - 'three': 556, - 'four': 556, - 'five': 556, - 'six': 556, - 'seven': 556, - 'eight': 556, - 'nine': 556, - 'colon': 278, - 'semicolon': 278, - 'less': 584, - 'equal': 584, - 'greater': 584, - 'question': 556, - 'at': 1015, - 'A': 667, - 'B': 667, - 'C': 722, - 'D': 722, - 'E': 667, - 'F': 611, - 'G': 778, - 'H': 722, - 'I': 278, - 'J': 500, - 'K': 667, - 'L': 556, - 'M': 833, - 'N': 722, - 'O': 778, - 'P': 667, - 'Q': 778, - 'R': 722, - 'S': 667, - 'T': 611, - 'U': 722, - 'V': 667, - 'W': 944, - 'X': 667, - 'Y': 667, - 'Z': 611, - 'bracketleft': 278, - 'backslash': 278, - 'bracketright': 278, - 'asciicircum': 469, - 'underscore': 556, - 'quoteleft': 222, - 'a': 556, - 'b': 556, - 'c': 500, - 'd': 556, - 'e': 556, - 'f': 278, - 'g': 556, - 'h': 556, - 'i': 222, - 'j': 222, - 'k': 500, - 'l': 222, - 'm': 833, - 'n': 556, - 'o': 556, - 'p': 556, - 'q': 556, - 'r': 333, - 's': 500, - 't': 278, - 'u': 556, - 'v': 500, - 'w': 722, - 'x': 500, - 'y': 500, - 'z': 500, - 'braceleft': 334, - 'bar': 260, - 'braceright': 334, - 'asciitilde': 584, - 'exclamdown': 333, - 'cent': 556, - 'sterling': 556, - 'fraction': 167, - 'yen': 556, - 'florin': 556, - 'section': 556, - 'currency': 556, - 'quotesingle': 191, - 'quotedblleft': 333, - 'guillemotleft': 556, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 500, - 'fl': 500, - 'endash': 556, - 'dagger': 556, - 'daggerdbl': 556, - 'periodcentered': 278, - 'paragraph': 537, - 'bullet': 350, - 'quotesinglbase': 222, - 'quotedblbase': 333, - 'quotedblright': 333, - 'guillemotright': 556, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 611, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 1000, - 'ordfeminine': 370, - 'Lslash': 556, - 'Oslash': 778, - 'OE': 1000, - 'ordmasculine': 365, - 'ae': 889, - 'dotlessi': 278, - 'lslash': 222, - 'oslash': 611, - 'oe': 944, - 'germandbls': 611, - 'Idieresis': 278, - 'eacute': 556, - 'abreve': 556, - 'uhungarumlaut': 556, - 'ecaron': 556, - 'Ydieresis': 667, - 'divide': 584, - 'Yacute': 667, - 'Acircumflex': 667, - 'aacute': 556, - 'Ucircumflex': 722, - 'yacute': 500, - 'scommaaccent': 500, - 'ecircumflex': 556, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 556, - 'Uacute': 722, - 'uogonek': 556, - 'Edieresis': 667, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 737, - 'Emacron': 667, - 'ccaron': 500, - 'aring': 556, - 'Ncommaaccent': 722, - 'lacute': 222, - 'agrave': 556, - 'Tcommaaccent': 611, - 'Cacute': 722, - 'atilde': 556, - 'Edotaccent': 667, - 'scaron': 500, - 'scedilla': 500, - 'iacute': 278, - 'lozenge': 471, - 'Rcaron': 722, - 'Gcommaaccent': 778, - 'ucircumflex': 556, - 'acircumflex': 556, - 'Amacron': 667, - 'rcaron': 333, - 'ccedilla': 500, - 'Zdotaccent': 611, - 'Thorn': 667, - 'Omacron': 778, - 'Racute': 722, - 'Sacute': 667, - 'dcaron': 643, - 'Umacron': 722, - 'uring': 556, - 'threesuperior': 333, - 'Ograve': 778, - 'Agrave': 667, - 'Abreve': 667, - 'multiply': 584, - 'uacute': 556, - 'Tcaron': 611, - 'partialdiff': 476, - 'ydieresis': 500, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 667, - 'adieresis': 556, - 'edieresis': 556, - 'cacute': 500, - 'nacute': 556, - 'umacron': 556, - 'Ncaron': 722, - 'Iacute': 278, - 'plusminus': 584, - 'brokenbar': 260, - 'registered': 737, - 'Gbreve': 778, - 'Idotaccent': 278, - 'summation': 600, - 'Egrave': 667, - 'racute': 333, - 'omacron': 556, - 'Zacute': 611, - 'Zcaron': 611, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 722, - 'lcommaaccent': 222, - 'tcaron': 317, - 'eogonek': 556, - 'Uogonek': 722, - 'Aacute': 667, - 'Adieresis': 667, - 'egrave': 556, - 'zacute': 500, - 'iogonek': 222, - 'Oacute': 778, - 'oacute': 556, - 'amacron': 556, - 'sacute': 500, - 'idieresis': 278, - 'Ocircumflex': 778, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 556, - 'twosuperior': 333, - 'Odieresis': 778, - 'mu': 556, - 'igrave': 278, - 'ohungarumlaut': 556, - 'Eogonek': 667, - 'dcroat': 556, - 'threequarters': 834, - 'Scedilla': 667, - 'lcaron': 299, - 'Kcommaaccent': 667, - 'Lacute': 556, - 'trademark': 1000, - 'edotaccent': 556, - 'Igrave': 278, - 'Imacron': 278, - 'Lcaron': 556, - 'onehalf': 834, - 'lessequal': 549, - 'ocircumflex': 556, - 'ntilde': 556, - 'Uhungarumlaut': 722, - 'Eacute': 667, - 'emacron': 556, - 'gbreve': 556, - 'onequarter': 834, - 'Scaron': 667, - 'Scommaaccent': 667, - 'Ohungarumlaut': 778, - 'degree': 400, - 'ograve': 556, - 'Ccaron': 722, - 'ugrave': 556, - 'radical': 453, - 'Dcaron': 722, - 'rcommaaccent': 333, - 'Ntilde': 722, - 'otilde': 556, - 'Rcommaaccent': 722, - 'Lcommaaccent': 556, - 'Atilde': 667, - 'Aogonek': 667, - 'Aring': 667, - 'Otilde': 778, - 'zdotaccent': 500, - 'Ecaron': 667, - 'Iogonek': 278, - 'kcommaaccent': 500, - 'minus': 584, - 'Icircumflex': 278, - 'ncaron': 556, - 'tcommaaccent': 278, - 'logicalnot': 584, - 'odieresis': 556, - 'udieresis': 556, - 'notequal': 549, - 'gcommaaccent': 556, - 'eth': 556, - 'zcaron': 500, - 'ncommaaccent': 556, - 'onesuperior': 333, - 'imacron': 278, - 'Euro': 556 - }, - 'Helvetica-Bold': { - 'space': 278, - 'exclam': 333, - 'quotedbl': 474, - 'numbersign': 556, - 'dollar': 556, - 'percent': 889, - 'ampersand': 722, - 'quoteright': 278, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 389, - 'plus': 584, - 'comma': 278, - 'hyphen': 333, - 'period': 278, - 'slash': 278, - 'zero': 556, - 'one': 556, - 'two': 556, - 'three': 556, - 'four': 556, - 'five': 556, - 'six': 556, - 'seven': 556, - 'eight': 556, - 'nine': 556, - 'colon': 333, - 'semicolon': 333, - 'less': 584, - 'equal': 584, - 'greater': 584, - 'question': 611, - 'at': 975, - 'A': 722, - 'B': 722, - 'C': 722, - 'D': 722, - 'E': 667, - 'F': 611, - 'G': 778, - 'H': 722, - 'I': 278, - 'J': 556, - 'K': 722, - 'L': 611, - 'M': 833, - 'N': 722, - 'O': 778, - 'P': 667, - 'Q': 778, - 'R': 722, - 'S': 667, - 'T': 611, - 'U': 722, - 'V': 667, - 'W': 944, - 'X': 667, - 'Y': 667, - 'Z': 611, - 'bracketleft': 333, - 'backslash': 278, - 'bracketright': 333, - 'asciicircum': 584, - 'underscore': 556, - 'quoteleft': 278, - 'a': 556, - 'b': 611, - 'c': 556, - 'd': 611, - 'e': 556, - 'f': 333, - 'g': 611, - 'h': 611, - 'i': 278, - 'j': 278, - 'k': 556, - 'l': 278, - 'm': 889, - 'n': 611, - 'o': 611, - 'p': 611, - 'q': 611, - 'r': 389, - 's': 556, - 't': 333, - 'u': 611, - 'v': 556, - 'w': 778, - 'x': 556, - 'y': 556, - 'z': 500, - 'braceleft': 389, - 'bar': 280, - 'braceright': 389, - 'asciitilde': 584, - 'exclamdown': 333, - 'cent': 556, - 'sterling': 556, - 'fraction': 167, - 'yen': 556, - 'florin': 556, - 'section': 556, - 'currency': 556, - 'quotesingle': 238, - 'quotedblleft': 500, - 'guillemotleft': 556, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 611, - 'fl': 611, - 'endash': 556, - 'dagger': 556, - 'daggerdbl': 556, - 'periodcentered': 278, - 'paragraph': 556, - 'bullet': 350, - 'quotesinglbase': 278, - 'quotedblbase': 500, - 'quotedblright': 500, - 'guillemotright': 556, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 611, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 1000, - 'ordfeminine': 370, - 'Lslash': 611, - 'Oslash': 778, - 'OE': 1000, - 'ordmasculine': 365, - 'ae': 889, - 'dotlessi': 278, - 'lslash': 278, - 'oslash': 611, - 'oe': 944, - 'germandbls': 611, - 'Idieresis': 278, - 'eacute': 556, - 'abreve': 556, - 'uhungarumlaut': 611, - 'ecaron': 556, - 'Ydieresis': 667, - 'divide': 584, - 'Yacute': 667, - 'Acircumflex': 722, - 'aacute': 556, - 'Ucircumflex': 722, - 'yacute': 556, - 'scommaaccent': 556, - 'ecircumflex': 556, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 556, - 'Uacute': 722, - 'uogonek': 611, - 'Edieresis': 667, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 737, - 'Emacron': 667, - 'ccaron': 556, - 'aring': 556, - 'Ncommaaccent': 722, - 'lacute': 278, - 'agrave': 556, - 'Tcommaaccent': 611, - 'Cacute': 722, - 'atilde': 556, - 'Edotaccent': 667, - 'scaron': 556, - 'scedilla': 556, - 'iacute': 278, - 'lozenge': 494, - 'Rcaron': 722, - 'Gcommaaccent': 778, - 'ucircumflex': 611, - 'acircumflex': 556, - 'Amacron': 722, - 'rcaron': 389, - 'ccedilla': 556, - 'Zdotaccent': 611, - 'Thorn': 667, - 'Omacron': 778, - 'Racute': 722, - 'Sacute': 667, - 'dcaron': 743, - 'Umacron': 722, - 'uring': 611, - 'threesuperior': 333, - 'Ograve': 778, - 'Agrave': 722, - 'Abreve': 722, - 'multiply': 584, - 'uacute': 611, - 'Tcaron': 611, - 'partialdiff': 494, - 'ydieresis': 556, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 667, - 'adieresis': 556, - 'edieresis': 556, - 'cacute': 556, - 'nacute': 611, - 'umacron': 611, - 'Ncaron': 722, - 'Iacute': 278, - 'plusminus': 584, - 'brokenbar': 280, - 'registered': 737, - 'Gbreve': 778, - 'Idotaccent': 278, - 'summation': 600, - 'Egrave': 667, - 'racute': 389, - 'omacron': 611, - 'Zacute': 611, - 'Zcaron': 611, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 722, - 'lcommaaccent': 278, - 'tcaron': 389, - 'eogonek': 556, - 'Uogonek': 722, - 'Aacute': 722, - 'Adieresis': 722, - 'egrave': 556, - 'zacute': 500, - 'iogonek': 278, - 'Oacute': 778, - 'oacute': 611, - 'amacron': 556, - 'sacute': 556, - 'idieresis': 278, - 'Ocircumflex': 778, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 611, - 'twosuperior': 333, - 'Odieresis': 778, - 'mu': 611, - 'igrave': 278, - 'ohungarumlaut': 611, - 'Eogonek': 667, - 'dcroat': 611, - 'threequarters': 834, - 'Scedilla': 667, - 'lcaron': 400, - 'Kcommaaccent': 722, - 'Lacute': 611, - 'trademark': 1000, - 'edotaccent': 556, - 'Igrave': 278, - 'Imacron': 278, - 'Lcaron': 611, - 'onehalf': 834, - 'lessequal': 549, - 'ocircumflex': 611, - 'ntilde': 611, - 'Uhungarumlaut': 722, - 'Eacute': 667, - 'emacron': 556, - 'gbreve': 611, - 'onequarter': 834, - 'Scaron': 667, - 'Scommaaccent': 667, - 'Ohungarumlaut': 778, - 'degree': 400, - 'ograve': 611, - 'Ccaron': 722, - 'ugrave': 611, - 'radical': 549, - 'Dcaron': 722, - 'rcommaaccent': 389, - 'Ntilde': 722, - 'otilde': 611, - 'Rcommaaccent': 722, - 'Lcommaaccent': 611, - 'Atilde': 722, - 'Aogonek': 722, - 'Aring': 722, - 'Otilde': 778, - 'zdotaccent': 500, - 'Ecaron': 667, - 'Iogonek': 278, - 'kcommaaccent': 556, - 'minus': 584, - 'Icircumflex': 278, - 'ncaron': 611, - 'tcommaaccent': 333, - 'logicalnot': 584, - 'odieresis': 611, - 'udieresis': 611, - 'notequal': 549, - 'gcommaaccent': 611, - 'eth': 611, - 'zcaron': 500, - 'ncommaaccent': 611, - 'onesuperior': 333, - 'imacron': 278, - 'Euro': 556 - }, - 'Helvetica-BoldOblique': { - 'space': 278, - 'exclam': 333, - 'quotedbl': 474, - 'numbersign': 556, - 'dollar': 556, - 'percent': 889, - 'ampersand': 722, - 'quoteright': 278, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 389, - 'plus': 584, - 'comma': 278, - 'hyphen': 333, - 'period': 278, - 'slash': 278, - 'zero': 556, - 'one': 556, - 'two': 556, - 'three': 556, - 'four': 556, - 'five': 556, - 'six': 556, - 'seven': 556, - 'eight': 556, - 'nine': 556, - 'colon': 333, - 'semicolon': 333, - 'less': 584, - 'equal': 584, - 'greater': 584, - 'question': 611, - 'at': 975, - 'A': 722, - 'B': 722, - 'C': 722, - 'D': 722, - 'E': 667, - 'F': 611, - 'G': 778, - 'H': 722, - 'I': 278, - 'J': 556, - 'K': 722, - 'L': 611, - 'M': 833, - 'N': 722, - 'O': 778, - 'P': 667, - 'Q': 778, - 'R': 722, - 'S': 667, - 'T': 611, - 'U': 722, - 'V': 667, - 'W': 944, - 'X': 667, - 'Y': 667, - 'Z': 611, - 'bracketleft': 333, - 'backslash': 278, - 'bracketright': 333, - 'asciicircum': 584, - 'underscore': 556, - 'quoteleft': 278, - 'a': 556, - 'b': 611, - 'c': 556, - 'd': 611, - 'e': 556, - 'f': 333, - 'g': 611, - 'h': 611, - 'i': 278, - 'j': 278, - 'k': 556, - 'l': 278, - 'm': 889, - 'n': 611, - 'o': 611, - 'p': 611, - 'q': 611, - 'r': 389, - 's': 556, - 't': 333, - 'u': 611, - 'v': 556, - 'w': 778, - 'x': 556, - 'y': 556, - 'z': 500, - 'braceleft': 389, - 'bar': 280, - 'braceright': 389, - 'asciitilde': 584, - 'exclamdown': 333, - 'cent': 556, - 'sterling': 556, - 'fraction': 167, - 'yen': 556, - 'florin': 556, - 'section': 556, - 'currency': 556, - 'quotesingle': 238, - 'quotedblleft': 500, - 'guillemotleft': 556, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 611, - 'fl': 611, - 'endash': 556, - 'dagger': 556, - 'daggerdbl': 556, - 'periodcentered': 278, - 'paragraph': 556, - 'bullet': 350, - 'quotesinglbase': 278, - 'quotedblbase': 500, - 'quotedblright': 500, - 'guillemotright': 556, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 611, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 1000, - 'ordfeminine': 370, - 'Lslash': 611, - 'Oslash': 778, - 'OE': 1000, - 'ordmasculine': 365, - 'ae': 889, - 'dotlessi': 278, - 'lslash': 278, - 'oslash': 611, - 'oe': 944, - 'germandbls': 611, - 'Idieresis': 278, - 'eacute': 556, - 'abreve': 556, - 'uhungarumlaut': 611, - 'ecaron': 556, - 'Ydieresis': 667, - 'divide': 584, - 'Yacute': 667, - 'Acircumflex': 722, - 'aacute': 556, - 'Ucircumflex': 722, - 'yacute': 556, - 'scommaaccent': 556, - 'ecircumflex': 556, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 556, - 'Uacute': 722, - 'uogonek': 611, - 'Edieresis': 667, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 737, - 'Emacron': 667, - 'ccaron': 556, - 'aring': 556, - 'Ncommaaccent': 722, - 'lacute': 278, - 'agrave': 556, - 'Tcommaaccent': 611, - 'Cacute': 722, - 'atilde': 556, - 'Edotaccent': 667, - 'scaron': 556, - 'scedilla': 556, - 'iacute': 278, - 'lozenge': 494, - 'Rcaron': 722, - 'Gcommaaccent': 778, - 'ucircumflex': 611, - 'acircumflex': 556, - 'Amacron': 722, - 'rcaron': 389, - 'ccedilla': 556, - 'Zdotaccent': 611, - 'Thorn': 667, - 'Omacron': 778, - 'Racute': 722, - 'Sacute': 667, - 'dcaron': 743, - 'Umacron': 722, - 'uring': 611, - 'threesuperior': 333, - 'Ograve': 778, - 'Agrave': 722, - 'Abreve': 722, - 'multiply': 584, - 'uacute': 611, - 'Tcaron': 611, - 'partialdiff': 494, - 'ydieresis': 556, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 667, - 'adieresis': 556, - 'edieresis': 556, - 'cacute': 556, - 'nacute': 611, - 'umacron': 611, - 'Ncaron': 722, - 'Iacute': 278, - 'plusminus': 584, - 'brokenbar': 280, - 'registered': 737, - 'Gbreve': 778, - 'Idotaccent': 278, - 'summation': 600, - 'Egrave': 667, - 'racute': 389, - 'omacron': 611, - 'Zacute': 611, - 'Zcaron': 611, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 722, - 'lcommaaccent': 278, - 'tcaron': 389, - 'eogonek': 556, - 'Uogonek': 722, - 'Aacute': 722, - 'Adieresis': 722, - 'egrave': 556, - 'zacute': 500, - 'iogonek': 278, - 'Oacute': 778, - 'oacute': 611, - 'amacron': 556, - 'sacute': 556, - 'idieresis': 278, - 'Ocircumflex': 778, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 611, - 'twosuperior': 333, - 'Odieresis': 778, - 'mu': 611, - 'igrave': 278, - 'ohungarumlaut': 611, - 'Eogonek': 667, - 'dcroat': 611, - 'threequarters': 834, - 'Scedilla': 667, - 'lcaron': 400, - 'Kcommaaccent': 722, - 'Lacute': 611, - 'trademark': 1000, - 'edotaccent': 556, - 'Igrave': 278, - 'Imacron': 278, - 'Lcaron': 611, - 'onehalf': 834, - 'lessequal': 549, - 'ocircumflex': 611, - 'ntilde': 611, - 'Uhungarumlaut': 722, - 'Eacute': 667, - 'emacron': 556, - 'gbreve': 611, - 'onequarter': 834, - 'Scaron': 667, - 'Scommaaccent': 667, - 'Ohungarumlaut': 778, - 'degree': 400, - 'ograve': 611, - 'Ccaron': 722, - 'ugrave': 611, - 'radical': 549, - 'Dcaron': 722, - 'rcommaaccent': 389, - 'Ntilde': 722, - 'otilde': 611, - 'Rcommaaccent': 722, - 'Lcommaaccent': 611, - 'Atilde': 722, - 'Aogonek': 722, - 'Aring': 722, - 'Otilde': 778, - 'zdotaccent': 500, - 'Ecaron': 667, - 'Iogonek': 278, - 'kcommaaccent': 556, - 'minus': 584, - 'Icircumflex': 278, - 'ncaron': 611, - 'tcommaaccent': 333, - 'logicalnot': 584, - 'odieresis': 611, - 'udieresis': 611, - 'notequal': 549, - 'gcommaaccent': 611, - 'eth': 611, - 'zcaron': 500, - 'ncommaaccent': 611, - 'onesuperior': 333, - 'imacron': 278, - 'Euro': 556 - }, - 'Helvetica-Oblique' : { - 'space': 278, - 'exclam': 278, - 'quotedbl': 355, - 'numbersign': 556, - 'dollar': 556, - 'percent': 889, - 'ampersand': 667, - 'quoteright': 222, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 389, - 'plus': 584, - 'comma': 278, - 'hyphen': 333, - 'period': 278, - 'slash': 278, - 'zero': 556, - 'one': 556, - 'two': 556, - 'three': 556, - 'four': 556, - 'five': 556, - 'six': 556, - 'seven': 556, - 'eight': 556, - 'nine': 556, - 'colon': 278, - 'semicolon': 278, - 'less': 584, - 'equal': 584, - 'greater': 584, - 'question': 556, - 'at': 1015, - 'A': 667, - 'B': 667, - 'C': 722, - 'D': 722, - 'E': 667, - 'F': 611, - 'G': 778, - 'H': 722, - 'I': 278, - 'J': 500, - 'K': 667, - 'L': 556, - 'M': 833, - 'N': 722, - 'O': 778, - 'P': 667, - 'Q': 778, - 'R': 722, - 'S': 667, - 'T': 611, - 'U': 722, - 'V': 667, - 'W': 944, - 'X': 667, - 'Y': 667, - 'Z': 611, - 'bracketleft': 278, - 'backslash': 278, - 'bracketright': 278, - 'asciicircum': 469, - 'underscore': 556, - 'quoteleft': 222, - 'a': 556, - 'b': 556, - 'c': 500, - 'd': 556, - 'e': 556, - 'f': 278, - 'g': 556, - 'h': 556, - 'i': 222, - 'j': 222, - 'k': 500, - 'l': 222, - 'm': 833, - 'n': 556, - 'o': 556, - 'p': 556, - 'q': 556, - 'r': 333, - 's': 500, - 't': 278, - 'u': 556, - 'v': 500, - 'w': 722, - 'x': 500, - 'y': 500, - 'z': 500, - 'braceleft': 334, - 'bar': 260, - 'braceright': 334, - 'asciitilde': 584, - 'exclamdown': 333, - 'cent': 556, - 'sterling': 556, - 'fraction': 167, - 'yen': 556, - 'florin': 556, - 'section': 556, - 'currency': 556, - 'quotesingle': 191, - 'quotedblleft': 333, - 'guillemotleft': 556, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 500, - 'fl': 500, - 'endash': 556, - 'dagger': 556, - 'daggerdbl': 556, - 'periodcentered': 278, - 'paragraph': 537, - 'bullet': 350, - 'quotesinglbase': 222, - 'quotedblbase': 333, - 'quotedblright': 333, - 'guillemotright': 556, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 611, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 1000, - 'ordfeminine': 370, - 'Lslash': 556, - 'Oslash': 778, - 'OE': 1000, - 'ordmasculine': 365, - 'ae': 889, - 'dotlessi': 278, - 'lslash': 222, - 'oslash': 611, - 'oe': 944, - 'germandbls': 611, - 'Idieresis': 278, - 'eacute': 556, - 'abreve': 556, - 'uhungarumlaut': 556, - 'ecaron': 556, - 'Ydieresis': 667, - 'divide': 584, - 'Yacute': 667, - 'Acircumflex': 667, - 'aacute': 556, - 'Ucircumflex': 722, - 'yacute': 500, - 'scommaaccent': 500, - 'ecircumflex': 556, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 556, - 'Uacute': 722, - 'uogonek': 556, - 'Edieresis': 667, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 737, - 'Emacron': 667, - 'ccaron': 500, - 'aring': 556, - 'Ncommaaccent': 722, - 'lacute': 222, - 'agrave': 556, - 'Tcommaaccent': 611, - 'Cacute': 722, - 'atilde': 556, - 'Edotaccent': 667, - 'scaron': 500, - 'scedilla': 500, - 'iacute': 278, - 'lozenge': 471, - 'Rcaron': 722, - 'Gcommaaccent': 778, - 'ucircumflex': 556, - 'acircumflex': 556, - 'Amacron': 667, - 'rcaron': 333, - 'ccedilla': 500, - 'Zdotaccent': 611, - 'Thorn': 667, - 'Omacron': 778, - 'Racute': 722, - 'Sacute': 667, - 'dcaron': 643, - 'Umacron': 722, - 'uring': 556, - 'threesuperior': 333, - 'Ograve': 778, - 'Agrave': 667, - 'Abreve': 667, - 'multiply': 584, - 'uacute': 556, - 'Tcaron': 611, - 'partialdiff': 476, - 'ydieresis': 500, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 667, - 'adieresis': 556, - 'edieresis': 556, - 'cacute': 500, - 'nacute': 556, - 'umacron': 556, - 'Ncaron': 722, - 'Iacute': 278, - 'plusminus': 584, - 'brokenbar': 260, - 'registered': 737, - 'Gbreve': 778, - 'Idotaccent': 278, - 'summation': 600, - 'Egrave': 667, - 'racute': 333, - 'omacron': 556, - 'Zacute': 611, - 'Zcaron': 611, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 722, - 'lcommaaccent': 222, - 'tcaron': 317, - 'eogonek': 556, - 'Uogonek': 722, - 'Aacute': 667, - 'Adieresis': 667, - 'egrave': 556, - 'zacute': 500, - 'iogonek': 222, - 'Oacute': 778, - 'oacute': 556, - 'amacron': 556, - 'sacute': 500, - 'idieresis': 278, - 'Ocircumflex': 778, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 556, - 'twosuperior': 333, - 'Odieresis': 778, - 'mu': 556, - 'igrave': 278, - 'ohungarumlaut': 556, - 'Eogonek': 667, - 'dcroat': 556, - 'threequarters': 834, - 'Scedilla': 667, - 'lcaron': 299, - 'Kcommaaccent': 667, - 'Lacute': 556, - 'trademark': 1000, - 'edotaccent': 556, - 'Igrave': 278, - 'Imacron': 278, - 'Lcaron': 556, - 'onehalf': 834, - 'lessequal': 549, - 'ocircumflex': 556, - 'ntilde': 556, - 'Uhungarumlaut': 722, - 'Eacute': 667, - 'emacron': 556, - 'gbreve': 556, - 'onequarter': 834, - 'Scaron': 667, - 'Scommaaccent': 667, - 'Ohungarumlaut': 778, - 'degree': 400, - 'ograve': 556, - 'Ccaron': 722, - 'ugrave': 556, - 'radical': 453, - 'Dcaron': 722, - 'rcommaaccent': 333, - 'Ntilde': 722, - 'otilde': 556, - 'Rcommaaccent': 722, - 'Lcommaaccent': 556, - 'Atilde': 667, - 'Aogonek': 667, - 'Aring': 667, - 'Otilde': 778, - 'zdotaccent': 500, - 'Ecaron': 667, - 'Iogonek': 278, - 'kcommaaccent': 500, - 'minus': 584, - 'Icircumflex': 278, - 'ncaron': 556, - 'tcommaaccent': 278, - 'logicalnot': 584, - 'odieresis': 556, - 'udieresis': 556, - 'notequal': 549, - 'gcommaaccent': 556, - 'eth': 556, - 'zcaron': 500, - 'ncommaaccent': 556, - 'onesuperior': 333, - 'imacron': 278, - 'Euro': 556 - }, - 'Symbol': { - 'space': 250, - 'exclam': 333, - 'universal': 713, - 'numbersign': 500, - 'existential': 549, - 'percent': 833, - 'ampersand': 778, - 'suchthat': 439, - 'parenleft': 333, - 'parenright': 333, - 'asteriskmath': 500, - 'plus': 549, - 'comma': 250, - 'minus': 549, - 'period': 250, - 'slash': 278, - 'zero': 500, - 'one': 500, - 'two': 500, - 'three': 500, - 'four': 500, - 'five': 500, - 'six': 500, - 'seven': 500, - 'eight': 500, - 'nine': 500, - 'colon': 278, - 'semicolon': 278, - 'less': 549, - 'equal': 549, - 'greater': 549, - 'question': 444, - 'congruent': 549, - 'Alpha': 722, - 'Beta': 667, - 'Chi': 722, - 'Delta': 612, - 'Epsilon': 611, - 'Phi': 763, - 'Gamma': 603, - 'Eta': 722, - 'Iota': 333, - 'theta1': 631, - 'Kappa': 722, - 'Lambda': 686, - 'Mu': 889, - 'Nu': 722, - 'Omicron': 722, - 'Pi': 768, - 'Theta': 741, - 'Rho': 556, - 'Sigma': 592, - 'Tau': 611, - 'Upsilon': 690, - 'sigma1': 439, - 'Omega': 768, - 'Xi': 645, - 'Psi': 795, - 'Zeta': 611, - 'bracketleft': 333, - 'therefore': 863, - 'bracketright': 333, - 'perpendicular': 658, - 'underscore': 500, - 'radicalex': 500, - 'alpha': 631, - 'beta': 549, - 'chi': 549, - 'delta': 494, - 'epsilon': 439, - 'phi': 521, - 'gamma': 411, - 'eta': 603, - 'iota': 329, - 'phi1': 603, - 'kappa': 549, - 'lambda': 549, - 'mu': 576, - 'nu': 521, - 'omicron': 549, - 'pi': 549, - 'theta': 521, - 'rho': 549, - 'sigma': 603, - 'tau': 439, - 'upsilon': 576, - 'omega1': 713, - 'omega': 686, - 'xi': 493, - 'psi': 686, - 'zeta': 494, - 'braceleft': 480, - 'bar': 200, - 'braceright': 480, - 'similar': 549, - 'Euro': 750, - 'Upsilon1': 620, - 'minute': 247, - 'lessequal': 549, - 'fraction': 167, - 'infinity': 713, - 'florin': 500, - 'club': 753, - 'diamond': 753, - 'heart': 753, - 'spade': 753, - 'arrowboth': 1042, - 'arrowleft': 987, - 'arrowup': 603, - 'arrowright': 987, - 'arrowdown': 603, - 'degree': 400, - 'plusminus': 549, - 'second': 411, - 'greaterequal': 549, - 'multiply': 549, - 'proportional': 713, - 'partialdiff': 494, - 'bullet': 460, - 'divide': 549, - 'notequal': 549, - 'equivalence': 549, - 'approxequal': 549, - 'ellipsis': 1000, - 'arrowvertex': 603, - 'arrowhorizex': 1000, - 'carriagereturn': 658, - 'aleph': 823, - 'Ifraktur': 686, - 'Rfraktur': 795, - 'weierstrass': 987, - 'circlemultiply': 768, - 'circleplus': 768, - 'emptyset': 823, - 'intersection': 768, - 'union': 768, - 'propersuperset': 713, - 'reflexsuperset': 713, - 'notsubset': 713, - 'propersubset': 713, - 'reflexsubset': 713, - 'element': 713, - 'notelement': 713, - 'angle': 768, - 'gradient': 713, - 'registerserif': 790, - 'copyrightserif': 790, - 'trademarkserif': 890, - 'product': 823, - 'radical': 549, - 'dotmath': 250, - 'logicalnot': 713, - 'logicaland': 603, - 'logicalor': 603, - 'arrowdblboth': 1042, - 'arrowdblleft': 987, - 'arrowdblup': 603, - 'arrowdblright': 987, - 'arrowdbldown': 603, - 'lozenge': 494, - 'angleleft': 329, - 'registersans': 790, - 'copyrightsans': 790, - 'trademarksans': 786, - 'summation': 713, - 'parenlefttp': 384, - 'parenleftex': 384, - 'parenleftbt': 384, - 'bracketlefttp': 384, - 'bracketleftex': 384, - 'bracketleftbt': 384, - 'bracelefttp': 494, - 'braceleftmid': 494, - 'braceleftbt': 494, - 'braceex': 494, - 'angleright': 329, - 'integral': 274, - 'integraltp': 686, - 'integralex': 686, - 'integralbt': 686, - 'parenrighttp': 384, - 'parenrightex': 384, - 'parenrightbt': 384, - 'bracketrighttp': 384, - 'bracketrightex': 384, - 'bracketrightbt': 384, - 'bracerighttp': 494, - 'bracerightmid': 494, - 'bracerightbt': 494, - 'apple': 790 - }, - 'Times-Roman': { - 'space': 250, - 'exclam': 333, - 'quotedbl': 408, - 'numbersign': 500, - 'dollar': 500, - 'percent': 833, - 'ampersand': 778, - 'quoteright': 333, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 500, - 'plus': 564, - 'comma': 250, - 'hyphen': 333, - 'period': 250, - 'slash': 278, - 'zero': 500, - 'one': 500, - 'two': 500, - 'three': 500, - 'four': 500, - 'five': 500, - 'six': 500, - 'seven': 500, - 'eight': 500, - 'nine': 500, - 'colon': 278, - 'semicolon': 278, - 'less': 564, - 'equal': 564, - 'greater': 564, - 'question': 444, - 'at': 921, - 'A': 722, - 'B': 667, - 'C': 667, - 'D': 722, - 'E': 611, - 'F': 556, - 'G': 722, - 'H': 722, - 'I': 333, - 'J': 389, - 'K': 722, - 'L': 611, - 'M': 889, - 'N': 722, - 'O': 722, - 'P': 556, - 'Q': 722, - 'R': 667, - 'S': 556, - 'T': 611, - 'U': 722, - 'V': 722, - 'W': 944, - 'X': 722, - 'Y': 722, - 'Z': 611, - 'bracketleft': 333, - 'backslash': 278, - 'bracketright': 333, - 'asciicircum': 469, - 'underscore': 500, - 'quoteleft': 333, - 'a': 444, - 'b': 500, - 'c': 444, - 'd': 500, - 'e': 444, - 'f': 333, - 'g': 500, - 'h': 500, - 'i': 278, - 'j': 278, - 'k': 500, - 'l': 278, - 'm': 778, - 'n': 500, - 'o': 500, - 'p': 500, - 'q': 500, - 'r': 333, - 's': 389, - 't': 278, - 'u': 500, - 'v': 500, - 'w': 722, - 'x': 500, - 'y': 500, - 'z': 444, - 'braceleft': 480, - 'bar': 200, - 'braceright': 480, - 'asciitilde': 541, - 'exclamdown': 333, - 'cent': 500, - 'sterling': 500, - 'fraction': 167, - 'yen': 500, - 'florin': 500, - 'section': 500, - 'currency': 500, - 'quotesingle': 180, - 'quotedblleft': 444, - 'guillemotleft': 500, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 556, - 'fl': 556, - 'endash': 500, - 'dagger': 500, - 'daggerdbl': 500, - 'periodcentered': 250, - 'paragraph': 453, - 'bullet': 350, - 'quotesinglbase': 333, - 'quotedblbase': 444, - 'quotedblright': 444, - 'guillemotright': 500, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 444, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 889, - 'ordfeminine': 276, - 'Lslash': 611, - 'Oslash': 722, - 'OE': 889, - 'ordmasculine': 310, - 'ae': 667, - 'dotlessi': 278, - 'lslash': 278, - 'oslash': 500, - 'oe': 722, - 'germandbls': 500, - 'Idieresis': 333, - 'eacute': 444, - 'abreve': 444, - 'uhungarumlaut': 500, - 'ecaron': 444, - 'Ydieresis': 722, - 'divide': 564, - 'Yacute': 722, - 'Acircumflex': 722, - 'aacute': 444, - 'Ucircumflex': 722, - 'yacute': 500, - 'scommaaccent': 389, - 'ecircumflex': 444, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 444, - 'Uacute': 722, - 'uogonek': 500, - 'Edieresis': 611, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 760, - 'Emacron': 611, - 'ccaron': 444, - 'aring': 444, - 'Ncommaaccent': 722, - 'lacute': 278, - 'agrave': 444, - 'Tcommaaccent': 611, - 'Cacute': 667, - 'atilde': 444, - 'Edotaccent': 611, - 'scaron': 389, - 'scedilla': 389, - 'iacute': 278, - 'lozenge': 471, - 'Rcaron': 667, - 'Gcommaaccent': 722, - 'ucircumflex': 500, - 'acircumflex': 444, - 'Amacron': 722, - 'rcaron': 333, - 'ccedilla': 444, - 'Zdotaccent': 611, - 'Thorn': 556, - 'Omacron': 722, - 'Racute': 667, - 'Sacute': 556, - 'dcaron': 588, - 'Umacron': 722, - 'uring': 500, - 'threesuperior': 300, - 'Ograve': 722, - 'Agrave': 722, - 'Abreve': 722, - 'multiply': 564, - 'uacute': 500, - 'Tcaron': 611, - 'partialdiff': 476, - 'ydieresis': 500, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 611, - 'adieresis': 444, - 'edieresis': 444, - 'cacute': 444, - 'nacute': 500, - 'umacron': 500, - 'Ncaron': 722, - 'Iacute': 333, - 'plusminus': 564, - 'brokenbar': 200, - 'registered': 760, - 'Gbreve': 722, - 'Idotaccent': 333, - 'summation': 600, - 'Egrave': 611, - 'racute': 333, - 'omacron': 500, - 'Zacute': 611, - 'Zcaron': 611, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 667, - 'lcommaaccent': 278, - 'tcaron': 326, - 'eogonek': 444, - 'Uogonek': 722, - 'Aacute': 722, - 'Adieresis': 722, - 'egrave': 444, - 'zacute': 444, - 'iogonek': 278, - 'Oacute': 722, - 'oacute': 500, - 'amacron': 444, - 'sacute': 389, - 'idieresis': 278, - 'Ocircumflex': 722, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 500, - 'twosuperior': 300, - 'Odieresis': 722, - 'mu': 500, - 'igrave': 278, - 'ohungarumlaut': 500, - 'Eogonek': 611, - 'dcroat': 500, - 'threequarters': 750, - 'Scedilla': 556, - 'lcaron': 344, - 'Kcommaaccent': 722, - 'Lacute': 611, - 'trademark': 980, - 'edotaccent': 444, - 'Igrave': 333, - 'Imacron': 333, - 'Lcaron': 611, - 'onehalf': 750, - 'lessequal': 549, - 'ocircumflex': 500, - 'ntilde': 500, - 'Uhungarumlaut': 722, - 'Eacute': 611, - 'emacron': 444, - 'gbreve': 500, - 'onequarter': 750, - 'Scaron': 556, - 'Scommaaccent': 556, - 'Ohungarumlaut': 722, - 'degree': 400, - 'ograve': 500, - 'Ccaron': 667, - 'ugrave': 500, - 'radical': 453, - 'Dcaron': 722, - 'rcommaaccent': 333, - 'Ntilde': 722, - 'otilde': 500, - 'Rcommaaccent': 667, - 'Lcommaaccent': 611, - 'Atilde': 722, - 'Aogonek': 722, - 'Aring': 722, - 'Otilde': 722, - 'zdotaccent': 444, - 'Ecaron': 611, - 'Iogonek': 333, - 'kcommaaccent': 500, - 'minus': 564, - 'Icircumflex': 333, - 'ncaron': 500, - 'tcommaaccent': 278, - 'logicalnot': 564, - 'odieresis': 500, - 'udieresis': 500, - 'notequal': 549, - 'gcommaaccent': 500, - 'eth': 500, - 'zcaron': 444, - 'ncommaaccent': 500, - 'onesuperior': 300, - 'imacron': 278, - 'Euro': 500 - }, - 'Times-Bold': { - 'space': 250, - 'exclam': 333, - 'quotedbl': 555, - 'numbersign': 500, - 'dollar': 500, - 'percent': 1000, - 'ampersand': 833, - 'quoteright': 333, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 500, - 'plus': 570, - 'comma': 250, - 'hyphen': 333, - 'period': 250, - 'slash': 278, - 'zero': 500, - 'one': 500, - 'two': 500, - 'three': 500, - 'four': 500, - 'five': 500, - 'six': 500, - 'seven': 500, - 'eight': 500, - 'nine': 500, - 'colon': 333, - 'semicolon': 333, - 'less': 570, - 'equal': 570, - 'greater': 570, - 'question': 500, - 'at': 930, - 'A': 722, - 'B': 667, - 'C': 722, - 'D': 722, - 'E': 667, - 'F': 611, - 'G': 778, - 'H': 778, - 'I': 389, - 'J': 500, - 'K': 778, - 'L': 667, - 'M': 944, - 'N': 722, - 'O': 778, - 'P': 611, - 'Q': 778, - 'R': 722, - 'S': 556, - 'T': 667, - 'U': 722, - 'V': 722, - 'W': 1000, - 'X': 722, - 'Y': 722, - 'Z': 667, - 'bracketleft': 333, - 'backslash': 278, - 'bracketright': 333, - 'asciicircum': 581, - 'underscore': 500, - 'quoteleft': 333, - 'a': 500, - 'b': 556, - 'c': 444, - 'd': 556, - 'e': 444, - 'f': 333, - 'g': 500, - 'h': 556, - 'i': 278, - 'j': 333, - 'k': 556, - 'l': 278, - 'm': 833, - 'n': 556, - 'o': 500, - 'p': 556, - 'q': 556, - 'r': 444, - 's': 389, - 't': 333, - 'u': 556, - 'v': 500, - 'w': 722, - 'x': 500, - 'y': 500, - 'z': 444, - 'braceleft': 394, - 'bar': 220, - 'braceright': 394, - 'asciitilde': 520, - 'exclamdown': 333, - 'cent': 500, - 'sterling': 500, - 'fraction': 167, - 'yen': 500, - 'florin': 500, - 'section': 500, - 'currency': 500, - 'quotesingle': 278, - 'quotedblleft': 500, - 'guillemotleft': 500, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 556, - 'fl': 556, - 'endash': 500, - 'dagger': 500, - 'daggerdbl': 500, - 'periodcentered': 250, - 'paragraph': 540, - 'bullet': 350, - 'quotesinglbase': 333, - 'quotedblbase': 500, - 'quotedblright': 500, - 'guillemotright': 500, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 500, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 1000, - 'ordfeminine': 300, - 'Lslash': 667, - 'Oslash': 778, - 'OE': 1000, - 'ordmasculine': 330, - 'ae': 722, - 'dotlessi': 278, - 'lslash': 278, - 'oslash': 500, - 'oe': 722, - 'germandbls': 556, - 'Idieresis': 389, - 'eacute': 444, - 'abreve': 500, - 'uhungarumlaut': 556, - 'ecaron': 444, - 'Ydieresis': 722, - 'divide': 570, - 'Yacute': 722, - 'Acircumflex': 722, - 'aacute': 500, - 'Ucircumflex': 722, - 'yacute': 500, - 'scommaaccent': 389, - 'ecircumflex': 444, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 500, - 'Uacute': 722, - 'uogonek': 556, - 'Edieresis': 667, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 747, - 'Emacron': 667, - 'ccaron': 444, - 'aring': 500, - 'Ncommaaccent': 722, - 'lacute': 278, - 'agrave': 500, - 'Tcommaaccent': 667, - 'Cacute': 722, - 'atilde': 500, - 'Edotaccent': 667, - 'scaron': 389, - 'scedilla': 389, - 'iacute': 278, - 'lozenge': 494, - 'Rcaron': 722, - 'Gcommaaccent': 778, - 'ucircumflex': 556, - 'acircumflex': 500, - 'Amacron': 722, - 'rcaron': 444, - 'ccedilla': 444, - 'Zdotaccent': 667, - 'Thorn': 611, - 'Omacron': 778, - 'Racute': 722, - 'Sacute': 556, - 'dcaron': 672, - 'Umacron': 722, - 'uring': 556, - 'threesuperior': 300, - 'Ograve': 778, - 'Agrave': 722, - 'Abreve': 722, - 'multiply': 570, - 'uacute': 556, - 'Tcaron': 667, - 'partialdiff': 494, - 'ydieresis': 500, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 667, - 'adieresis': 500, - 'edieresis': 444, - 'cacute': 444, - 'nacute': 556, - 'umacron': 556, - 'Ncaron': 722, - 'Iacute': 389, - 'plusminus': 570, - 'brokenbar': 220, - 'registered': 747, - 'Gbreve': 778, - 'Idotaccent': 389, - 'summation': 600, - 'Egrave': 667, - 'racute': 444, - 'omacron': 500, - 'Zacute': 667, - 'Zcaron': 667, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 722, - 'lcommaaccent': 278, - 'tcaron': 416, - 'eogonek': 444, - 'Uogonek': 722, - 'Aacute': 722, - 'Adieresis': 722, - 'egrave': 444, - 'zacute': 444, - 'iogonek': 278, - 'Oacute': 778, - 'oacute': 500, - 'amacron': 500, - 'sacute': 389, - 'idieresis': 278, - 'Ocircumflex': 778, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 556, - 'twosuperior': 300, - 'Odieresis': 778, - 'mu': 556, - 'igrave': 278, - 'ohungarumlaut': 500, - 'Eogonek': 667, - 'dcroat': 556, - 'threequarters': 750, - 'Scedilla': 556, - 'lcaron': 394, - 'Kcommaaccent': 778, - 'Lacute': 667, - 'trademark': 1000, - 'edotaccent': 444, - 'Igrave': 389, - 'Imacron': 389, - 'Lcaron': 667, - 'onehalf': 750, - 'lessequal': 549, - 'ocircumflex': 500, - 'ntilde': 556, - 'Uhungarumlaut': 722, - 'Eacute': 667, - 'emacron': 444, - 'gbreve': 500, - 'onequarter': 750, - 'Scaron': 556, - 'Scommaaccent': 556, - 'Ohungarumlaut': 778, - 'degree': 400, - 'ograve': 500, - 'Ccaron': 722, - 'ugrave': 556, - 'radical': 549, - 'Dcaron': 722, - 'rcommaaccent': 444, - 'Ntilde': 722, - 'otilde': 500, - 'Rcommaaccent': 722, - 'Lcommaaccent': 667, - 'Atilde': 722, - 'Aogonek': 722, - 'Aring': 722, - 'Otilde': 778, - 'zdotaccent': 444, - 'Ecaron': 667, - 'Iogonek': 389, - 'kcommaaccent': 556, - 'minus': 570, - 'Icircumflex': 389, - 'ncaron': 556, - 'tcommaaccent': 333, - 'logicalnot': 570, - 'odieresis': 500, - 'udieresis': 556, - 'notequal': 549, - 'gcommaaccent': 500, - 'eth': 500, - 'zcaron': 444, - 'ncommaaccent': 556, - 'onesuperior': 300, - 'imacron': 278, - 'Euro': 500 - }, - 'Times-BoldItalic': { - 'space': 250, - 'exclam': 389, - 'quotedbl': 555, - 'numbersign': 500, - 'dollar': 500, - 'percent': 833, - 'ampersand': 778, - 'quoteright': 333, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 500, - 'plus': 570, - 'comma': 250, - 'hyphen': 333, - 'period': 250, - 'slash': 278, - 'zero': 500, - 'one': 500, - 'two': 500, - 'three': 500, - 'four': 500, - 'five': 500, - 'six': 500, - 'seven': 500, - 'eight': 500, - 'nine': 500, - 'colon': 333, - 'semicolon': 333, - 'less': 570, - 'equal': 570, - 'greater': 570, - 'question': 500, - 'at': 832, - 'A': 667, - 'B': 667, - 'C': 667, - 'D': 722, - 'E': 667, - 'F': 667, - 'G': 722, - 'H': 778, - 'I': 389, - 'J': 500, - 'K': 667, - 'L': 611, - 'M': 889, - 'N': 722, - 'O': 722, - 'P': 611, - 'Q': 722, - 'R': 667, - 'S': 556, - 'T': 611, - 'U': 722, - 'V': 667, - 'W': 889, - 'X': 667, - 'Y': 611, - 'Z': 611, - 'bracketleft': 333, - 'backslash': 278, - 'bracketright': 333, - 'asciicircum': 570, - 'underscore': 500, - 'quoteleft': 333, - 'a': 500, - 'b': 500, - 'c': 444, - 'd': 500, - 'e': 444, - 'f': 333, - 'g': 500, - 'h': 556, - 'i': 278, - 'j': 278, - 'k': 500, - 'l': 278, - 'm': 778, - 'n': 556, - 'o': 500, - 'p': 500, - 'q': 500, - 'r': 389, - 's': 389, - 't': 278, - 'u': 556, - 'v': 444, - 'w': 667, - 'x': 500, - 'y': 444, - 'z': 389, - 'braceleft': 348, - 'bar': 220, - 'braceright': 348, - 'asciitilde': 570, - 'exclamdown': 389, - 'cent': 500, - 'sterling': 500, - 'fraction': 167, - 'yen': 500, - 'florin': 500, - 'section': 500, - 'currency': 500, - 'quotesingle': 278, - 'quotedblleft': 500, - 'guillemotleft': 500, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 556, - 'fl': 556, - 'endash': 500, - 'dagger': 500, - 'daggerdbl': 500, - 'periodcentered': 250, - 'paragraph': 500, - 'bullet': 350, - 'quotesinglbase': 333, - 'quotedblbase': 500, - 'quotedblright': 500, - 'guillemotright': 500, - 'ellipsis': 1000, - 'perthousand': 1000, - 'questiondown': 500, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 1000, - 'AE': 944, - 'ordfeminine': 266, - 'Lslash': 611, - 'Oslash': 722, - 'OE': 944, - 'ordmasculine': 300, - 'ae': 722, - 'dotlessi': 278, - 'lslash': 278, - 'oslash': 500, - 'oe': 722, - 'germandbls': 500, - 'Idieresis': 389, - 'eacute': 444, - 'abreve': 500, - 'uhungarumlaut': 556, - 'ecaron': 444, - 'Ydieresis': 611, - 'divide': 570, - 'Yacute': 611, - 'Acircumflex': 667, - 'aacute': 500, - 'Ucircumflex': 722, - 'yacute': 444, - 'scommaaccent': 389, - 'ecircumflex': 444, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 500, - 'Uacute': 722, - 'uogonek': 556, - 'Edieresis': 667, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 747, - 'Emacron': 667, - 'ccaron': 444, - 'aring': 500, - 'Ncommaaccent': 722, - 'lacute': 278, - 'agrave': 500, - 'Tcommaaccent': 611, - 'Cacute': 667, - 'atilde': 500, - 'Edotaccent': 667, - 'scaron': 389, - 'scedilla': 389, - 'iacute': 278, - 'lozenge': 494, - 'Rcaron': 667, - 'Gcommaaccent': 722, - 'ucircumflex': 556, - 'acircumflex': 500, - 'Amacron': 667, - 'rcaron': 389, - 'ccedilla': 444, - 'Zdotaccent': 611, - 'Thorn': 611, - 'Omacron': 722, - 'Racute': 667, - 'Sacute': 556, - 'dcaron': 608, - 'Umacron': 722, - 'uring': 556, - 'threesuperior': 300, - 'Ograve': 722, - 'Agrave': 667, - 'Abreve': 667, - 'multiply': 570, - 'uacute': 556, - 'Tcaron': 611, - 'partialdiff': 494, - 'ydieresis': 444, - 'Nacute': 722, - 'icircumflex': 278, - 'Ecircumflex': 667, - 'adieresis': 500, - 'edieresis': 444, - 'cacute': 444, - 'nacute': 556, - 'umacron': 556, - 'Ncaron': 722, - 'Iacute': 389, - 'plusminus': 570, - 'brokenbar': 220, - 'registered': 747, - 'Gbreve': 722, - 'Idotaccent': 389, - 'summation': 600, - 'Egrave': 667, - 'racute': 389, - 'omacron': 500, - 'Zacute': 611, - 'Zcaron': 611, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 667, - 'lcommaaccent': 278, - 'tcaron': 366, - 'eogonek': 444, - 'Uogonek': 722, - 'Aacute': 667, - 'Adieresis': 667, - 'egrave': 444, - 'zacute': 389, - 'iogonek': 278, - 'Oacute': 722, - 'oacute': 500, - 'amacron': 500, - 'sacute': 389, - 'idieresis': 278, - 'Ocircumflex': 722, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 500, - 'twosuperior': 300, - 'Odieresis': 722, - 'mu': 576, - 'igrave': 278, - 'ohungarumlaut': 500, - 'Eogonek': 667, - 'dcroat': 500, - 'threequarters': 750, - 'Scedilla': 556, - 'lcaron': 382, - 'Kcommaaccent': 667, - 'Lacute': 611, - 'trademark': 1000, - 'edotaccent': 444, - 'Igrave': 389, - 'Imacron': 389, - 'Lcaron': 611, - 'onehalf': 750, - 'lessequal': 549, - 'ocircumflex': 500, - 'ntilde': 556, - 'Uhungarumlaut': 722, - 'Eacute': 667, - 'emacron': 444, - 'gbreve': 500, - 'onequarter': 750, - 'Scaron': 556, - 'Scommaaccent': 556, - 'Ohungarumlaut': 722, - 'degree': 400, - 'ograve': 500, - 'Ccaron': 667, - 'ugrave': 556, - 'radical': 549, - 'Dcaron': 722, - 'rcommaaccent': 389, - 'Ntilde': 722, - 'otilde': 500, - 'Rcommaaccent': 667, - 'Lcommaaccent': 611, - 'Atilde': 667, - 'Aogonek': 667, - 'Aring': 667, - 'Otilde': 722, - 'zdotaccent': 389, - 'Ecaron': 667, - 'Iogonek': 389, - 'kcommaaccent': 500, - 'minus': 606, - 'Icircumflex': 389, - 'ncaron': 556, - 'tcommaaccent': 278, - 'logicalnot': 606, - 'odieresis': 500, - 'udieresis': 556, - 'notequal': 549, - 'gcommaaccent': 500, - 'eth': 500, - 'zcaron': 389, - 'ncommaaccent': 556, - 'onesuperior': 300, - 'imacron': 278, - 'Euro': 500 - }, - 'Times-Italic': { - 'space': 250, - 'exclam': 333, - 'quotedbl': 420, - 'numbersign': 500, - 'dollar': 500, - 'percent': 833, - 'ampersand': 778, - 'quoteright': 333, - 'parenleft': 333, - 'parenright': 333, - 'asterisk': 500, - 'plus': 675, - 'comma': 250, - 'hyphen': 333, - 'period': 250, - 'slash': 278, - 'zero': 500, - 'one': 500, - 'two': 500, - 'three': 500, - 'four': 500, - 'five': 500, - 'six': 500, - 'seven': 500, - 'eight': 500, - 'nine': 500, - 'colon': 333, - 'semicolon': 333, - 'less': 675, - 'equal': 675, - 'greater': 675, - 'question': 500, - 'at': 920, - 'A': 611, - 'B': 611, - 'C': 667, - 'D': 722, - 'E': 611, - 'F': 611, - 'G': 722, - 'H': 722, - 'I': 333, - 'J': 444, - 'K': 667, - 'L': 556, - 'M': 833, - 'N': 667, - 'O': 722, - 'P': 611, - 'Q': 722, - 'R': 611, - 'S': 500, - 'T': 556, - 'U': 722, - 'V': 611, - 'W': 833, - 'X': 611, - 'Y': 556, - 'Z': 556, - 'bracketleft': 389, - 'backslash': 278, - 'bracketright': 389, - 'asciicircum': 422, - 'underscore': 500, - 'quoteleft': 333, - 'a': 500, - 'b': 500, - 'c': 444, - 'd': 500, - 'e': 444, - 'f': 278, - 'g': 500, - 'h': 500, - 'i': 278, - 'j': 278, - 'k': 444, - 'l': 278, - 'm': 722, - 'n': 500, - 'o': 500, - 'p': 500, - 'q': 500, - 'r': 389, - 's': 389, - 't': 278, - 'u': 500, - 'v': 444, - 'w': 667, - 'x': 444, - 'y': 444, - 'z': 389, - 'braceleft': 400, - 'bar': 275, - 'braceright': 400, - 'asciitilde': 541, - 'exclamdown': 389, - 'cent': 500, - 'sterling': 500, - 'fraction': 167, - 'yen': 500, - 'florin': 500, - 'section': 500, - 'currency': 500, - 'quotesingle': 214, - 'quotedblleft': 556, - 'guillemotleft': 500, - 'guilsinglleft': 333, - 'guilsinglright': 333, - 'fi': 500, - 'fl': 500, - 'endash': 500, - 'dagger': 500, - 'daggerdbl': 500, - 'periodcentered': 250, - 'paragraph': 523, - 'bullet': 350, - 'quotesinglbase': 333, - 'quotedblbase': 556, - 'quotedblright': 556, - 'guillemotright': 500, - 'ellipsis': 889, - 'perthousand': 1000, - 'questiondown': 500, - 'grave': 333, - 'acute': 333, - 'circumflex': 333, - 'tilde': 333, - 'macron': 333, - 'breve': 333, - 'dotaccent': 333, - 'dieresis': 333, - 'ring': 333, - 'cedilla': 333, - 'hungarumlaut': 333, - 'ogonek': 333, - 'caron': 333, - 'emdash': 889, - 'AE': 889, - 'ordfeminine': 276, - 'Lslash': 556, - 'Oslash': 722, - 'OE': 944, - 'ordmasculine': 310, - 'ae': 667, - 'dotlessi': 278, - 'lslash': 278, - 'oslash': 500, - 'oe': 667, - 'germandbls': 500, - 'Idieresis': 333, - 'eacute': 444, - 'abreve': 500, - 'uhungarumlaut': 500, - 'ecaron': 444, - 'Ydieresis': 556, - 'divide': 675, - 'Yacute': 556, - 'Acircumflex': 611, - 'aacute': 500, - 'Ucircumflex': 722, - 'yacute': 444, - 'scommaaccent': 389, - 'ecircumflex': 444, - 'Uring': 722, - 'Udieresis': 722, - 'aogonek': 500, - 'Uacute': 722, - 'uogonek': 500, - 'Edieresis': 611, - 'Dcroat': 722, - 'commaaccent': 250, - 'copyright': 760, - 'Emacron': 611, - 'ccaron': 444, - 'aring': 500, - 'Ncommaaccent': 667, - 'lacute': 278, - 'agrave': 500, - 'Tcommaaccent': 556, - 'Cacute': 667, - 'atilde': 500, - 'Edotaccent': 611, - 'scaron': 389, - 'scedilla': 389, - 'iacute': 278, - 'lozenge': 471, - 'Rcaron': 611, - 'Gcommaaccent': 722, - 'ucircumflex': 500, - 'acircumflex': 500, - 'Amacron': 611, - 'rcaron': 389, - 'ccedilla': 444, - 'Zdotaccent': 556, - 'Thorn': 611, - 'Omacron': 722, - 'Racute': 611, - 'Sacute': 500, - 'dcaron': 544, - 'Umacron': 722, - 'uring': 500, - 'threesuperior': 300, - 'Ograve': 722, - 'Agrave': 611, - 'Abreve': 611, - 'multiply': 675, - 'uacute': 500, - 'Tcaron': 556, - 'partialdiff': 476, - 'ydieresis': 444, - 'Nacute': 667, - 'icircumflex': 278, - 'Ecircumflex': 611, - 'adieresis': 500, - 'edieresis': 444, - 'cacute': 444, - 'nacute': 500, - 'umacron': 500, - 'Ncaron': 667, - 'Iacute': 333, - 'plusminus': 675, - 'brokenbar': 275, - 'registered': 760, - 'Gbreve': 722, - 'Idotaccent': 333, - 'summation': 600, - 'Egrave': 611, - 'racute': 389, - 'omacron': 500, - 'Zacute': 556, - 'Zcaron': 556, - 'greaterequal': 549, - 'Eth': 722, - 'Ccedilla': 667, - 'lcommaaccent': 278, - 'tcaron': 300, - 'eogonek': 444, - 'Uogonek': 722, - 'Aacute': 611, - 'Adieresis': 611, - 'egrave': 444, - 'zacute': 389, - 'iogonek': 278, - 'Oacute': 722, - 'oacute': 500, - 'amacron': 500, - 'sacute': 389, - 'idieresis': 278, - 'Ocircumflex': 722, - 'Ugrave': 722, - 'Delta': 612, - 'thorn': 500, - 'twosuperior': 300, - 'Odieresis': 722, - 'mu': 500, - 'igrave': 278, - 'ohungarumlaut': 500, - 'Eogonek': 611, - 'dcroat': 500, - 'threequarters': 750, - 'Scedilla': 500, - 'lcaron': 300, - 'Kcommaaccent': 667, - 'Lacute': 556, - 'trademark': 980, - 'edotaccent': 444, - 'Igrave': 333, - 'Imacron': 333, - 'Lcaron': 611, - 'onehalf': 750, - 'lessequal': 549, - 'ocircumflex': 500, - 'ntilde': 500, - 'Uhungarumlaut': 722, - 'Eacute': 611, - 'emacron': 444, - 'gbreve': 500, - 'onequarter': 750, - 'Scaron': 500, - 'Scommaaccent': 500, - 'Ohungarumlaut': 722, - 'degree': 400, - 'ograve': 500, - 'Ccaron': 667, - 'ugrave': 500, - 'radical': 453, - 'Dcaron': 722, - 'rcommaaccent': 389, - 'Ntilde': 667, - 'otilde': 500, - 'Rcommaaccent': 611, - 'Lcommaaccent': 556, - 'Atilde': 611, - 'Aogonek': 611, - 'Aring': 611, - 'Otilde': 722, - 'zdotaccent': 389, - 'Ecaron': 611, - 'Iogonek': 333, - 'kcommaaccent': 444, - 'minus': 675, - 'Icircumflex': 333, - 'ncaron': 500, - 'tcommaaccent': 278, - 'logicalnot': 675, - 'odieresis': 500, - 'udieresis': 500, - 'notequal': 549, - 'gcommaaccent': 500, - 'eth': 500, - 'zcaron': 389, - 'ncommaaccent': 500, - 'onesuperior': 300, - 'imacron': 278, - 'Euro': 500 - }, - 'ZapfDingbats': { - 'space': 278, - 'a1': 974, - 'a2': 961, - 'a202': 974, - 'a3': 980, - 'a4': 719, - 'a5': 789, - 'a119': 790, - 'a118': 791, - 'a117': 690, - 'a11': 960, - 'a12': 939, - 'a13': 549, - 'a14': 855, - 'a15': 911, - 'a16': 933, - 'a105': 911, - 'a17': 945, - 'a18': 974, - 'a19': 755, - 'a20': 846, - 'a21': 762, - 'a22': 761, - 'a23': 571, - 'a24': 677, - 'a25': 763, - 'a26': 760, - 'a27': 759, - 'a28': 754, - 'a6': 494, - 'a7': 552, - 'a8': 537, - 'a9': 577, - 'a10': 692, - 'a29': 786, - 'a30': 788, - 'a31': 788, - 'a32': 790, - 'a33': 793, - 'a34': 794, - 'a35': 816, - 'a36': 823, - 'a37': 789, - 'a38': 841, - 'a39': 823, - 'a40': 833, - 'a41': 816, - 'a42': 831, - 'a43': 923, - 'a44': 744, - 'a45': 723, - 'a46': 749, - 'a47': 790, - 'a48': 792, - 'a49': 695, - 'a50': 776, - 'a51': 768, - 'a52': 792, - 'a53': 759, - 'a54': 707, - 'a55': 708, - 'a56': 682, - 'a57': 701, - 'a58': 826, - 'a59': 815, - 'a60': 789, - 'a61': 789, - 'a62': 707, - 'a63': 687, - 'a64': 696, - 'a65': 689, - 'a66': 786, - 'a67': 787, - 'a68': 713, - 'a69': 791, - 'a70': 785, - 'a71': 791, - 'a72': 873, - 'a73': 761, - 'a74': 762, - 'a203': 762, - 'a75': 759, - 'a204': 759, - 'a76': 892, - 'a77': 892, - 'a78': 788, - 'a79': 784, - 'a81': 438, - 'a82': 138, - 'a83': 277, - 'a84': 415, - 'a97': 392, - 'a98': 392, - 'a99': 668, - 'a100': 668, - 'a89': 390, - 'a90': 390, - 'a93': 317, - 'a94': 317, - 'a91': 276, - 'a92': 276, - 'a205': 509, - 'a85': 509, - 'a206': 410, - 'a86': 410, - 'a87': 234, - 'a88': 234, - 'a95': 334, - 'a96': 334, - 'a101': 732, - 'a102': 544, - 'a103': 544, - 'a104': 910, - 'a106': 667, - 'a107': 760, - 'a108': 760, - 'a112': 776, - 'a111': 595, - 'a110': 694, - 'a109': 626, - 'a120': 788, - 'a121': 788, - 'a122': 788, - 'a123': 788, - 'a124': 788, - 'a125': 788, - 'a126': 788, - 'a127': 788, - 'a128': 788, - 'a129': 788, - 'a130': 788, - 'a131': 788, - 'a132': 788, - 'a133': 788, - 'a134': 788, - 'a135': 788, - 'a136': 788, - 'a137': 788, - 'a138': 788, - 'a139': 788, - 'a140': 788, - 'a141': 788, - 'a142': 788, - 'a143': 788, - 'a144': 788, - 'a145': 788, - 'a146': 788, - 'a147': 788, - 'a148': 788, - 'a149': 788, - 'a150': 788, - 'a151': 788, - 'a152': 788, - 'a153': 788, - 'a154': 788, - 'a155': 788, - 'a156': 788, - 'a157': 788, - 'a158': 788, - 'a159': 788, - 'a160': 894, - 'a161': 838, - 'a163': 1016, - 'a164': 458, - 'a196': 748, - 'a165': 924, - 'a192': 748, - 'a166': 918, - 'a167': 927, - 'a168': 928, - 'a169': 928, - 'a170': 834, - 'a171': 873, - 'a172': 828, - 'a173': 924, - 'a162': 924, - 'a174': 917, - 'a175': 930, - 'a176': 931, - 'a177': 463, - 'a178': 883, - 'a179': 836, - 'a193': 836, - 'a180': 867, - 'a199': 867, - 'a181': 696, - 'a200': 696, - 'a182': 874, - 'a201': 874, - 'a183': 760, - 'a184': 946, - 'a197': 771, - 'a185': 865, - 'a194': 771, - 'a198': 888, - 'a186': 967, - 'a195': 888, - 'a187': 831, - 'a188': 873, - 'a189': 927, - 'a190': 970, - 'a191': 918 - } -}; - - -var EOF = {}; - -function isEOF(v) { - return (v === EOF); -} - -var MAX_LENGTH_TO_CACHE = 1000; - -var Parser = (function ParserClosure() { - function Parser(lexer, allowStreams, xref) { - this.lexer = lexer; - this.allowStreams = allowStreams; - this.xref = xref; - this.imageCache = {}; - this.refill(); - } - - Parser.prototype = { - refill: function Parser_refill() { - this.buf1 = this.lexer.getObj(); - this.buf2 = this.lexer.getObj(); - }, - shift: function Parser_shift() { - if (isCmd(this.buf2, 'ID')) { - this.buf1 = this.buf2; - this.buf2 = null; - } else { - this.buf1 = this.buf2; - this.buf2 = this.lexer.getObj(); - } - }, - getObj: function Parser_getObj(cipherTransform) { - var buf1 = this.buf1; - this.shift(); - - if (buf1 instanceof Cmd) { - switch (buf1.cmd) { - case 'BI': // inline image - return this.makeInlineImage(cipherTransform); - case '[': // array - var array = []; - while (!isCmd(this.buf1, ']') && !isEOF(this.buf1)) { - array.push(this.getObj(cipherTransform)); - } - if (isEOF(this.buf1)) { - error('End of file inside array'); - } - this.shift(); - return array; - case '<<': // dictionary or stream - var dict = new Dict(this.xref); - while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) { - if (!isName(this.buf1)) { - info('Malformed dictionary: key must be a name object'); - this.shift(); - continue; - } - - var key = this.buf1.name; - this.shift(); - if (isEOF(this.buf1)) { - break; - } - dict.set(key, this.getObj(cipherTransform)); - } - if (isEOF(this.buf1)) { - error('End of file inside dictionary'); - } - - // Stream objects are not allowed inside content streams or - // object streams. - if (isCmd(this.buf2, 'stream')) { - return (this.allowStreams ? - this.makeStream(dict, cipherTransform) : dict); - } - this.shift(); - return dict; - default: // simple object - return buf1; - } - } - - if (isInt(buf1)) { // indirect reference or integer - var num = buf1; - if (isInt(this.buf1) && isCmd(this.buf2, 'R')) { - var ref = new Ref(num, this.buf1); - this.shift(); - this.shift(); - return ref; - } - return num; - } - - if (isString(buf1)) { // string - var str = buf1; - if (cipherTransform) { - str = cipherTransform.decryptString(str); - } - return str; - } - - // simple object - return buf1; - }, - /** - * Find the end of the stream by searching for the /EI\s/. - * @returns {number} The inline stream length. - */ - findDefaultInlineStreamEnd: - function Parser_findDefaultInlineStreamEnd(stream) { - var E = 0x45, I = 0x49, SPACE = 0x20, LF = 0xA, CR = 0xD; - var startPos = stream.pos, state = 0, ch, i, n, followingBytes; - while ((ch = stream.getByte()) !== -1) { - if (state === 0) { - state = (ch === E) ? 1 : 0; - } else if (state === 1) { - state = (ch === I) ? 2 : 0; - } else { - assert(state === 2); - if (ch === SPACE || ch === LF || ch === CR) { - // Let's check the next five bytes are ASCII... just be sure. - n = 5; - followingBytes = stream.peekBytes(n); - for (i = 0; i < n; i++) { - ch = followingBytes[i]; - if (ch !== LF && ch !== CR && (ch < SPACE || ch > 0x7F)) { - // Not a LF, CR, SPACE or any visible ASCII character, i.e. - // it's binary stuff. Resetting the state. - state = 0; - break; - } - } - if (state === 2) { - break; // Finished! - } - } else { - state = 0; - } - } - } - return ((stream.pos - 4) - startPos); - }, - /** - * Find the EOI (end-of-image) marker 0xFFD9 of the stream. - * @returns {number} The inline stream length. - */ - findDCTDecodeInlineStreamEnd: - function Parser_findDCTDecodeInlineStreamEnd(stream) { - var startPos = stream.pos, foundEOI = false, b, markerLength, length; - while ((b = stream.getByte()) !== -1) { - if (b !== 0xFF) { // Not a valid marker. - continue; - } - switch (stream.getByte()) { - case 0x00: // Byte stuffing. - // 0xFF00 appears to be a very common byte sequence in JPEG images. - break; - - case 0xFF: // Fill byte. - // Avoid skipping a valid marker, resetting the stream position. - stream.skip(-1); - break; - - case 0xD9: // EOI - foundEOI = true; - break; - - case 0xC0: // SOF0 - case 0xC1: // SOF1 - case 0xC2: // SOF2 - case 0xC3: // SOF3 - - case 0xC5: // SOF5 - case 0xC6: // SOF6 - case 0xC7: // SOF7 - - case 0xC9: // SOF9 - case 0xCA: // SOF10 - case 0xCB: // SOF11 - - case 0xCD: // SOF13 - case 0xCE: // SOF14 - case 0xCF: // SOF15 - - case 0xC4: // DHT - case 0xCC: // DAC - - case 0xDA: // SOS - case 0xDB: // DQT - case 0xDC: // DNL - case 0xDD: // DRI - case 0xDE: // DHP - case 0xDF: // EXP - - case 0xE0: // APP0 - case 0xE1: // APP1 - case 0xE2: // APP2 - case 0xE3: // APP3 - case 0xE4: // APP4 - case 0xE5: // APP5 - case 0xE6: // APP6 - case 0xE7: // APP7 - case 0xE8: // APP8 - case 0xE9: // APP9 - case 0xEA: // APP10 - case 0xEB: // APP11 - case 0xEC: // APP12 - case 0xED: // APP13 - case 0xEE: // APP14 - case 0xEF: // APP15 - - case 0xFE: // COM - // The marker should be followed by the length of the segment. - markerLength = stream.getUint16(); - if (markerLength > 2) { - // |markerLength| contains the byte length of the marker segment, - // including its own length (2 bytes) and excluding the marker. - stream.skip(markerLength - 2); // Jump to the next marker. - } else { - // The marker length is invalid, resetting the stream position. - stream.skip(-2); - } - break; - } - if (foundEOI) { - break; - } - } - length = stream.pos - startPos; - if (b === -1) { - warn('Inline DCTDecode image stream: ' + - 'EOI marker not found, searching for /EI/ instead.'); - stream.skip(-length); // Reset the stream position. - return this.findDefaultInlineStreamEnd(stream); - } - this.inlineStreamSkipEI(stream); - return length; - }, - /** - * Find the EOD (end-of-data) marker '~>' (i.e. TILDE + GT) of the stream. - * @returns {number} The inline stream length. - */ - findASCII85DecodeInlineStreamEnd: - function Parser_findASCII85DecodeInlineStreamEnd(stream) { - var TILDE = 0x7E, GT = 0x3E; - var startPos = stream.pos, ch, length; - while ((ch = stream.getByte()) !== -1) { - if (ch === TILDE && stream.peekByte() === GT) { - stream.skip(); - break; - } - } - length = stream.pos - startPos; - if (ch === -1) { - warn('Inline ASCII85Decode image stream: ' + - 'EOD marker not found, searching for /EI/ instead.'); - stream.skip(-length); // Reset the stream position. - return this.findDefaultInlineStreamEnd(stream); - } - this.inlineStreamSkipEI(stream); - return length; - }, - /** - * Find the EOD (end-of-data) marker '>' (i.e. GT) of the stream. - * @returns {number} The inline stream length. - */ - findASCIIHexDecodeInlineStreamEnd: - function Parser_findASCIIHexDecodeInlineStreamEnd(stream) { - var GT = 0x3E; - var startPos = stream.pos, ch, length; - while ((ch = stream.getByte()) !== -1) { - if (ch === GT) { - break; - } - } - length = stream.pos - startPos; - if (ch === -1) { - warn('Inline ASCIIHexDecode image stream: ' + - 'EOD marker not found, searching for /EI/ instead.'); - stream.skip(-length); // Reset the stream position. - return this.findDefaultInlineStreamEnd(stream); - } - this.inlineStreamSkipEI(stream); - return length; - }, - /** - * Skip over the /EI/ for streams where we search for an EOD marker. - */ - inlineStreamSkipEI: function Parser_inlineStreamSkipEI(stream) { - var E = 0x45, I = 0x49; - var state = 0, ch; - while ((ch = stream.getByte()) !== -1) { - if (state === 0) { - state = (ch === E) ? 1 : 0; - } else if (state === 1) { - state = (ch === I) ? 2 : 0; - } else if (state === 2) { - break; - } - } - }, - makeInlineImage: function Parser_makeInlineImage(cipherTransform) { - var lexer = this.lexer; - var stream = lexer.stream; - - // Parse dictionary. - var dict = new Dict(null); - while (!isCmd(this.buf1, 'ID') && !isEOF(this.buf1)) { - if (!isName(this.buf1)) { - error('Dictionary key must be a name object'); - } - var key = this.buf1.name; - this.shift(); - if (isEOF(this.buf1)) { - break; - } - dict.set(key, this.getObj(cipherTransform)); - } - - // Extract the name of the first (i.e. the current) image filter. - var filter = this.fetchIfRef(dict.get('Filter', 'F')), filterName; - if (isName(filter)) { - filterName = filter.name; - } else if (isArray(filter) && isName(filter[0])) { - filterName = filter[0].name; - } - - // Parse image stream. - var startPos = stream.pos, length, i, ii; - if (filterName === 'DCTDecode' || filterName === 'DCT') { - length = this.findDCTDecodeInlineStreamEnd(stream); - } else if (filterName === 'ASCII85Decide' || filterName === 'A85') { - length = this.findASCII85DecodeInlineStreamEnd(stream); - } else if (filterName === 'ASCIIHexDecode' || filterName === 'AHx') { - length = this.findASCIIHexDecodeInlineStreamEnd(stream); - } else { - length = this.findDefaultInlineStreamEnd(stream); - } - var imageStream = stream.makeSubStream(startPos, length, dict); - - // Cache all images below the MAX_LENGTH_TO_CACHE threshold by their - // adler32 checksum. - var adler32; - if (length < MAX_LENGTH_TO_CACHE) { - var imageBytes = imageStream.getBytes(); - imageStream.reset(); - - var a = 1; - var b = 0; - for (i = 0, ii = imageBytes.length; i < ii; ++i) { - // No modulo required in the loop if imageBytes.length < 5552. - a += imageBytes[i] & 0xff; - b += a; - } - adler32 = ((b % 65521) << 16) | (a % 65521); - - if (this.imageCache.adler32 === adler32) { - this.buf2 = Cmd.get('EI'); - this.shift(); - - this.imageCache[adler32].reset(); - return this.imageCache[adler32]; - } - } - - if (cipherTransform) { - imageStream = cipherTransform.createStream(imageStream, length); - } - - imageStream = this.filter(imageStream, dict, length); - imageStream.dict = dict; - if (adler32 !== undefined) { - imageStream.cacheKey = 'inline_' + length + '_' + adler32; - this.imageCache[adler32] = imageStream; - } - - this.buf2 = Cmd.get('EI'); - this.shift(); - - return imageStream; - }, - fetchIfRef: function Parser_fetchIfRef(obj) { - // not relying on the xref.fetchIfRef -- xref might not be set - return (isRef(obj) ? this.xref.fetch(obj) : obj); - }, - makeStream: function Parser_makeStream(dict, cipherTransform) { - var lexer = this.lexer; - var stream = lexer.stream; - - // get stream start position - lexer.skipToNextLine(); - var pos = stream.pos - 1; - - // get length - var length = this.fetchIfRef(dict.get('Length')); - if (!isInt(length)) { - info('Bad ' + length + ' attribute in stream'); - length = 0; - } - - // skip over the stream data - stream.pos = pos + length; - lexer.nextChar(); - - this.shift(); // '>>' - this.shift(); // 'stream' - if (!isCmd(this.buf1, 'endstream')) { - // bad stream length, scanning for endstream - stream.pos = pos; - var SCAN_BLOCK_SIZE = 2048; - var ENDSTREAM_SIGNATURE_LENGTH = 9; - var ENDSTREAM_SIGNATURE = [0x65, 0x6E, 0x64, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6D]; - var skipped = 0, found = false, i, j; - while (stream.pos < stream.end) { - var scanBytes = stream.peekBytes(SCAN_BLOCK_SIZE); - var scanLength = scanBytes.length - ENDSTREAM_SIGNATURE_LENGTH; - if (scanLength <= 0) { - break; - } - found = false; - for (i = 0, j = 0; i < scanLength; i++) { - var b = scanBytes[i]; - if (b !== ENDSTREAM_SIGNATURE[j]) { - i -= j; - j = 0; - } else { - j++; - if (j >= ENDSTREAM_SIGNATURE_LENGTH) { - i++; - found = true; - break; - } - } - } - if (found) { - skipped += i - ENDSTREAM_SIGNATURE_LENGTH; - stream.pos += i - ENDSTREAM_SIGNATURE_LENGTH; - break; - } - skipped += scanLength; - stream.pos += scanLength; - } - if (!found) { - error('Missing endstream'); - } - length = skipped; - - lexer.nextChar(); - this.shift(); - this.shift(); - } - this.shift(); // 'endstream' - - stream = stream.makeSubStream(pos, length, dict); - if (cipherTransform) { - stream = cipherTransform.createStream(stream, length); - } - stream = this.filter(stream, dict, length); - stream.dict = dict; - return stream; - }, - filter: function Parser_filter(stream, dict, length) { - var filter = this.fetchIfRef(dict.get('Filter', 'F')); - var params = this.fetchIfRef(dict.get('DecodeParms', 'DP')); - if (isName(filter)) { - return this.makeFilter(stream, filter.name, length, params); - } - - var maybeLength = length; - if (isArray(filter)) { - var filterArray = filter; - var paramsArray = params; - for (var i = 0, ii = filterArray.length; i < ii; ++i) { - filter = filterArray[i]; - if (!isName(filter)) { - error('Bad filter name: ' + filter); - } - - params = null; - if (isArray(paramsArray) && (i in paramsArray)) { - params = paramsArray[i]; - } - stream = this.makeFilter(stream, filter.name, maybeLength, params); - // after the first stream the length variable is invalid - maybeLength = null; - } - } - return stream; - }, - makeFilter: function Parser_makeFilter(stream, name, maybeLength, params) { - if (stream.dict.get('Length') === 0) { - return new NullStream(stream); - } - try { - if (params) { - params = this.fetchIfRef(params); - } - var xrefStreamStats = this.xref.stats.streamTypes; - if (name === 'FlateDecode' || name === 'Fl') { - xrefStreamStats[StreamType.FLATE] = true; - if (params) { - return new PredictorStream(new FlateStream(stream, maybeLength), - maybeLength, params); - } - return new FlateStream(stream, maybeLength); - } - if (name === 'LZWDecode' || name === 'LZW') { - xrefStreamStats[StreamType.LZW] = true; - var earlyChange = 1; - if (params) { - if (params.has('EarlyChange')) { - earlyChange = params.get('EarlyChange'); - } - return new PredictorStream( - new LZWStream(stream, maybeLength, earlyChange), - maybeLength, params); - } - return new LZWStream(stream, maybeLength, earlyChange); - } - if (name === 'DCTDecode' || name === 'DCT') { - xrefStreamStats[StreamType.DCT] = true; - return new JpegStream(stream, maybeLength, stream.dict, this.xref); - } - if (name === 'JPXDecode' || name === 'JPX') { - xrefStreamStats[StreamType.JPX] = true; - return new JpxStream(stream, maybeLength, stream.dict); - } - if (name === 'ASCII85Decode' || name === 'A85') { - xrefStreamStats[StreamType.A85] = true; - return new Ascii85Stream(stream, maybeLength); - } - if (name === 'ASCIIHexDecode' || name === 'AHx') { - xrefStreamStats[StreamType.AHX] = true; - return new AsciiHexStream(stream, maybeLength); - } - if (name === 'CCITTFaxDecode' || name === 'CCF') { - xrefStreamStats[StreamType.CCF] = true; - return new CCITTFaxStream(stream, maybeLength, params); - } - if (name === 'RunLengthDecode' || name === 'RL') { - xrefStreamStats[StreamType.RL] = true; - return new RunLengthStream(stream, maybeLength); - } - if (name === 'JBIG2Decode') { - xrefStreamStats[StreamType.JBIG] = true; - return new Jbig2Stream(stream, maybeLength, stream.dict); - } - warn('filter "' + name + '" not supported yet'); - return stream; - } catch (ex) { - if (ex instanceof MissingDataException) { - throw ex; - } - warn('Invalid stream: \"' + ex + '\"'); - return new NullStream(stream); - } - } - }; - - return Parser; -})(); - -var Lexer = (function LexerClosure() { - function Lexer(stream, knownCommands) { - this.stream = stream; - this.nextChar(); - - // While lexing, we build up many strings one char at a time. Using += for - // this can result in lots of garbage strings. It's better to build an - // array of single-char strings and then join() them together at the end. - // And reusing a single array (i.e. |this.strBuf|) over and over for this - // purpose uses less memory than using a new array for each string. - this.strBuf = []; - - // The PDFs might have "glued" commands with other commands, operands or - // literals, e.g. "q1". The knownCommands is a dictionary of the valid - // commands and their prefixes. The prefixes are built the following way: - // if there a command that is a prefix of the other valid command or - // literal (e.g. 'f' and 'false') the following prefixes must be included, - // 'fa', 'fal', 'fals'. The prefixes are not needed, if the command has no - // other commands or literals as a prefix. The knowCommands is optional. - this.knownCommands = knownCommands; - } - - Lexer.isSpace = function Lexer_isSpace(ch) { - // Space is one of the following characters: SPACE, TAB, CR or LF. - return (ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A); - }; - - // A '1' in this array means the character is white space. A '1' or - // '2' means the character ends a name or command. - var specialChars = [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x - 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx - ]; - - function toHexDigit(ch) { - if (ch >= 0x30 && ch <= 0x39) { // '0'-'9' - return ch & 0x0F; - } - if ((ch >= 0x41 && ch <= 0x46) || (ch >= 0x61 && ch <= 0x66)) { - // 'A'-'F', 'a'-'f' - return (ch & 0x0F) + 9; - } - return -1; - } - - Lexer.prototype = { - nextChar: function Lexer_nextChar() { - return (this.currentChar = this.stream.getByte()); - }, - peekChar: function Lexer_peekChar() { - return this.stream.peekByte(); - }, - getNumber: function Lexer_getNumber() { - var ch = this.currentChar; - var eNotation = false; - var divideBy = 0; // different from 0 if it's a floating point value - var sign = 1; - - if (ch === 0x2D) { // '-' - sign = -1; - ch = this.nextChar(); - } else if (ch === 0x2B) { // '+' - ch = this.nextChar(); - } - if (ch === 0x2E) { // '.' - divideBy = 10; - ch = this.nextChar(); - } - if (ch < 0x30 || ch > 0x39) { // '0' - '9' - error('Invalid number: ' + String.fromCharCode(ch)); - return 0; - } - - var baseValue = ch - 0x30; // '0' - var powerValue = 0; - var powerValueSign = 1; - - while ((ch = this.nextChar()) >= 0) { - if (0x30 <= ch && ch <= 0x39) { // '0' - '9' - var currentDigit = ch - 0x30; // '0' - if (eNotation) { // We are after an 'e' or 'E' - powerValue = powerValue * 10 + currentDigit; - } else { - if (divideBy !== 0) { // We are after a point - divideBy *= 10; - } - baseValue = baseValue * 10 + currentDigit; - } - } else if (ch === 0x2E) { // '.' - if (divideBy === 0) { - divideBy = 1; - } else { - // A number can have only one '.' - break; - } - } else if (ch === 0x2D) { // '-' - // ignore minus signs in the middle of numbers to match - // Adobe's behavior - warn('Badly formated number'); - } else if (ch === 0x45 || ch === 0x65) { // 'E', 'e' - // 'E' can be either a scientific notation or the beginning of a new - // operator - ch = this.peekChar(); - if (ch === 0x2B || ch === 0x2D) { // '+', '-' - powerValueSign = (ch === 0x2D) ? -1 : 1; - this.nextChar(); // Consume the sign character - } else if (ch < 0x30 || ch > 0x39) { // '0' - '9' - // The 'E' must be the beginning of a new operator - break; - } - eNotation = true; - } else { - // the last character doesn't belong to us - break; - } - } - - if (divideBy !== 0) { - baseValue /= divideBy; - } - if (eNotation) { - baseValue *= Math.pow(10, powerValueSign * powerValue); - } - return sign * baseValue; - }, - getString: function Lexer_getString() { - var numParen = 1; - var done = false; - var strBuf = this.strBuf; - strBuf.length = 0; - - var ch = this.nextChar(); - while (true) { - var charBuffered = false; - switch (ch | 0) { - case -1: - warn('Unterminated string'); - done = true; - break; - case 0x28: // '(' - ++numParen; - strBuf.push('('); - break; - case 0x29: // ')' - if (--numParen === 0) { - this.nextChar(); // consume strings ')' - done = true; - } else { - strBuf.push(')'); - } - break; - case 0x5C: // '\\' - ch = this.nextChar(); - switch (ch) { - case -1: - warn('Unterminated string'); - done = true; - break; - case 0x6E: // 'n' - strBuf.push('\n'); - break; - case 0x72: // 'r' - strBuf.push('\r'); - break; - case 0x74: // 't' - strBuf.push('\t'); - break; - case 0x62: // 'b' - strBuf.push('\b'); - break; - case 0x66: // 'f' - strBuf.push('\f'); - break; - case 0x5C: // '\' - case 0x28: // '(' - case 0x29: // ')' - strBuf.push(String.fromCharCode(ch)); - break; - case 0x30: case 0x31: case 0x32: case 0x33: // '0'-'3' - case 0x34: case 0x35: case 0x36: case 0x37: // '4'-'7' - var x = ch & 0x0F; - ch = this.nextChar(); - charBuffered = true; - if (ch >= 0x30 && ch <= 0x37) { // '0'-'7' - x = (x << 3) + (ch & 0x0F); - ch = this.nextChar(); - if (ch >= 0x30 && ch <= 0x37) { // '0'-'7' - charBuffered = false; - x = (x << 3) + (ch & 0x0F); - } - } - strBuf.push(String.fromCharCode(x)); - break; - case 0x0D: // CR - if (this.peekChar() === 0x0A) { // LF - this.nextChar(); - } - break; - case 0x0A: // LF - break; - default: - strBuf.push(String.fromCharCode(ch)); - break; - } - break; - default: - strBuf.push(String.fromCharCode(ch)); - break; - } - if (done) { - break; - } - if (!charBuffered) { - ch = this.nextChar(); - } - } - return strBuf.join(''); - }, - getName: function Lexer_getName() { - var ch; - var strBuf = this.strBuf; - strBuf.length = 0; - while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) { - if (ch === 0x23) { // '#' - ch = this.nextChar(); - var x = toHexDigit(ch); - if (x !== -1) { - var x2 = toHexDigit(this.nextChar()); - if (x2 === -1) { - error('Illegal digit in hex char in name: ' + x2); - } - strBuf.push(String.fromCharCode((x << 4) | x2)); - } else { - strBuf.push('#', String.fromCharCode(ch)); - } - } else { - strBuf.push(String.fromCharCode(ch)); - } - } - if (strBuf.length > 128) { - error('Warning: name token is longer than allowed by the spec: ' + - strBuf.length); - } - return Name.get(strBuf.join('')); - }, - getHexString: function Lexer_getHexString() { - var strBuf = this.strBuf; - strBuf.length = 0; - var ch = this.currentChar; - var isFirstHex = true; - var firstDigit; - var secondDigit; - while (true) { - if (ch < 0) { - warn('Unterminated hex string'); - break; - } else if (ch === 0x3E) { // '>' - this.nextChar(); - break; - } else if (specialChars[ch] === 1) { - ch = this.nextChar(); - continue; - } else { - if (isFirstHex) { - firstDigit = toHexDigit(ch); - if (firstDigit === -1) { - warn('Ignoring invalid character "' + ch + '" in hex string'); - ch = this.nextChar(); - continue; - } - } else { - secondDigit = toHexDigit(ch); - if (secondDigit === -1) { - warn('Ignoring invalid character "' + ch + '" in hex string'); - ch = this.nextChar(); - continue; - } - strBuf.push(String.fromCharCode((firstDigit << 4) | secondDigit)); - } - isFirstHex = !isFirstHex; - ch = this.nextChar(); - } - } - return strBuf.join(''); - }, - getObj: function Lexer_getObj() { - // skip whitespace and comments - var comment = false; - var ch = this.currentChar; - while (true) { - if (ch < 0) { - return EOF; - } - if (comment) { - if (ch === 0x0A || ch === 0x0D) { // LF, CR - comment = false; - } - } else if (ch === 0x25) { // '%' - comment = true; - } else if (specialChars[ch] !== 1) { - break; - } - ch = this.nextChar(); - } - - // start reading token - switch (ch | 0) { - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4' - case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9' - case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.' - return this.getNumber(); - case 0x28: // '(' - return this.getString(); - case 0x2F: // '/' - return this.getName(); - // array punctuation - case 0x5B: // '[' - this.nextChar(); - return Cmd.get('['); - case 0x5D: // ']' - this.nextChar(); - return Cmd.get(']'); - // hex string or dict punctuation - case 0x3C: // '<' - ch = this.nextChar(); - if (ch === 0x3C) { - // dict punctuation - this.nextChar(); - return Cmd.get('<<'); - } - return this.getHexString(); - // dict punctuation - case 0x3E: // '>' - ch = this.nextChar(); - if (ch === 0x3E) { - this.nextChar(); - return Cmd.get('>>'); - } - return Cmd.get('>'); - case 0x7B: // '{' - this.nextChar(); - return Cmd.get('{'); - case 0x7D: // '}' - this.nextChar(); - return Cmd.get('}'); - case 0x29: // ')' - error('Illegal character: ' + ch); - break; - } - - // command - var str = String.fromCharCode(ch); - var knownCommands = this.knownCommands; - var knownCommandFound = knownCommands && knownCommands[str] !== undefined; - while ((ch = this.nextChar()) >= 0 && !specialChars[ch]) { - // stop if known command is found and next character does not make - // the str a command - var possibleCommand = str + String.fromCharCode(ch); - if (knownCommandFound && knownCommands[possibleCommand] === undefined) { - break; - } - if (str.length === 128) { - error('Command token too long: ' + str.length); - } - str = possibleCommand; - knownCommandFound = knownCommands && knownCommands[str] !== undefined; - } - if (str === 'true') { - return true; - } - if (str === 'false') { - return false; - } - if (str === 'null') { - return null; - } - return Cmd.get(str); - }, - skipToNextLine: function Lexer_skipToNextLine() { - var ch = this.currentChar; - while (ch >= 0) { - if (ch === 0x0D) { // CR - ch = this.nextChar(); - if (ch === 0x0A) { // LF - this.nextChar(); - } - break; - } else if (ch === 0x0A) { // LF - this.nextChar(); - break; - } - ch = this.nextChar(); - } - } - }; - - return Lexer; -})(); - -var Linearization = { - create: function LinearizationCreate(stream) { - function getInt(name, allowZeroValue) { - var obj = linDict.get(name); - if (isInt(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) { - return obj; - } - throw new Error('The "' + name + '" parameter in the linearization ' + - 'dictionary is invalid.'); - } - function getHints() { - var hints = linDict.get('H'), hintsLength, item; - if (isArray(hints) && - ((hintsLength = hints.length) === 2 || hintsLength === 4)) { - for (var index = 0; index < hintsLength; index++) { - if (!(isInt(item = hints[index]) && item > 0)) { - throw new Error('Hint (' + index + - ') in the linearization dictionary is invalid.'); - } - } - return hints; - } - throw new Error('Hint array in the linearization dictionary is invalid.'); - } - var parser = new Parser(new Lexer(stream), false, null); - var obj1 = parser.getObj(); - var obj2 = parser.getObj(); - var obj3 = parser.getObj(); - var linDict = parser.getObj(); - var obj, length; - if (!(isInt(obj1) && isInt(obj2) && isCmd(obj3, 'obj') && isDict(linDict) && - isNum(obj = linDict.get('Linearized')) && obj > 0)) { - return null; // No valid linearization dictionary found. - } else if ((length = getInt('L')) !== stream.length) { - throw new Error('The "L" parameter in the linearization dictionary ' + - 'does not equal the stream length.'); - } - return { - length: length, - hints: getHints(), - objectNumberFirst: getInt('O'), - endFirst: getInt('E'), - numPages: getInt('N'), - mainXRefEntriesOffset: getInt('T'), - pageFirst: (linDict.has('P') ? getInt('P', true) : 0) - }; - } -}; - - -var PostScriptParser = (function PostScriptParserClosure() { - function PostScriptParser(lexer) { - this.lexer = lexer; - this.operators = []; - this.token = null; - this.prev = null; - } - PostScriptParser.prototype = { - nextToken: function PostScriptParser_nextToken() { - this.prev = this.token; - this.token = this.lexer.getToken(); - }, - accept: function PostScriptParser_accept(type) { - if (this.token.type === type) { - this.nextToken(); - return true; - } - return false; - }, - expect: function PostScriptParser_expect(type) { - if (this.accept(type)) { - return true; - } - error('Unexpected symbol: found ' + this.token.type + ' expected ' + - type + '.'); - }, - parse: function PostScriptParser_parse() { - this.nextToken(); - this.expect(PostScriptTokenTypes.LBRACE); - this.parseBlock(); - this.expect(PostScriptTokenTypes.RBRACE); - return this.operators; - }, - parseBlock: function PostScriptParser_parseBlock() { - while (true) { - if (this.accept(PostScriptTokenTypes.NUMBER)) { - this.operators.push(this.prev.value); - } else if (this.accept(PostScriptTokenTypes.OPERATOR)) { - this.operators.push(this.prev.value); - } else if (this.accept(PostScriptTokenTypes.LBRACE)) { - this.parseCondition(); - } else { - return; - } - } - }, - parseCondition: function PostScriptParser_parseCondition() { - // Add two place holders that will be updated later - var conditionLocation = this.operators.length; - this.operators.push(null, null); - - this.parseBlock(); - this.expect(PostScriptTokenTypes.RBRACE); - if (this.accept(PostScriptTokenTypes.IF)) { - // The true block is right after the 'if' so it just falls through on - // true else it jumps and skips the true block. - this.operators[conditionLocation] = this.operators.length; - this.operators[conditionLocation + 1] = 'jz'; - } else if (this.accept(PostScriptTokenTypes.LBRACE)) { - var jumpLocation = this.operators.length; - this.operators.push(null, null); - var endOfTrue = this.operators.length; - this.parseBlock(); - this.expect(PostScriptTokenTypes.RBRACE); - this.expect(PostScriptTokenTypes.IFELSE); - // The jump is added at the end of the true block to skip the false - // block. - this.operators[jumpLocation] = this.operators.length; - this.operators[jumpLocation + 1] = 'j'; - - this.operators[conditionLocation] = endOfTrue; - this.operators[conditionLocation + 1] = 'jz'; - } else { - error('PS Function: error parsing conditional.'); - } - } - }; - return PostScriptParser; -})(); - -var PostScriptTokenTypes = { - LBRACE: 0, - RBRACE: 1, - NUMBER: 2, - OPERATOR: 3, - IF: 4, - IFELSE: 5 -}; - -var PostScriptToken = (function PostScriptTokenClosure() { - function PostScriptToken(type, value) { - this.type = type; - this.value = value; - } - - var opCache = {}; - - PostScriptToken.getOperator = function PostScriptToken_getOperator(op) { - var opValue = opCache[op]; - if (opValue) { - return opValue; - } - return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); - }; - - PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, - '{'); - PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, - '}'); - PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF'); - PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE, - 'IFELSE'); - return PostScriptToken; -})(); - -var PostScriptLexer = (function PostScriptLexerClosure() { - function PostScriptLexer(stream) { - this.stream = stream; - this.nextChar(); - - this.strBuf = []; - } - PostScriptLexer.prototype = { - nextChar: function PostScriptLexer_nextChar() { - return (this.currentChar = this.stream.getByte()); - }, - getToken: function PostScriptLexer_getToken() { - var comment = false; - var ch = this.currentChar; - - // skip comments - while (true) { - if (ch < 0) { - return EOF; - } - - if (comment) { - if (ch === 0x0A || ch === 0x0D) { - comment = false; - } - } else if (ch === 0x25) { // '%' - comment = true; - } else if (!Lexer.isSpace(ch)) { - break; - } - ch = this.nextChar(); - } - switch (ch | 0) { - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4' - case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9' - case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.' - return new PostScriptToken(PostScriptTokenTypes.NUMBER, - this.getNumber()); - case 0x7B: // '{' - this.nextChar(); - return PostScriptToken.LBRACE; - case 0x7D: // '}' - this.nextChar(); - return PostScriptToken.RBRACE; - } - // operator - var strBuf = this.strBuf; - strBuf.length = 0; - strBuf[0] = String.fromCharCode(ch); - - while ((ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z' - ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { - strBuf.push(String.fromCharCode(ch)); - } - var str = strBuf.join(''); - switch (str.toLowerCase()) { - case 'if': - return PostScriptToken.IF; - case 'ifelse': - return PostScriptToken.IFELSE; - default: - return PostScriptToken.getOperator(str); - } - }, - getNumber: function PostScriptLexer_getNumber() { - var ch = this.currentChar; - var strBuf = this.strBuf; - strBuf.length = 0; - strBuf[0] = String.fromCharCode(ch); - - while ((ch = this.nextChar()) >= 0) { - if ((ch >= 0x30 && ch <= 0x39) || // '0'-'9' - ch === 0x2D || ch === 0x2E) { // '-', '.' - strBuf.push(String.fromCharCode(ch)); - } else { - break; - } - } - var value = parseFloat(strBuf.join('')); - if (isNaN(value)) { - error('Invalid floating point number: ' + value); - } - return value; - } - }; - return PostScriptLexer; -})(); - - -var Stream = (function StreamClosure() { - function Stream(arrayBuffer, start, length, dict) { - this.bytes = (arrayBuffer instanceof Uint8Array ? - arrayBuffer : new Uint8Array(arrayBuffer)); - this.start = start || 0; - this.pos = this.start; - this.end = (start + length) || this.bytes.length; - this.dict = dict; - } - - // required methods for a stream. if a particular stream does not - // implement these, an error should be thrown - Stream.prototype = { - get length() { - return this.end - this.start; - }, - get isEmpty() { - return this.length === 0; - }, - getByte: function Stream_getByte() { - if (this.pos >= this.end) { - return -1; - } - return this.bytes[this.pos++]; - }, - getUint16: function Stream_getUint16() { - var b0 = this.getByte(); - var b1 = this.getByte(); - if (b0 === -1 || b1 === -1) { - return -1; - } - return (b0 << 8) + b1; - }, - getInt32: function Stream_getInt32() { - var b0 = this.getByte(); - var b1 = this.getByte(); - var b2 = this.getByte(); - var b3 = this.getByte(); - return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; - }, - // returns subarray of original buffer - // should only be read - getBytes: function Stream_getBytes(length) { - var bytes = this.bytes; - var pos = this.pos; - var strEnd = this.end; - - if (!length) { - return bytes.subarray(pos, strEnd); - } - var end = pos + length; - if (end > strEnd) { - end = strEnd; - } - this.pos = end; - return bytes.subarray(pos, end); - }, - peekByte: function Stream_peekByte() { - var peekedByte = this.getByte(); - this.pos--; - return peekedByte; - }, - peekBytes: function Stream_peekBytes(length) { - var bytes = this.getBytes(length); - this.pos -= bytes.length; - return bytes; - }, - skip: function Stream_skip(n) { - if (!n) { - n = 1; - } - this.pos += n; - }, - reset: function Stream_reset() { - this.pos = this.start; - }, - moveStart: function Stream_moveStart() { - this.start = this.pos; - }, - makeSubStream: function Stream_makeSubStream(start, length, dict) { - return new Stream(this.bytes.buffer, start, length, dict); - }, - isStream: true - }; - - return Stream; -})(); - -var StringStream = (function StringStreamClosure() { - function StringStream(str) { - var length = str.length; - var bytes = new Uint8Array(length); - for (var n = 0; n < length; ++n) { - bytes[n] = str.charCodeAt(n); - } - Stream.call(this, bytes); - } - - StringStream.prototype = Stream.prototype; - - return StringStream; -})(); - -// super class for the decoding streams -var DecodeStream = (function DecodeStreamClosure() { - // Lots of DecodeStreams are created whose buffers are never used. For these - // we share a single empty buffer. This is (a) space-efficient and (b) avoids - // having special cases that would be required if we used |null| for an empty - // buffer. - var emptyBuffer = new Uint8Array(0); - - function DecodeStream(maybeMinBufferLength) { - this.pos = 0; - this.bufferLength = 0; - this.eof = false; - this.buffer = emptyBuffer; - this.minBufferLength = 512; - if (maybeMinBufferLength) { - // Compute the first power of two that is as big as maybeMinBufferLength. - while (this.minBufferLength < maybeMinBufferLength) { - this.minBufferLength *= 2; - } - } - } - - DecodeStream.prototype = { - get isEmpty() { - while (!this.eof && this.bufferLength === 0) { - this.readBlock(); - } - return this.bufferLength === 0; - }, - ensureBuffer: function DecodeStream_ensureBuffer(requested) { - var buffer = this.buffer; - if (requested <= buffer.byteLength) { - return buffer; - } - var size = this.minBufferLength; - while (size < requested) { - size *= 2; - } - var buffer2 = new Uint8Array(size); - buffer2.set(buffer); - return (this.buffer = buffer2); - }, - getByte: function DecodeStream_getByte() { - var pos = this.pos; - while (this.bufferLength <= pos) { - if (this.eof) { - return -1; - } - this.readBlock(); - } - return this.buffer[this.pos++]; - }, - getUint16: function DecodeStream_getUint16() { - var b0 = this.getByte(); - var b1 = this.getByte(); - if (b0 === -1 || b1 === -1) { - return -1; - } - return (b0 << 8) + b1; - }, - getInt32: function DecodeStream_getInt32() { - var b0 = this.getByte(); - var b1 = this.getByte(); - var b2 = this.getByte(); - var b3 = this.getByte(); - return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; - }, - getBytes: function DecodeStream_getBytes(length) { - var end, pos = this.pos; - - if (length) { - this.ensureBuffer(pos + length); - end = pos + length; - - while (!this.eof && this.bufferLength < end) { - this.readBlock(); - } - var bufEnd = this.bufferLength; - if (end > bufEnd) { - end = bufEnd; - } - } else { - while (!this.eof) { - this.readBlock(); - } - end = this.bufferLength; - } - - this.pos = end; - return this.buffer.subarray(pos, end); - }, - peekByte: function DecodeStream_peekByte() { - var peekedByte = this.getByte(); - this.pos--; - return peekedByte; - }, - peekBytes: function DecodeStream_peekBytes(length) { - var bytes = this.getBytes(length); - this.pos -= bytes.length; - return bytes; - }, - makeSubStream: function DecodeStream_makeSubStream(start, length, dict) { - var end = start + length; - while (this.bufferLength <= end && !this.eof) { - this.readBlock(); - } - return new Stream(this.buffer, start, length, dict); - }, - skip: function DecodeStream_skip(n) { - if (!n) { - n = 1; - } - this.pos += n; - }, - reset: function DecodeStream_reset() { - this.pos = 0; - }, - getBaseStreams: function DecodeStream_getBaseStreams() { - if (this.str && this.str.getBaseStreams) { - return this.str.getBaseStreams(); - } - return []; - } - }; - - return DecodeStream; -})(); - -var StreamsSequenceStream = (function StreamsSequenceStreamClosure() { - function StreamsSequenceStream(streams) { - this.streams = streams; - DecodeStream.call(this, /* maybeLength = */ null); - } - - StreamsSequenceStream.prototype = Object.create(DecodeStream.prototype); - - StreamsSequenceStream.prototype.readBlock = - function streamSequenceStreamReadBlock() { - - var streams = this.streams; - if (streams.length === 0) { - this.eof = true; - return; - } - var stream = streams.shift(); - var chunk = stream.getBytes(); - var bufferLength = this.bufferLength; - var newLength = bufferLength + chunk.length; - var buffer = this.ensureBuffer(newLength); - buffer.set(chunk, bufferLength); - this.bufferLength = newLength; - }; - - StreamsSequenceStream.prototype.getBaseStreams = - function StreamsSequenceStream_getBaseStreams() { - - var baseStreams = []; - for (var i = 0, ii = this.streams.length; i < ii; i++) { - var stream = this.streams[i]; - if (stream.getBaseStreams) { - Util.appendToArray(baseStreams, stream.getBaseStreams()); - } - } - return baseStreams; - }; - - return StreamsSequenceStream; -})(); - -var FlateStream = (function FlateStreamClosure() { - var codeLenCodeMap = new Int32Array([ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - ]); - - var lengthDecode = new Int32Array([ - 0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a, - 0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f, - 0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073, - 0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102 - ]); - - var distDecode = new Int32Array([ - 0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d, - 0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1, - 0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01, - 0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001 - ]); - - var fixedLitCodeTab = [new Int32Array([ - 0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0, - 0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0, - 0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0, - 0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0, - 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8, - 0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8, - 0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8, - 0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8, - 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4, - 0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4, - 0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4, - 0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4, - 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc, - 0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec, - 0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc, - 0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc, - 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2, - 0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2, - 0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2, - 0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2, - 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca, - 0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea, - 0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da, - 0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa, - 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6, - 0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6, - 0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6, - 0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6, - 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce, - 0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee, - 0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de, - 0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe, - 0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1, - 0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1, - 0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1, - 0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1, - 0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9, - 0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9, - 0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9, - 0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9, - 0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5, - 0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5, - 0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5, - 0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5, - 0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd, - 0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed, - 0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd, - 0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd, - 0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3, - 0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3, - 0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3, - 0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3, - 0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb, - 0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb, - 0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db, - 0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb, - 0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7, - 0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7, - 0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7, - 0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7, - 0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf, - 0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef, - 0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df, - 0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff - ]), 9]; - - var fixedDistCodeTab = [new Int32Array([ - 0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c, - 0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000, - 0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d, - 0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000 - ]), 5]; - - function FlateStream(str, maybeLength) { - this.str = str; - this.dict = str.dict; - - var cmf = str.getByte(); - var flg = str.getByte(); - if (cmf === -1 || flg === -1) { - error('Invalid header in flate stream: ' + cmf + ', ' + flg); - } - if ((cmf & 0x0f) !== 0x08) { - error('Unknown compression method in flate stream: ' + cmf + ', ' + flg); - } - if ((((cmf << 8) + flg) % 31) !== 0) { - error('Bad FCHECK in flate stream: ' + cmf + ', ' + flg); - } - if (flg & 0x20) { - error('FDICT bit set in flate stream: ' + cmf + ', ' + flg); - } - - this.codeSize = 0; - this.codeBuf = 0; - - DecodeStream.call(this, maybeLength); - } - - FlateStream.prototype = Object.create(DecodeStream.prototype); - - FlateStream.prototype.getBits = function FlateStream_getBits(bits) { - var str = this.str; - var codeSize = this.codeSize; - var codeBuf = this.codeBuf; - - var b; - while (codeSize < bits) { - if ((b = str.getByte()) === -1) { - error('Bad encoding in flate stream'); - } - codeBuf |= b << codeSize; - codeSize += 8; - } - b = codeBuf & ((1 << bits) - 1); - this.codeBuf = codeBuf >> bits; - this.codeSize = codeSize -= bits; - - return b; - }; - - FlateStream.prototype.getCode = function FlateStream_getCode(table) { - var str = this.str; - var codes = table[0]; - var maxLen = table[1]; - var codeSize = this.codeSize; - var codeBuf = this.codeBuf; - - var b; - while (codeSize < maxLen) { - if ((b = str.getByte()) === -1) { - // premature end of stream. code might however still be valid. - // codeSize < codeLen check below guards against incomplete codeVal. - break; - } - codeBuf |= (b << codeSize); - codeSize += 8; - } - var code = codes[codeBuf & ((1 << maxLen) - 1)]; - var codeLen = code >> 16; - var codeVal = code & 0xffff; - if (codeLen < 1 || codeSize < codeLen) { - error('Bad encoding in flate stream'); - } - this.codeBuf = (codeBuf >> codeLen); - this.codeSize = (codeSize - codeLen); - return codeVal; - }; - - FlateStream.prototype.generateHuffmanTable = - function flateStreamGenerateHuffmanTable(lengths) { - var n = lengths.length; - - // find max code length - var maxLen = 0; - var i; - for (i = 0; i < n; ++i) { - if (lengths[i] > maxLen) { - maxLen = lengths[i]; - } - } - - // build the table - var size = 1 << maxLen; - var codes = new Int32Array(size); - for (var len = 1, code = 0, skip = 2; - len <= maxLen; - ++len, code <<= 1, skip <<= 1) { - for (var val = 0; val < n; ++val) { - if (lengths[val] === len) { - // bit-reverse the code - var code2 = 0; - var t = code; - for (i = 0; i < len; ++i) { - code2 = (code2 << 1) | (t & 1); - t >>= 1; - } - - // fill the table entries - for (i = code2; i < size; i += skip) { - codes[i] = (len << 16) | val; - } - ++code; - } - } - } - - return [codes, maxLen]; - }; - - FlateStream.prototype.readBlock = function FlateStream_readBlock() { - var buffer, len; - var str = this.str; - // read block header - var hdr = this.getBits(3); - if (hdr & 1) { - this.eof = true; - } - hdr >>= 1; - - if (hdr === 0) { // uncompressed block - var b; - - if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); - } - var blockLen = b; - if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); - } - blockLen |= (b << 8); - if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); - } - var check = b; - if ((b = str.getByte()) === -1) { - error('Bad block header in flate stream'); - } - check |= (b << 8); - if (check !== (~blockLen & 0xffff) && - (blockLen !== 0 || check !== 0)) { - // Ignoring error for bad "empty" block (see issue 1277) - error('Bad uncompressed block length in flate stream'); - } - - this.codeBuf = 0; - this.codeSize = 0; - - var bufferLength = this.bufferLength; - buffer = this.ensureBuffer(bufferLength + blockLen); - var end = bufferLength + blockLen; - this.bufferLength = end; - if (blockLen === 0) { - if (str.peekByte() === -1) { - this.eof = true; - } - } else { - for (var n = bufferLength; n < end; ++n) { - if ((b = str.getByte()) === -1) { - this.eof = true; - break; - } - buffer[n] = b; - } - } - return; - } - - var litCodeTable; - var distCodeTable; - if (hdr === 1) { // compressed block, fixed codes - litCodeTable = fixedLitCodeTab; - distCodeTable = fixedDistCodeTab; - } else if (hdr === 2) { // compressed block, dynamic codes - var numLitCodes = this.getBits(5) + 257; - var numDistCodes = this.getBits(5) + 1; - var numCodeLenCodes = this.getBits(4) + 4; - - // build the code lengths code table - var codeLenCodeLengths = new Uint8Array(codeLenCodeMap.length); - - var i; - for (i = 0; i < numCodeLenCodes; ++i) { - codeLenCodeLengths[codeLenCodeMap[i]] = this.getBits(3); - } - var codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths); - - // build the literal and distance code tables - len = 0; - i = 0; - var codes = numLitCodes + numDistCodes; - var codeLengths = new Uint8Array(codes); - var bitsLength, bitsOffset, what; - while (i < codes) { - var code = this.getCode(codeLenCodeTab); - if (code === 16) { - bitsLength = 2; bitsOffset = 3; what = len; - } else if (code === 17) { - bitsLength = 3; bitsOffset = 3; what = (len = 0); - } else if (code === 18) { - bitsLength = 7; bitsOffset = 11; what = (len = 0); - } else { - codeLengths[i++] = len = code; - continue; - } - - var repeatLength = this.getBits(bitsLength) + bitsOffset; - while (repeatLength-- > 0) { - codeLengths[i++] = what; - } - } - - litCodeTable = - this.generateHuffmanTable(codeLengths.subarray(0, numLitCodes)); - distCodeTable = - this.generateHuffmanTable(codeLengths.subarray(numLitCodes, codes)); - } else { - error('Unknown block type in flate stream'); - } - - buffer = this.buffer; - var limit = buffer ? buffer.length : 0; - var pos = this.bufferLength; - while (true) { - var code1 = this.getCode(litCodeTable); - if (code1 < 256) { - if (pos + 1 >= limit) { - buffer = this.ensureBuffer(pos + 1); - limit = buffer.length; - } - buffer[pos++] = code1; - continue; - } - if (code1 === 256) { - this.bufferLength = pos; - return; - } - code1 -= 257; - code1 = lengthDecode[code1]; - var code2 = code1 >> 16; - if (code2 > 0) { - code2 = this.getBits(code2); - } - len = (code1 & 0xffff) + code2; - code1 = this.getCode(distCodeTable); - code1 = distDecode[code1]; - code2 = code1 >> 16; - if (code2 > 0) { - code2 = this.getBits(code2); - } - var dist = (code1 & 0xffff) + code2; - if (pos + len >= limit) { - buffer = this.ensureBuffer(pos + len); - limit = buffer.length; - } - for (var k = 0; k < len; ++k, ++pos) { - buffer[pos] = buffer[pos - dist]; - } - } - }; - - return FlateStream; -})(); - -var PredictorStream = (function PredictorStreamClosure() { - function PredictorStream(str, maybeLength, params) { - var predictor = this.predictor = params.get('Predictor') || 1; - - if (predictor <= 1) { - return str; // no prediction - } - if (predictor !== 2 && (predictor < 10 || predictor > 15)) { - error('Unsupported predictor: ' + predictor); - } - - if (predictor === 2) { - this.readBlock = this.readBlockTiff; - } else { - this.readBlock = this.readBlockPng; - } - - this.str = str; - this.dict = str.dict; - - var colors = this.colors = params.get('Colors') || 1; - var bits = this.bits = params.get('BitsPerComponent') || 8; - var columns = this.columns = params.get('Columns') || 1; - - this.pixBytes = (colors * bits + 7) >> 3; - this.rowBytes = (columns * colors * bits + 7) >> 3; - - DecodeStream.call(this, maybeLength); - return this; - } - - PredictorStream.prototype = Object.create(DecodeStream.prototype); - - PredictorStream.prototype.readBlockTiff = - function predictorStreamReadBlockTiff() { - var rowBytes = this.rowBytes; - - var bufferLength = this.bufferLength; - var buffer = this.ensureBuffer(bufferLength + rowBytes); - - var bits = this.bits; - var colors = this.colors; - - var rawBytes = this.str.getBytes(rowBytes); - this.eof = !rawBytes.length; - if (this.eof) { - return; - } - - var inbuf = 0, outbuf = 0; - var inbits = 0, outbits = 0; - var pos = bufferLength; - var i; - - if (bits === 1) { - for (i = 0; i < rowBytes; ++i) { - var c = rawBytes[i]; - inbuf = (inbuf << 8) | c; - // bitwise addition is exclusive or - // first shift inbuf and then add - buffer[pos++] = (c ^ (inbuf >> colors)) & 0xFF; - // truncate inbuf (assumes colors < 16) - inbuf &= 0xFFFF; - } - } else if (bits === 8) { - for (i = 0; i < colors; ++i) { - buffer[pos++] = rawBytes[i]; - } - for (; i < rowBytes; ++i) { - buffer[pos] = buffer[pos - colors] + rawBytes[i]; - pos++; - } - } else { - var compArray = new Uint8Array(colors + 1); - var bitMask = (1 << bits) - 1; - var j = 0, k = bufferLength; - var columns = this.columns; - for (i = 0; i < columns; ++i) { - for (var kk = 0; kk < colors; ++kk) { - if (inbits < bits) { - inbuf = (inbuf << 8) | (rawBytes[j++] & 0xFF); - inbits += 8; - } - compArray[kk] = (compArray[kk] + - (inbuf >> (inbits - bits))) & bitMask; - inbits -= bits; - outbuf = (outbuf << bits) | compArray[kk]; - outbits += bits; - if (outbits >= 8) { - buffer[k++] = (outbuf >> (outbits - 8)) & 0xFF; - outbits -= 8; - } - } - } - if (outbits > 0) { - buffer[k++] = (outbuf << (8 - outbits)) + - (inbuf & ((1 << (8 - outbits)) - 1)); - } - } - this.bufferLength += rowBytes; - }; - - PredictorStream.prototype.readBlockPng = - function predictorStreamReadBlockPng() { - - var rowBytes = this.rowBytes; - var pixBytes = this.pixBytes; - - var predictor = this.str.getByte(); - var rawBytes = this.str.getBytes(rowBytes); - this.eof = !rawBytes.length; - if (this.eof) { - return; - } - - var bufferLength = this.bufferLength; - var buffer = this.ensureBuffer(bufferLength + rowBytes); - - var prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength); - if (prevRow.length === 0) { - prevRow = new Uint8Array(rowBytes); - } - - var i, j = bufferLength, up, c; - switch (predictor) { - case 0: - for (i = 0; i < rowBytes; ++i) { - buffer[j++] = rawBytes[i]; - } - break; - case 1: - for (i = 0; i < pixBytes; ++i) { - buffer[j++] = rawBytes[i]; - } - for (; i < rowBytes; ++i) { - buffer[j] = (buffer[j - pixBytes] + rawBytes[i]) & 0xFF; - j++; - } - break; - case 2: - for (i = 0; i < rowBytes; ++i) { - buffer[j++] = (prevRow[i] + rawBytes[i]) & 0xFF; - } - break; - case 3: - for (i = 0; i < pixBytes; ++i) { - buffer[j++] = (prevRow[i] >> 1) + rawBytes[i]; - } - for (; i < rowBytes; ++i) { - buffer[j] = (((prevRow[i] + buffer[j - pixBytes]) >> 1) + - rawBytes[i]) & 0xFF; - j++; - } - break; - case 4: - // we need to save the up left pixels values. the simplest way - // is to create a new buffer - for (i = 0; i < pixBytes; ++i) { - up = prevRow[i]; - c = rawBytes[i]; - buffer[j++] = up + c; - } - for (; i < rowBytes; ++i) { - up = prevRow[i]; - var upLeft = prevRow[i - pixBytes]; - var left = buffer[j - pixBytes]; - var p = left + up - upLeft; - - var pa = p - left; - if (pa < 0) { - pa = -pa; - } - var pb = p - up; - if (pb < 0) { - pb = -pb; - } - var pc = p - upLeft; - if (pc < 0) { - pc = -pc; - } - - c = rawBytes[i]; - if (pa <= pb && pa <= pc) { - buffer[j++] = left + c; - } else if (pb <= pc) { - buffer[j++] = up + c; - } else { - buffer[j++] = upLeft + c; - } - } - break; - default: - error('Unsupported predictor: ' + predictor); - } - this.bufferLength += rowBytes; - }; - - return PredictorStream; -})(); - -/** - * Depending on the type of JPEG a JpegStream is handled in different ways. For - * JPEG's that are supported natively such as DeviceGray and DeviceRGB the image - * data is stored and then loaded by the browser. For unsupported JPEG's we use - * a library to decode these images and the stream behaves like all the other - * DecodeStreams. - */ -var JpegStream = (function JpegStreamClosure() { - function JpegStream(stream, maybeLength, dict, xref) { - // Some images may contain 'junk' before the SOI (start-of-image) marker. - // Note: this seems to mainly affect inline images. - var ch; - while ((ch = stream.getByte()) !== -1) { - if (ch === 0xFF) { // Find the first byte of the SOI marker (0xFFD8). - stream.skip(-1); // Reset the stream position to the SOI. - break; - } - } - this.stream = stream; - this.maybeLength = maybeLength; - this.dict = dict; - - DecodeStream.call(this, maybeLength); - } - - JpegStream.prototype = Object.create(DecodeStream.prototype); - - Object.defineProperty(JpegStream.prototype, 'bytes', { - get: function JpegStream_bytes() { - // If this.maybeLength is null, we'll get the entire stream. - return shadow(this, 'bytes', this.stream.getBytes(this.maybeLength)); - }, - configurable: true - }); - - JpegStream.prototype.ensureBuffer = function JpegStream_ensureBuffer(req) { - if (this.bufferLength) { - return; - } - try { - var jpegImage = new JpegImage(); - - // checking if values needs to be transformed before conversion - if (this.forceRGB && this.dict && isArray(this.dict.get('Decode'))) { - var decodeArr = this.dict.get('Decode'); - var bitsPerComponent = this.dict.get('BitsPerComponent') || 8; - var decodeArrLength = decodeArr.length; - var transform = new Int32Array(decodeArrLength); - var transformNeeded = false; - var maxValue = (1 << bitsPerComponent) - 1; - for (var i = 0; i < decodeArrLength; i += 2) { - transform[i] = ((decodeArr[i + 1] - decodeArr[i]) * 256) | 0; - transform[i + 1] = (decodeArr[i] * maxValue) | 0; - if (transform[i] !== 256 || transform[i + 1] !== 0) { - transformNeeded = true; - } - } - if (transformNeeded) { - jpegImage.decodeTransform = transform; - } - } - - jpegImage.parse(this.bytes); - var data = jpegImage.getData(this.drawWidth, this.drawHeight, - this.forceRGB); - this.buffer = data; - this.bufferLength = data.length; - this.eof = true; - } catch (e) { - error('JPEG error: ' + e); - } - }; - - JpegStream.prototype.getBytes = function JpegStream_getBytes(length) { - this.ensureBuffer(); - return this.buffer; - }; - - JpegStream.prototype.getIR = function JpegStream_getIR() { - return PDFJS.createObjectURL(this.bytes, 'image/jpeg'); - }; - /** - * Checks if the image can be decoded and displayed by the browser without any - * further processing such as color space conversions. - */ - JpegStream.prototype.isNativelySupported = - function JpegStream_isNativelySupported(xref, res) { - var cs = ColorSpace.parse(this.dict.get('ColorSpace', 'CS'), xref, res); - return cs.name === 'DeviceGray' || cs.name === 'DeviceRGB'; - }; - /** - * Checks if the image can be decoded by the browser. - */ - JpegStream.prototype.isNativelyDecodable = - function JpegStream_isNativelyDecodable(xref, res) { - var cs = ColorSpace.parse(this.dict.get('ColorSpace', 'CS'), xref, res); - var numComps = cs.numComps; - return numComps === 1 || numComps === 3; - }; - - return JpegStream; -})(); - -/** - * For JPEG 2000's we use a library to decode these images and - * the stream behaves like all the other DecodeStreams. - */ -var JpxStream = (function JpxStreamClosure() { - function JpxStream(stream, maybeLength, dict) { - this.stream = stream; - this.maybeLength = maybeLength; - this.dict = dict; - - DecodeStream.call(this, maybeLength); - } - - JpxStream.prototype = Object.create(DecodeStream.prototype); - - Object.defineProperty(JpxStream.prototype, 'bytes', { - get: function JpxStream_bytes() { - // If this.maybeLength is null, we'll get the entire stream. - return shadow(this, 'bytes', this.stream.getBytes(this.maybeLength)); - }, - configurable: true - }); - - JpxStream.prototype.ensureBuffer = function JpxStream_ensureBuffer(req) { - if (this.bufferLength) { - return; - } - - var jpxImage = new JpxImage(); - jpxImage.parse(this.bytes); - - var width = jpxImage.width; - var height = jpxImage.height; - var componentsCount = jpxImage.componentsCount; - var tileCount = jpxImage.tiles.length; - if (tileCount === 1) { - this.buffer = jpxImage.tiles[0].items; - } else { - var data = new Uint8Array(width * height * componentsCount); - - for (var k = 0; k < tileCount; k++) { - var tileComponents = jpxImage.tiles[k]; - var tileWidth = tileComponents.width; - var tileHeight = tileComponents.height; - var tileLeft = tileComponents.left; - var tileTop = tileComponents.top; - - var src = tileComponents.items; - var srcPosition = 0; - var dataPosition = (width * tileTop + tileLeft) * componentsCount; - var imgRowSize = width * componentsCount; - var tileRowSize = tileWidth * componentsCount; - - for (var j = 0; j < tileHeight; j++) { - var rowBytes = src.subarray(srcPosition, srcPosition + tileRowSize); - data.set(rowBytes, dataPosition); - srcPosition += tileRowSize; - dataPosition += imgRowSize; - } - } - this.buffer = data; - } - this.bufferLength = this.buffer.length; - this.eof = true; - }; - - return JpxStream; -})(); - -/** - * For JBIG2's we use a library to decode these images and - * the stream behaves like all the other DecodeStreams. - */ -var Jbig2Stream = (function Jbig2StreamClosure() { - function Jbig2Stream(stream, maybeLength, dict) { - this.stream = stream; - this.maybeLength = maybeLength; - this.dict = dict; - - DecodeStream.call(this, maybeLength); - } - - Jbig2Stream.prototype = Object.create(DecodeStream.prototype); - - Object.defineProperty(Jbig2Stream.prototype, 'bytes', { - get: function Jbig2Stream_bytes() { - // If this.maybeLength is null, we'll get the entire stream. - return shadow(this, 'bytes', this.stream.getBytes(this.maybeLength)); - }, - configurable: true - }); - - Jbig2Stream.prototype.ensureBuffer = function Jbig2Stream_ensureBuffer(req) { - if (this.bufferLength) { - return; - } - - var jbig2Image = new Jbig2Image(); - - var chunks = [], xref = this.dict.xref; - var decodeParams = xref.fetchIfRef(this.dict.get('DecodeParms')); - - // According to the PDF specification, DecodeParms can be either - // a dictionary, or an array whose elements are dictionaries. - if (isArray(decodeParams)) { - if (decodeParams.length > 1) { - warn('JBIG2 - \'DecodeParms\' array with multiple elements ' + - 'not supported.'); - } - decodeParams = xref.fetchIfRef(decodeParams[0]); - } - if (decodeParams && decodeParams.has('JBIG2Globals')) { - var globalsStream = decodeParams.get('JBIG2Globals'); - var globals = globalsStream.getBytes(); - chunks.push({data: globals, start: 0, end: globals.length}); - } - chunks.push({data: this.bytes, start: 0, end: this.bytes.length}); - var data = jbig2Image.parseChunks(chunks); - var dataLength = data.length; - - // JBIG2 had black as 1 and white as 0, inverting the colors - for (var i = 0; i < dataLength; i++) { - data[i] ^= 0xFF; - } - - this.buffer = data; - this.bufferLength = dataLength; - this.eof = true; - }; - - return Jbig2Stream; -})(); - -var DecryptStream = (function DecryptStreamClosure() { - function DecryptStream(str, maybeLength, decrypt) { - this.str = str; - this.dict = str.dict; - this.decrypt = decrypt; - this.nextChunk = null; - this.initialized = false; - - DecodeStream.call(this, maybeLength); - } - - var chunkSize = 512; - - DecryptStream.prototype = Object.create(DecodeStream.prototype); - - DecryptStream.prototype.readBlock = function DecryptStream_readBlock() { - var chunk; - if (this.initialized) { - chunk = this.nextChunk; - } else { - chunk = this.str.getBytes(chunkSize); - this.initialized = true; - } - if (!chunk || chunk.length === 0) { - this.eof = true; - return; - } - this.nextChunk = this.str.getBytes(chunkSize); - var hasMoreData = this.nextChunk && this.nextChunk.length > 0; - - var decrypt = this.decrypt; - chunk = decrypt(chunk, !hasMoreData); - - var bufferLength = this.bufferLength; - var i, n = chunk.length; - var buffer = this.ensureBuffer(bufferLength + n); - for (i = 0; i < n; i++) { - buffer[bufferLength++] = chunk[i]; - } - this.bufferLength = bufferLength; - }; - - return DecryptStream; -})(); - -var Ascii85Stream = (function Ascii85StreamClosure() { - function Ascii85Stream(str, maybeLength) { - this.str = str; - this.dict = str.dict; - this.input = new Uint8Array(5); - - // Most streams increase in size when decoded, but Ascii85 streams - // typically shrink by ~20%. - if (maybeLength) { - maybeLength = 0.8 * maybeLength; - } - DecodeStream.call(this, maybeLength); - } - - Ascii85Stream.prototype = Object.create(DecodeStream.prototype); - - Ascii85Stream.prototype.readBlock = function Ascii85Stream_readBlock() { - var TILDA_CHAR = 0x7E; // '~' - var Z_LOWER_CHAR = 0x7A; // 'z' - var EOF = -1; - - var str = this.str; - - var c = str.getByte(); - while (Lexer.isSpace(c)) { - c = str.getByte(); - } - - if (c === EOF || c === TILDA_CHAR) { - this.eof = true; - return; - } - - var bufferLength = this.bufferLength, buffer; - var i; - - // special code for z - if (c === Z_LOWER_CHAR) { - buffer = this.ensureBuffer(bufferLength + 4); - for (i = 0; i < 4; ++i) { - buffer[bufferLength + i] = 0; - } - this.bufferLength += 4; - } else { - var input = this.input; - input[0] = c; - for (i = 1; i < 5; ++i) { - c = str.getByte(); - while (Lexer.isSpace(c)) { - c = str.getByte(); - } - - input[i] = c; - - if (c === EOF || c === TILDA_CHAR) { - break; - } - } - buffer = this.ensureBuffer(bufferLength + i - 1); - this.bufferLength += i - 1; - - // partial ending; - if (i < 5) { - for (; i < 5; ++i) { - input[i] = 0x21 + 84; - } - this.eof = true; - } - var t = 0; - for (i = 0; i < 5; ++i) { - t = t * 85 + (input[i] - 0x21); - } - - for (i = 3; i >= 0; --i) { - buffer[bufferLength + i] = t & 0xFF; - t >>= 8; - } - } - }; - - return Ascii85Stream; -})(); - -var AsciiHexStream = (function AsciiHexStreamClosure() { - function AsciiHexStream(str, maybeLength) { - this.str = str; - this.dict = str.dict; - - this.firstDigit = -1; - - // Most streams increase in size when decoded, but AsciiHex streams shrink - // by 50%. - if (maybeLength) { - maybeLength = 0.5 * maybeLength; - } - DecodeStream.call(this, maybeLength); - } - - AsciiHexStream.prototype = Object.create(DecodeStream.prototype); - - AsciiHexStream.prototype.readBlock = function AsciiHexStream_readBlock() { - var UPSTREAM_BLOCK_SIZE = 8000; - var bytes = this.str.getBytes(UPSTREAM_BLOCK_SIZE); - if (!bytes.length) { - this.eof = true; - return; - } - - var maxDecodeLength = (bytes.length + 1) >> 1; - var buffer = this.ensureBuffer(this.bufferLength + maxDecodeLength); - var bufferLength = this.bufferLength; - - var firstDigit = this.firstDigit; - for (var i = 0, ii = bytes.length; i < ii; i++) { - var ch = bytes[i], digit; - if (ch >= 0x30 && ch <= 0x39) { // '0'-'9' - digit = ch & 0x0F; - } else if ((ch >= 0x41 && ch <= 0x46) || (ch >= 0x61 && ch <= 0x66)) { - // 'A'-'Z', 'a'-'z' - digit = (ch & 0x0F) + 9; - } else if (ch === 0x3E) { // '>' - this.eof = true; - break; - } else { // probably whitespace - continue; // ignoring - } - if (firstDigit < 0) { - firstDigit = digit; - } else { - buffer[bufferLength++] = (firstDigit << 4) | digit; - firstDigit = -1; - } - } - if (firstDigit >= 0 && this.eof) { - // incomplete byte - buffer[bufferLength++] = (firstDigit << 4); - firstDigit = -1; - } - this.firstDigit = firstDigit; - this.bufferLength = bufferLength; - }; - - return AsciiHexStream; -})(); - -var RunLengthStream = (function RunLengthStreamClosure() { - function RunLengthStream(str, maybeLength) { - this.str = str; - this.dict = str.dict; - - DecodeStream.call(this, maybeLength); - } - - RunLengthStream.prototype = Object.create(DecodeStream.prototype); - - RunLengthStream.prototype.readBlock = function RunLengthStream_readBlock() { - // The repeatHeader has following format. The first byte defines type of run - // and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes - // (in addition to the second byte from the header), n = 129 through 255 - - // duplicate the second byte from the header (257 - n) times, n = 128 - end. - var repeatHeader = this.str.getBytes(2); - if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] === 128) { - this.eof = true; - return; - } - - var buffer; - var bufferLength = this.bufferLength; - var n = repeatHeader[0]; - if (n < 128) { - // copy n bytes - buffer = this.ensureBuffer(bufferLength + n + 1); - buffer[bufferLength++] = repeatHeader[1]; - if (n > 0) { - var source = this.str.getBytes(n); - buffer.set(source, bufferLength); - bufferLength += n; - } - } else { - n = 257 - n; - var b = repeatHeader[1]; - buffer = this.ensureBuffer(bufferLength + n + 1); - for (var i = 0; i < n; i++) { - buffer[bufferLength++] = b; - } - } - this.bufferLength = bufferLength; - }; - - return RunLengthStream; -})(); - -var CCITTFaxStream = (function CCITTFaxStreamClosure() { - - var ccittEOL = -2; - var twoDimPass = 0; - var twoDimHoriz = 1; - var twoDimVert0 = 2; - var twoDimVertR1 = 3; - var twoDimVertL1 = 4; - var twoDimVertR2 = 5; - var twoDimVertL2 = 6; - var twoDimVertR3 = 7; - var twoDimVertL3 = 8; - - var twoDimTable = [ - [-1, -1], [-1, -1], // 000000x - [7, twoDimVertL3], // 0000010 - [7, twoDimVertR3], // 0000011 - [6, twoDimVertL2], [6, twoDimVertL2], // 000010x - [6, twoDimVertR2], [6, twoDimVertR2], // 000011x - [4, twoDimPass], [4, twoDimPass], // 0001xxx - [4, twoDimPass], [4, twoDimPass], - [4, twoDimPass], [4, twoDimPass], - [4, twoDimPass], [4, twoDimPass], - [3, twoDimHoriz], [3, twoDimHoriz], // 001xxxx - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimHoriz], [3, twoDimHoriz], - [3, twoDimVertL1], [3, twoDimVertL1], // 010xxxx - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertL1], [3, twoDimVertL1], - [3, twoDimVertR1], [3, twoDimVertR1], // 011xxxx - [3, twoDimVertR1], [3, twoDimVertR1], - [3, twoDimVertR1], [3, twoDimVertR1], - [3, twoDimVertR1], [3, twoDimVertR1], - [3, twoDimVertR1], [3, twoDimVertR1], - [3, twoDimVertR1], [3, twoDimVertR1], - [3, twoDimVertR1], [3, twoDimVertR1], - [3, twoDimVertR1], [3, twoDimVertR1], - [1, twoDimVert0], [1, twoDimVert0], // 1xxxxxx - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0], - [1, twoDimVert0], [1, twoDimVert0] - ]; - - var whiteTable1 = [ - [-1, -1], // 00000 - [12, ccittEOL], // 00001 - [-1, -1], [-1, -1], // 0001x - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 001xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 010xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 011xx - [11, 1792], [11, 1792], // 1000x - [12, 1984], // 10010 - [12, 2048], // 10011 - [12, 2112], // 10100 - [12, 2176], // 10101 - [12, 2240], // 10110 - [12, 2304], // 10111 - [11, 1856], [11, 1856], // 1100x - [11, 1920], [11, 1920], // 1101x - [12, 2368], // 11100 - [12, 2432], // 11101 - [12, 2496], // 11110 - [12, 2560] // 11111 - ]; - - var whiteTable2 = [ - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 0000000xx - [8, 29], [8, 29], // 00000010x - [8, 30], [8, 30], // 00000011x - [8, 45], [8, 45], // 00000100x - [8, 46], [8, 46], // 00000101x - [7, 22], [7, 22], [7, 22], [7, 22], // 0000011xx - [7, 23], [7, 23], [7, 23], [7, 23], // 0000100xx - [8, 47], [8, 47], // 00001010x - [8, 48], [8, 48], // 00001011x - [6, 13], [6, 13], [6, 13], [6, 13], // 000011xxx - [6, 13], [6, 13], [6, 13], [6, 13], - [7, 20], [7, 20], [7, 20], [7, 20], // 0001000xx - [8, 33], [8, 33], // 00010010x - [8, 34], [8, 34], // 00010011x - [8, 35], [8, 35], // 00010100x - [8, 36], [8, 36], // 00010101x - [8, 37], [8, 37], // 00010110x - [8, 38], [8, 38], // 00010111x - [7, 19], [7, 19], [7, 19], [7, 19], // 0001100xx - [8, 31], [8, 31], // 00011010x - [8, 32], [8, 32], // 00011011x - [6, 1], [6, 1], [6, 1], [6, 1], // 000111xxx - [6, 1], [6, 1], [6, 1], [6, 1], - [6, 12], [6, 12], [6, 12], [6, 12], // 001000xxx - [6, 12], [6, 12], [6, 12], [6, 12], - [8, 53], [8, 53], // 00100100x - [8, 54], [8, 54], // 00100101x - [7, 26], [7, 26], [7, 26], [7, 26], // 0010011xx - [8, 39], [8, 39], // 00101000x - [8, 40], [8, 40], // 00101001x - [8, 41], [8, 41], // 00101010x - [8, 42], [8, 42], // 00101011x - [8, 43], [8, 43], // 00101100x - [8, 44], [8, 44], // 00101101x - [7, 21], [7, 21], [7, 21], [7, 21], // 0010111xx - [7, 28], [7, 28], [7, 28], [7, 28], // 0011000xx - [8, 61], [8, 61], // 00110010x - [8, 62], [8, 62], // 00110011x - [8, 63], [8, 63], // 00110100x - [8, 0], [8, 0], // 00110101x - [8, 320], [8, 320], // 00110110x - [8, 384], [8, 384], // 00110111x - [5, 10], [5, 10], [5, 10], [5, 10], // 00111xxxx - [5, 10], [5, 10], [5, 10], [5, 10], - [5, 10], [5, 10], [5, 10], [5, 10], - [5, 10], [5, 10], [5, 10], [5, 10], - [5, 11], [5, 11], [5, 11], [5, 11], // 01000xxxx - [5, 11], [5, 11], [5, 11], [5, 11], - [5, 11], [5, 11], [5, 11], [5, 11], - [5, 11], [5, 11], [5, 11], [5, 11], - [7, 27], [7, 27], [7, 27], [7, 27], // 0100100xx - [8, 59], [8, 59], // 01001010x - [8, 60], [8, 60], // 01001011x - [9, 1472], // 010011000 - [9, 1536], // 010011001 - [9, 1600], // 010011010 - [9, 1728], // 010011011 - [7, 18], [7, 18], [7, 18], [7, 18], // 0100111xx - [7, 24], [7, 24], [7, 24], [7, 24], // 0101000xx - [8, 49], [8, 49], // 01010010x - [8, 50], [8, 50], // 01010011x - [8, 51], [8, 51], // 01010100x - [8, 52], [8, 52], // 01010101x - [7, 25], [7, 25], [7, 25], [7, 25], // 0101011xx - [8, 55], [8, 55], // 01011000x - [8, 56], [8, 56], // 01011001x - [8, 57], [8, 57], // 01011010x - [8, 58], [8, 58], // 01011011x - [6, 192], [6, 192], [6, 192], [6, 192], // 010111xxx - [6, 192], [6, 192], [6, 192], [6, 192], - [6, 1664], [6, 1664], [6, 1664], [6, 1664], // 011000xxx - [6, 1664], [6, 1664], [6, 1664], [6, 1664], - [8, 448], [8, 448], // 01100100x - [8, 512], [8, 512], // 01100101x - [9, 704], // 011001100 - [9, 768], // 011001101 - [8, 640], [8, 640], // 01100111x - [8, 576], [8, 576], // 01101000x - [9, 832], // 011010010 - [9, 896], // 011010011 - [9, 960], // 011010100 - [9, 1024], // 011010101 - [9, 1088], // 011010110 - [9, 1152], // 011010111 - [9, 1216], // 011011000 - [9, 1280], // 011011001 - [9, 1344], // 011011010 - [9, 1408], // 011011011 - [7, 256], [7, 256], [7, 256], [7, 256], // 0110111xx - [4, 2], [4, 2], [4, 2], [4, 2], // 0111xxxxx - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 2], [4, 2], [4, 2], [4, 2], - [4, 3], [4, 3], [4, 3], [4, 3], // 1000xxxxx - [4, 3], [4, 3], [4, 3], [4, 3], - [4, 3], [4, 3], [4, 3], [4, 3], - [4, 3], [4, 3], [4, 3], [4, 3], - [4, 3], [4, 3], [4, 3], [4, 3], - [4, 3], [4, 3], [4, 3], [4, 3], - [4, 3], [4, 3], [4, 3], [4, 3], - [4, 3], [4, 3], [4, 3], [4, 3], - [5, 128], [5, 128], [5, 128], [5, 128], // 10010xxxx - [5, 128], [5, 128], [5, 128], [5, 128], - [5, 128], [5, 128], [5, 128], [5, 128], - [5, 128], [5, 128], [5, 128], [5, 128], - [5, 8], [5, 8], [5, 8], [5, 8], // 10011xxxx - [5, 8], [5, 8], [5, 8], [5, 8], - [5, 8], [5, 8], [5, 8], [5, 8], - [5, 8], [5, 8], [5, 8], [5, 8], - [5, 9], [5, 9], [5, 9], [5, 9], // 10100xxxx - [5, 9], [5, 9], [5, 9], [5, 9], - [5, 9], [5, 9], [5, 9], [5, 9], - [5, 9], [5, 9], [5, 9], [5, 9], - [6, 16], [6, 16], [6, 16], [6, 16], // 101010xxx - [6, 16], [6, 16], [6, 16], [6, 16], - [6, 17], [6, 17], [6, 17], [6, 17], // 101011xxx - [6, 17], [6, 17], [6, 17], [6, 17], - [4, 4], [4, 4], [4, 4], [4, 4], // 1011xxxxx - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 4], [4, 4], [4, 4], [4, 4], - [4, 5], [4, 5], [4, 5], [4, 5], // 1100xxxxx - [4, 5], [4, 5], [4, 5], [4, 5], - [4, 5], [4, 5], [4, 5], [4, 5], - [4, 5], [4, 5], [4, 5], [4, 5], - [4, 5], [4, 5], [4, 5], [4, 5], - [4, 5], [4, 5], [4, 5], [4, 5], - [4, 5], [4, 5], [4, 5], [4, 5], - [4, 5], [4, 5], [4, 5], [4, 5], - [6, 14], [6, 14], [6, 14], [6, 14], // 110100xxx - [6, 14], [6, 14], [6, 14], [6, 14], - [6, 15], [6, 15], [6, 15], [6, 15], // 110101xxx - [6, 15], [6, 15], [6, 15], [6, 15], - [5, 64], [5, 64], [5, 64], [5, 64], // 11011xxxx - [5, 64], [5, 64], [5, 64], [5, 64], - [5, 64], [5, 64], [5, 64], [5, 64], - [5, 64], [5, 64], [5, 64], [5, 64], - [4, 6], [4, 6], [4, 6], [4, 6], // 1110xxxxx - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 6], [4, 6], [4, 6], [4, 6], - [4, 7], [4, 7], [4, 7], [4, 7], // 1111xxxxx - [4, 7], [4, 7], [4, 7], [4, 7], - [4, 7], [4, 7], [4, 7], [4, 7], - [4, 7], [4, 7], [4, 7], [4, 7], - [4, 7], [4, 7], [4, 7], [4, 7], - [4, 7], [4, 7], [4, 7], [4, 7], - [4, 7], [4, 7], [4, 7], [4, 7], - [4, 7], [4, 7], [4, 7], [4, 7] - ]; - - var blackTable1 = [ - [-1, -1], [-1, -1], // 000000000000x - [12, ccittEOL], [12, ccittEOL], // 000000000001x - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000001xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000010xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000011xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000100xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000101xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000110xx - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 00000000111xx - [11, 1792], [11, 1792], [11, 1792], [11, 1792], // 00000001000xx - [12, 1984], [12, 1984], // 000000010010x - [12, 2048], [12, 2048], // 000000010011x - [12, 2112], [12, 2112], // 000000010100x - [12, 2176], [12, 2176], // 000000010101x - [12, 2240], [12, 2240], // 000000010110x - [12, 2304], [12, 2304], // 000000010111x - [11, 1856], [11, 1856], [11, 1856], [11, 1856], // 00000001100xx - [11, 1920], [11, 1920], [11, 1920], [11, 1920], // 00000001101xx - [12, 2368], [12, 2368], // 000000011100x - [12, 2432], [12, 2432], // 000000011101x - [12, 2496], [12, 2496], // 000000011110x - [12, 2560], [12, 2560], // 000000011111x - [10, 18], [10, 18], [10, 18], [10, 18], // 0000001000xxx - [10, 18], [10, 18], [10, 18], [10, 18], - [12, 52], [12, 52], // 000000100100x - [13, 640], // 0000001001010 - [13, 704], // 0000001001011 - [13, 768], // 0000001001100 - [13, 832], // 0000001001101 - [12, 55], [12, 55], // 000000100111x - [12, 56], [12, 56], // 000000101000x - [13, 1280], // 0000001010010 - [13, 1344], // 0000001010011 - [13, 1408], // 0000001010100 - [13, 1472], // 0000001010101 - [12, 59], [12, 59], // 000000101011x - [12, 60], [12, 60], // 000000101100x - [13, 1536], // 0000001011010 - [13, 1600], // 0000001011011 - [11, 24], [11, 24], [11, 24], [11, 24], // 00000010111xx - [11, 25], [11, 25], [11, 25], [11, 25], // 00000011000xx - [13, 1664], // 0000001100100 - [13, 1728], // 0000001100101 - [12, 320], [12, 320], // 000000110011x - [12, 384], [12, 384], // 000000110100x - [12, 448], [12, 448], // 000000110101x - [13, 512], // 0000001101100 - [13, 576], // 0000001101101 - [12, 53], [12, 53], // 000000110111x - [12, 54], [12, 54], // 000000111000x - [13, 896], // 0000001110010 - [13, 960], // 0000001110011 - [13, 1024], // 0000001110100 - [13, 1088], // 0000001110101 - [13, 1152], // 0000001110110 - [13, 1216], // 0000001110111 - [10, 64], [10, 64], [10, 64], [10, 64], // 0000001111xxx - [10, 64], [10, 64], [10, 64], [10, 64] - ]; - - var blackTable2 = [ - [8, 13], [8, 13], [8, 13], [8, 13], // 00000100xxxx - [8, 13], [8, 13], [8, 13], [8, 13], - [8, 13], [8, 13], [8, 13], [8, 13], - [8, 13], [8, 13], [8, 13], [8, 13], - [11, 23], [11, 23], // 00000101000x - [12, 50], // 000001010010 - [12, 51], // 000001010011 - [12, 44], // 000001010100 - [12, 45], // 000001010101 - [12, 46], // 000001010110 - [12, 47], // 000001010111 - [12, 57], // 000001011000 - [12, 58], // 000001011001 - [12, 61], // 000001011010 - [12, 256], // 000001011011 - [10, 16], [10, 16], [10, 16], [10, 16], // 0000010111xx - [10, 17], [10, 17], [10, 17], [10, 17], // 0000011000xx - [12, 48], // 000001100100 - [12, 49], // 000001100101 - [12, 62], // 000001100110 - [12, 63], // 000001100111 - [12, 30], // 000001101000 - [12, 31], // 000001101001 - [12, 32], // 000001101010 - [12, 33], // 000001101011 - [12, 40], // 000001101100 - [12, 41], // 000001101101 - [11, 22], [11, 22], // 00000110111x - [8, 14], [8, 14], [8, 14], [8, 14], // 00000111xxxx - [8, 14], [8, 14], [8, 14], [8, 14], - [8, 14], [8, 14], [8, 14], [8, 14], - [8, 14], [8, 14], [8, 14], [8, 14], - [7, 10], [7, 10], [7, 10], [7, 10], // 0000100xxxxx - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 10], [7, 10], [7, 10], [7, 10], - [7, 11], [7, 11], [7, 11], [7, 11], // 0000101xxxxx - [7, 11], [7, 11], [7, 11], [7, 11], - [7, 11], [7, 11], [7, 11], [7, 11], - [7, 11], [7, 11], [7, 11], [7, 11], - [7, 11], [7, 11], [7, 11], [7, 11], - [7, 11], [7, 11], [7, 11], [7, 11], - [7, 11], [7, 11], [7, 11], [7, 11], - [7, 11], [7, 11], [7, 11], [7, 11], - [9, 15], [9, 15], [9, 15], [9, 15], // 000011000xxx - [9, 15], [9, 15], [9, 15], [9, 15], - [12, 128], // 000011001000 - [12, 192], // 000011001001 - [12, 26], // 000011001010 - [12, 27], // 000011001011 - [12, 28], // 000011001100 - [12, 29], // 000011001101 - [11, 19], [11, 19], // 00001100111x - [11, 20], [11, 20], // 00001101000x - [12, 34], // 000011010010 - [12, 35], // 000011010011 - [12, 36], // 000011010100 - [12, 37], // 000011010101 - [12, 38], // 000011010110 - [12, 39], // 000011010111 - [11, 21], [11, 21], // 00001101100x - [12, 42], // 000011011010 - [12, 43], // 000011011011 - [10, 0], [10, 0], [10, 0], [10, 0], // 0000110111xx - [7, 12], [7, 12], [7, 12], [7, 12], // 0000111xxxxx - [7, 12], [7, 12], [7, 12], [7, 12], - [7, 12], [7, 12], [7, 12], [7, 12], - [7, 12], [7, 12], [7, 12], [7, 12], - [7, 12], [7, 12], [7, 12], [7, 12], - [7, 12], [7, 12], [7, 12], [7, 12], - [7, 12], [7, 12], [7, 12], [7, 12], - [7, 12], [7, 12], [7, 12], [7, 12] - ]; - - var blackTable3 = [ - [-1, -1], [-1, -1], [-1, -1], [-1, -1], // 0000xx - [6, 9], // 000100 - [6, 8], // 000101 - [5, 7], [5, 7], // 00011x - [4, 6], [4, 6], [4, 6], [4, 6], // 0010xx - [4, 5], [4, 5], [4, 5], [4, 5], // 0011xx - [3, 1], [3, 1], [3, 1], [3, 1], // 010xxx - [3, 1], [3, 1], [3, 1], [3, 1], - [3, 4], [3, 4], [3, 4], [3, 4], // 011xxx - [3, 4], [3, 4], [3, 4], [3, 4], - [2, 3], [2, 3], [2, 3], [2, 3], // 10xxxx - [2, 3], [2, 3], [2, 3], [2, 3], - [2, 3], [2, 3], [2, 3], [2, 3], - [2, 3], [2, 3], [2, 3], [2, 3], - [2, 2], [2, 2], [2, 2], [2, 2], // 11xxxx - [2, 2], [2, 2], [2, 2], [2, 2], - [2, 2], [2, 2], [2, 2], [2, 2], - [2, 2], [2, 2], [2, 2], [2, 2] - ]; - - function CCITTFaxStream(str, maybeLength, params) { - this.str = str; - this.dict = str.dict; - - params = params || Dict.empty; - - this.encoding = params.get('K') || 0; - this.eoline = params.get('EndOfLine') || false; - this.byteAlign = params.get('EncodedByteAlign') || false; - this.columns = params.get('Columns') || 1728; - this.rows = params.get('Rows') || 0; - var eoblock = params.get('EndOfBlock'); - if (eoblock === null || eoblock === undefined) { - eoblock = true; - } - this.eoblock = eoblock; - this.black = params.get('BlackIs1') || false; - - this.codingLine = new Uint32Array(this.columns + 1); - this.refLine = new Uint32Array(this.columns + 2); - - this.codingLine[0] = this.columns; - this.codingPos = 0; - - this.row = 0; - this.nextLine2D = this.encoding < 0; - this.inputBits = 0; - this.inputBuf = 0; - this.outputBits = 0; - - var code1; - while ((code1 = this.lookBits(12)) === 0) { - this.eatBits(1); - } - if (code1 === 1) { - this.eatBits(12); - } - if (this.encoding > 0) { - this.nextLine2D = !this.lookBits(1); - this.eatBits(1); - } - - DecodeStream.call(this, maybeLength); - } - - CCITTFaxStream.prototype = Object.create(DecodeStream.prototype); - - CCITTFaxStream.prototype.readBlock = function CCITTFaxStream_readBlock() { - while (!this.eof) { - var c = this.lookChar(); - this.ensureBuffer(this.bufferLength + 1); - this.buffer[this.bufferLength++] = c; - } - }; - - CCITTFaxStream.prototype.addPixels = - function ccittFaxStreamAddPixels(a1, blackPixels) { - var codingLine = this.codingLine; - var codingPos = this.codingPos; - - if (a1 > codingLine[codingPos]) { - if (a1 > this.columns) { - info('row is wrong length'); - this.err = true; - a1 = this.columns; - } - if ((codingPos & 1) ^ blackPixels) { - ++codingPos; - } - - codingLine[codingPos] = a1; - } - this.codingPos = codingPos; - }; - - CCITTFaxStream.prototype.addPixelsNeg = - function ccittFaxStreamAddPixelsNeg(a1, blackPixels) { - var codingLine = this.codingLine; - var codingPos = this.codingPos; - - if (a1 > codingLine[codingPos]) { - if (a1 > this.columns) { - info('row is wrong length'); - this.err = true; - a1 = this.columns; - } - if ((codingPos & 1) ^ blackPixels) { - ++codingPos; - } - - codingLine[codingPos] = a1; - } else if (a1 < codingLine[codingPos]) { - if (a1 < 0) { - info('invalid code'); - this.err = true; - a1 = 0; - } - while (codingPos > 0 && a1 < codingLine[codingPos - 1]) { - --codingPos; - } - codingLine[codingPos] = a1; - } - - this.codingPos = codingPos; - }; - - CCITTFaxStream.prototype.lookChar = function CCITTFaxStream_lookChar() { - var refLine = this.refLine; - var codingLine = this.codingLine; - var columns = this.columns; - - var refPos, blackPixels, bits, i; - - if (this.outputBits === 0) { - if (this.eof) { - return null; - } - this.err = false; - - var code1, code2, code3; - if (this.nextLine2D) { - for (i = 0; codingLine[i] < columns; ++i) { - refLine[i] = codingLine[i]; - } - refLine[i++] = columns; - refLine[i] = columns; - codingLine[0] = 0; - this.codingPos = 0; - refPos = 0; - blackPixels = 0; - - while (codingLine[this.codingPos] < columns) { - code1 = this.getTwoDimCode(); - switch (code1) { - case twoDimPass: - this.addPixels(refLine[refPos + 1], blackPixels); - if (refLine[refPos + 1] < columns) { - refPos += 2; - } - break; - case twoDimHoriz: - code1 = code2 = 0; - if (blackPixels) { - do { - code1 += (code3 = this.getBlackCode()); - } while (code3 >= 64); - do { - code2 += (code3 = this.getWhiteCode()); - } while (code3 >= 64); - } else { - do { - code1 += (code3 = this.getWhiteCode()); - } while (code3 >= 64); - do { - code2 += (code3 = this.getBlackCode()); - } while (code3 >= 64); - } - this.addPixels(codingLine[this.codingPos] + - code1, blackPixels); - if (codingLine[this.codingPos] < columns) { - this.addPixels(codingLine[this.codingPos] + code2, - blackPixels ^ 1); - } - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - break; - case twoDimVertR3: - this.addPixels(refLine[refPos] + 3, blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - ++refPos; - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case twoDimVertR2: - this.addPixels(refLine[refPos] + 2, blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - ++refPos; - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case twoDimVertR1: - this.addPixels(refLine[refPos] + 1, blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - ++refPos; - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case twoDimVert0: - this.addPixels(refLine[refPos], blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - ++refPos; - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case twoDimVertL3: - this.addPixelsNeg(refLine[refPos] - 3, blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - if (refPos > 0) { - --refPos; - } else { - ++refPos; - } - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case twoDimVertL2: - this.addPixelsNeg(refLine[refPos] - 2, blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - if (refPos > 0) { - --refPos; - } else { - ++refPos; - } - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case twoDimVertL1: - this.addPixelsNeg(refLine[refPos] - 1, blackPixels); - blackPixels ^= 1; - if (codingLine[this.codingPos] < columns) { - if (refPos > 0) { - --refPos; - } else { - ++refPos; - } - while (refLine[refPos] <= codingLine[this.codingPos] && - refLine[refPos] < columns) { - refPos += 2; - } - } - break; - case EOF: - this.addPixels(columns, 0); - this.eof = true; - break; - default: - info('bad 2d code'); - this.addPixels(columns, 0); - this.err = true; - } - } - } else { - codingLine[0] = 0; - this.codingPos = 0; - blackPixels = 0; - while (codingLine[this.codingPos] < columns) { - code1 = 0; - if (blackPixels) { - do { - code1 += (code3 = this.getBlackCode()); - } while (code3 >= 64); - } else { - do { - code1 += (code3 = this.getWhiteCode()); - } while (code3 >= 64); - } - this.addPixels(codingLine[this.codingPos] + code1, blackPixels); - blackPixels ^= 1; - } - } - - var gotEOL = false; - - if (this.byteAlign) { - this.inputBits &= ~7; - } - - if (!this.eoblock && this.row === this.rows - 1) { - this.eof = true; - } else { - code1 = this.lookBits(12); - if (this.eoline) { - while (code1 !== EOF && code1 !== 1) { - this.eatBits(1); - code1 = this.lookBits(12); - } - } else { - while (code1 === 0) { - this.eatBits(1); - code1 = this.lookBits(12); - } - } - if (code1 === 1) { - this.eatBits(12); - gotEOL = true; - } else if (code1 === EOF) { - this.eof = true; - } - } - - if (!this.eof && this.encoding > 0) { - this.nextLine2D = !this.lookBits(1); - this.eatBits(1); - } - - if (this.eoblock && gotEOL && this.byteAlign) { - code1 = this.lookBits(12); - if (code1 === 1) { - this.eatBits(12); - if (this.encoding > 0) { - this.lookBits(1); - this.eatBits(1); - } - if (this.encoding >= 0) { - for (i = 0; i < 4; ++i) { - code1 = this.lookBits(12); - if (code1 !== 1) { - info('bad rtc code: ' + code1); - } - this.eatBits(12); - if (this.encoding > 0) { - this.lookBits(1); - this.eatBits(1); - } - } - } - this.eof = true; - } - } else if (this.err && this.eoline) { - while (true) { - code1 = this.lookBits(13); - if (code1 === EOF) { - this.eof = true; - return null; - } - if ((code1 >> 1) === 1) { - break; - } - this.eatBits(1); - } - this.eatBits(12); - if (this.encoding > 0) { - this.eatBits(1); - this.nextLine2D = !(code1 & 1); - } - } - - if (codingLine[0] > 0) { - this.outputBits = codingLine[this.codingPos = 0]; - } else { - this.outputBits = codingLine[this.codingPos = 1]; - } - this.row++; - } - - var c; - if (this.outputBits >= 8) { - c = (this.codingPos & 1) ? 0 : 0xFF; - this.outputBits -= 8; - if (this.outputBits === 0 && codingLine[this.codingPos] < columns) { - this.codingPos++; - this.outputBits = (codingLine[this.codingPos] - - codingLine[this.codingPos - 1]); - } - } else { - bits = 8; - c = 0; - do { - if (this.outputBits > bits) { - c <<= bits; - if (!(this.codingPos & 1)) { - c |= 0xFF >> (8 - bits); - } - this.outputBits -= bits; - bits = 0; - } else { - c <<= this.outputBits; - if (!(this.codingPos & 1)) { - c |= 0xFF >> (8 - this.outputBits); - } - bits -= this.outputBits; - this.outputBits = 0; - if (codingLine[this.codingPos] < columns) { - this.codingPos++; - this.outputBits = (codingLine[this.codingPos] - - codingLine[this.codingPos - 1]); - } else if (bits > 0) { - c <<= bits; - bits = 0; - } - } - } while (bits); - } - if (this.black) { - c ^= 0xFF; - } - return c; - }; - - // This functions returns the code found from the table. - // The start and end parameters set the boundaries for searching the table. - // The limit parameter is optional. Function returns an array with three - // values. The first array element indicates whether a valid code is being - // returned. The second array element is the actual code. The third array - // element indicates whether EOF was reached. - CCITTFaxStream.prototype.findTableCode = - function ccittFaxStreamFindTableCode(start, end, table, limit) { - - var limitValue = limit || 0; - for (var i = start; i <= end; ++i) { - var code = this.lookBits(i); - if (code === EOF) { - return [true, 1, false]; - } - if (i < end) { - code <<= end - i; - } - if (!limitValue || code >= limitValue) { - var p = table[code - limitValue]; - if (p[0] === i) { - this.eatBits(i); - return [true, p[1], true]; - } - } - } - return [false, 0, false]; - }; - - CCITTFaxStream.prototype.getTwoDimCode = - function ccittFaxStreamGetTwoDimCode() { - - var code = 0; - var p; - if (this.eoblock) { - code = this.lookBits(7); - p = twoDimTable[code]; - if (p && p[0] > 0) { - this.eatBits(p[0]); - return p[1]; - } - } else { - var result = this.findTableCode(1, 7, twoDimTable); - if (result[0] && result[2]) { - return result[1]; - } - } - info('Bad two dim code'); - return EOF; - }; - - CCITTFaxStream.prototype.getWhiteCode = - function ccittFaxStreamGetWhiteCode() { - - var code = 0; - var p; - if (this.eoblock) { - code = this.lookBits(12); - if (code === EOF) { - return 1; - } - - if ((code >> 5) === 0) { - p = whiteTable1[code]; - } else { - p = whiteTable2[code >> 3]; - } - - if (p[0] > 0) { - this.eatBits(p[0]); - return p[1]; - } - } else { - var result = this.findTableCode(1, 9, whiteTable2); - if (result[0]) { - return result[1]; - } - - result = this.findTableCode(11, 12, whiteTable1); - if (result[0]) { - return result[1]; - } - } - info('bad white code'); - this.eatBits(1); - return 1; - }; - - CCITTFaxStream.prototype.getBlackCode = - function ccittFaxStreamGetBlackCode() { - - var code, p; - if (this.eoblock) { - code = this.lookBits(13); - if (code === EOF) { - return 1; - } - if ((code >> 7) === 0) { - p = blackTable1[code]; - } else if ((code >> 9) === 0 && (code >> 7) !== 0) { - p = blackTable2[(code >> 1) - 64]; - } else { - p = blackTable3[code >> 7]; - } - - if (p[0] > 0) { - this.eatBits(p[0]); - return p[1]; - } - } else { - var result = this.findTableCode(2, 6, blackTable3); - if (result[0]) { - return result[1]; - } - - result = this.findTableCode(7, 12, blackTable2, 64); - if (result[0]) { - return result[1]; - } - - result = this.findTableCode(10, 13, blackTable1); - if (result[0]) { - return result[1]; - } - } - info('bad black code'); - this.eatBits(1); - return 1; - }; - - CCITTFaxStream.prototype.lookBits = function CCITTFaxStream_lookBits(n) { - var c; - while (this.inputBits < n) { - if ((c = this.str.getByte()) === -1) { - if (this.inputBits === 0) { - return EOF; - } - return ((this.inputBuf << (n - this.inputBits)) & - (0xFFFF >> (16 - n))); - } - this.inputBuf = (this.inputBuf << 8) + c; - this.inputBits += 8; - } - return (this.inputBuf >> (this.inputBits - n)) & (0xFFFF >> (16 - n)); - }; - - CCITTFaxStream.prototype.eatBits = function CCITTFaxStream_eatBits(n) { - if ((this.inputBits -= n) < 0) { - this.inputBits = 0; - } - }; - - return CCITTFaxStream; -})(); - -var LZWStream = (function LZWStreamClosure() { - function LZWStream(str, maybeLength, earlyChange) { - this.str = str; - this.dict = str.dict; - this.cachedData = 0; - this.bitsCached = 0; - - var maxLzwDictionarySize = 4096; - var lzwState = { - earlyChange: earlyChange, - codeLength: 9, - nextCode: 258, - dictionaryValues: new Uint8Array(maxLzwDictionarySize), - dictionaryLengths: new Uint16Array(maxLzwDictionarySize), - dictionaryPrevCodes: new Uint16Array(maxLzwDictionarySize), - currentSequence: new Uint8Array(maxLzwDictionarySize), - currentSequenceLength: 0 - }; - for (var i = 0; i < 256; ++i) { - lzwState.dictionaryValues[i] = i; - lzwState.dictionaryLengths[i] = 1; - } - this.lzwState = lzwState; - - DecodeStream.call(this, maybeLength); - } - - LZWStream.prototype = Object.create(DecodeStream.prototype); - - LZWStream.prototype.readBits = function LZWStream_readBits(n) { - var bitsCached = this.bitsCached; - var cachedData = this.cachedData; - while (bitsCached < n) { - var c = this.str.getByte(); - if (c === -1) { - this.eof = true; - return null; - } - cachedData = (cachedData << 8) | c; - bitsCached += 8; - } - this.bitsCached = (bitsCached -= n); - this.cachedData = cachedData; - this.lastCode = null; - return (cachedData >>> bitsCached) & ((1 << n) - 1); - }; - - LZWStream.prototype.readBlock = function LZWStream_readBlock() { - var blockSize = 512; - var estimatedDecodedSize = blockSize * 2, decodedSizeDelta = blockSize; - var i, j, q; - - var lzwState = this.lzwState; - if (!lzwState) { - return; // eof was found - } - - var earlyChange = lzwState.earlyChange; - var nextCode = lzwState.nextCode; - var dictionaryValues = lzwState.dictionaryValues; - var dictionaryLengths = lzwState.dictionaryLengths; - var dictionaryPrevCodes = lzwState.dictionaryPrevCodes; - var codeLength = lzwState.codeLength; - var prevCode = lzwState.prevCode; - var currentSequence = lzwState.currentSequence; - var currentSequenceLength = lzwState.currentSequenceLength; - - var decodedLength = 0; - var currentBufferLength = this.bufferLength; - var buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize); - - for (i = 0; i < blockSize; i++) { - var code = this.readBits(codeLength); - var hasPrev = currentSequenceLength > 0; - if (code < 256) { - currentSequence[0] = code; - currentSequenceLength = 1; - } else if (code >= 258) { - if (code < nextCode) { - currentSequenceLength = dictionaryLengths[code]; - for (j = currentSequenceLength - 1, q = code; j >= 0; j--) { - currentSequence[j] = dictionaryValues[q]; - q = dictionaryPrevCodes[q]; - } - } else { - currentSequence[currentSequenceLength++] = currentSequence[0]; - } - } else if (code === 256) { - codeLength = 9; - nextCode = 258; - currentSequenceLength = 0; - continue; - } else { - this.eof = true; - delete this.lzwState; - break; - } - - if (hasPrev) { - dictionaryPrevCodes[nextCode] = prevCode; - dictionaryLengths[nextCode] = dictionaryLengths[prevCode] + 1; - dictionaryValues[nextCode] = currentSequence[0]; - nextCode++; - codeLength = (nextCode + earlyChange) & (nextCode + earlyChange - 1) ? - codeLength : Math.min(Math.log(nextCode + earlyChange) / - 0.6931471805599453 + 1, 12) | 0; - } - prevCode = code; - - decodedLength += currentSequenceLength; - if (estimatedDecodedSize < decodedLength) { - do { - estimatedDecodedSize += decodedSizeDelta; - } while (estimatedDecodedSize < decodedLength); - buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize); - } - for (j = 0; j < currentSequenceLength; j++) { - buffer[currentBufferLength++] = currentSequence[j]; - } - } - lzwState.nextCode = nextCode; - lzwState.codeLength = codeLength; - lzwState.prevCode = prevCode; - lzwState.currentSequenceLength = currentSequenceLength; - - this.bufferLength = currentBufferLength; - }; - - return LZWStream; -})(); - -var NullStream = (function NullStreamClosure() { - function NullStream() { - Stream.call(this, new Uint8Array(0)); - } - - NullStream.prototype = Stream.prototype; - - return NullStream; -})(); - - -var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { - setup: function wphSetup(handler) { - var pdfManager; - - function loadDocument(recoveryMode) { - var loadDocumentCapability = createPromiseCapability(); - - var parseSuccess = function parseSuccess() { - var numPagesPromise = pdfManager.ensureDoc('numPages'); - var fingerprintPromise = pdfManager.ensureDoc('fingerprint'); - var encryptedPromise = pdfManager.ensureXRef('encrypt'); - Promise.all([numPagesPromise, fingerprintPromise, - encryptedPromise]).then(function onDocReady(results) { - var doc = { - numPages: results[0], - fingerprint: results[1], - encrypted: !!results[2], - }; - loadDocumentCapability.resolve(doc); - }, - parseFailure); - }; - - var parseFailure = function parseFailure(e) { - loadDocumentCapability.reject(e); - }; - - pdfManager.ensureDoc('checkHeader', []).then(function() { - pdfManager.ensureDoc('parseStartXRef', []).then(function() { - pdfManager.ensureDoc('parse', [recoveryMode]).then( - parseSuccess, parseFailure); - }, parseFailure); - }, parseFailure); - - return loadDocumentCapability.promise; - } - - function getPdfManager(data) { - var pdfManagerCapability = createPromiseCapability(); - - var source = data.source; - var disableRange = data.disableRange; - if (source.data) { - try { - pdfManager = new LocalPdfManager(source.data, source.password); - pdfManagerCapability.resolve(); - } catch (ex) { - pdfManagerCapability.reject(ex); - } - return pdfManagerCapability.promise; - } else if (source.chunkedViewerLoading) { - try { - pdfManager = new NetworkPdfManager(source, handler); - pdfManagerCapability.resolve(); - } catch (ex) { - pdfManagerCapability.reject(ex); - } - return pdfManagerCapability.promise; - } - - var networkManager = new NetworkManager(source.url, { - httpHeaders: source.httpHeaders, - withCredentials: source.withCredentials - }); - var cachedChunks = []; - var fullRequestXhrId = networkManager.requestFull({ - onHeadersReceived: function onHeadersReceived() { - if (disableRange) { - return; - } - - var fullRequestXhr = networkManager.getRequestXhr(fullRequestXhrId); - if (fullRequestXhr.getResponseHeader('Accept-Ranges') !== 'bytes') { - return; - } - - var contentEncoding = - fullRequestXhr.getResponseHeader('Content-Encoding') || 'identity'; - if (contentEncoding !== 'identity') { - return; - } - - var length = fullRequestXhr.getResponseHeader('Content-Length'); - length = parseInt(length, 10); - if (!isInt(length)) { - return; - } - source.length = length; - if (length <= 2 * RANGE_CHUNK_SIZE) { - // The file size is smaller than the size of two chunks, so it does - // not make any sense to abort the request and retry with a range - // request. - return; - } - - if (networkManager.isStreamingRequest(fullRequestXhrId)) { - // We can continue fetching when progressive loading is enabled, - // and we don't need the autoFetch feature. - source.disableAutoFetch = true; - } else { - // NOTE: by cancelling the full request, and then issuing range - // requests, there will be an issue for sites where you can only - // request the pdf once. However, if this is the case, then the - // server should not be returning that it can support range - // requests. - networkManager.abortRequest(fullRequestXhrId); - } - - try { - pdfManager = new NetworkPdfManager(source, handler); - pdfManagerCapability.resolve(pdfManager); - } catch (ex) { - pdfManagerCapability.reject(ex); - } - }, - - onProgressiveData: source.disableStream ? null : - function onProgressiveData(chunk) { - if (!pdfManager) { - cachedChunks.push(chunk); - return; - } - pdfManager.sendProgressiveData(chunk); - }, - - onDone: function onDone(args) { - if (pdfManager) { - return; // already processed - } - - var pdfFile; - if (args === null) { - // TODO add some streaming manager, e.g. for unknown length files. - // The data was returned in the onProgressiveData, combining... - var pdfFileLength = 0, pos = 0; - cachedChunks.forEach(function (chunk) { - pdfFileLength += chunk.byteLength; - }); - if (source.length && pdfFileLength !== source.length) { - warn('reported HTTP length is different from actual'); - } - var pdfFileArray = new Uint8Array(pdfFileLength); - cachedChunks.forEach(function (chunk) { - pdfFileArray.set(new Uint8Array(chunk), pos); - pos += chunk.byteLength; - }); - pdfFile = pdfFileArray.buffer; - } else { - pdfFile = args.chunk; - } - - // the data is array, instantiating directly from it - try { - pdfManager = new LocalPdfManager(pdfFile, source.password); - pdfManagerCapability.resolve(); - } catch (ex) { - pdfManagerCapability.reject(ex); - } - }, - - onError: function onError(status) { - var exception; - if (status === 404) { - exception = new MissingPDFException('Missing PDF "' + - source.url + '".'); - handler.send('MissingPDF', exception); - } else { - exception = new UnexpectedResponseException( - 'Unexpected server response (' + status + - ') while retrieving PDF "' + source.url + '".', status); - handler.send('UnexpectedResponse', exception); - } - }, - - onProgress: function onProgress(evt) { - handler.send('DocProgress', { - loaded: evt.loaded, - total: evt.lengthComputable ? evt.total : source.length - }); - } - }); - - return pdfManagerCapability.promise; - } - - handler.on('test', function wphSetupTest(data) { - // check if Uint8Array can be sent to worker - if (!(data instanceof Uint8Array)) { - handler.send('test', false); - return; - } - // making sure postMessage transfers are working - var supportTransfers = data[0] === 255; - handler.postMessageTransfers = supportTransfers; - // check if the response property is supported by xhr - var xhr = new XMLHttpRequest(); - var responseExists = 'response' in xhr; - // check if the property is actually implemented - try { - var dummy = xhr.responseType; - } catch (e) { - responseExists = false; - } - if (!responseExists) { - handler.send('test', false); - return; - } - handler.send('test', { - supportTypedArray: true, - supportTransfers: supportTransfers - }); - }); - - handler.on('GetDocRequest', function wphSetupDoc(data) { - - var onSuccess = function(doc) { - handler.send('GetDoc', { pdfInfo: doc }); - }; - - var onFailure = function(e) { - if (e instanceof PasswordException) { - if (e.code === PasswordResponses.NEED_PASSWORD) { - handler.send('NeedPassword', e); - } else if (e.code === PasswordResponses.INCORRECT_PASSWORD) { - handler.send('IncorrectPassword', e); - } - } else if (e instanceof InvalidPDFException) { - handler.send('InvalidPDF', e); - } else if (e instanceof MissingPDFException) { - handler.send('MissingPDF', e); - } else if (e instanceof UnexpectedResponseException) { - handler.send('UnexpectedResponse', e); - } else { - handler.send('UnknownError', - new UnknownErrorException(e.message, e.toString())); - } - }; - - PDFJS.maxImageSize = data.maxImageSize === undefined ? - -1 : data.maxImageSize; - PDFJS.disableFontFace = data.disableFontFace; - PDFJS.disableCreateObjectURL = data.disableCreateObjectURL; - PDFJS.verbosity = data.verbosity; - PDFJS.cMapUrl = data.cMapUrl === undefined ? - null : data.cMapUrl; - PDFJS.cMapPacked = data.cMapPacked === true; - - getPdfManager(data).then(function () { - handler.send('PDFManagerReady', null); - pdfManager.onLoadedStream().then(function(stream) { - handler.send('DataLoaded', { length: stream.bytes.byteLength }); - }); - }).then(function pdfManagerReady() { - loadDocument(false).then(onSuccess, function loadFailure(ex) { - // Try again with recoveryMode == true - if (!(ex instanceof XRefParseException)) { - if (ex instanceof PasswordException) { - // after password exception prepare to receive a new password - // to repeat loading - pdfManager.passwordChanged().then(pdfManagerReady); - } - - onFailure(ex); - return; - } - - pdfManager.requestLoadedStream(); - pdfManager.onLoadedStream().then(function() { - loadDocument(true).then(onSuccess, onFailure); - }); - }, onFailure); - }, onFailure); - }); - - handler.on('GetPage', function wphSetupGetPage(data) { - return pdfManager.getPage(data.pageIndex).then(function(page) { - var rotatePromise = pdfManager.ensure(page, 'rotate'); - var refPromise = pdfManager.ensure(page, 'ref'); - var viewPromise = pdfManager.ensure(page, 'view'); - - return Promise.all([rotatePromise, refPromise, viewPromise]).then( - function(results) { - return { - rotate: results[0], - ref: results[1], - view: results[2] - }; - }); - }); - }); - - handler.on('GetPageIndex', function wphSetupGetPageIndex(data) { - var ref = new Ref(data.ref.num, data.ref.gen); - var catalog = pdfManager.pdfDocument.catalog; - return catalog.getPageIndex(ref); - }); - - handler.on('GetDestinations', - function wphSetupGetDestinations(data) { - return pdfManager.ensureCatalog('destinations'); - } - ); - - handler.on('GetDestination', - function wphSetupGetDestination(data) { - return pdfManager.ensureCatalog('getDestination', [ data.id ]); - } - ); - - handler.on('GetAttachments', - function wphSetupGetAttachments(data) { - return pdfManager.ensureCatalog('attachments'); - } - ); - - handler.on('GetJavaScript', - function wphSetupGetJavaScript(data) { - return pdfManager.ensureCatalog('javaScript'); - } - ); - - handler.on('GetOutline', - function wphSetupGetOutline(data) { - return pdfManager.ensureCatalog('documentOutline'); - } - ); - - handler.on('GetMetadata', - function wphSetupGetMetadata(data) { - return Promise.all([pdfManager.ensureDoc('documentInfo'), - pdfManager.ensureCatalog('metadata')]); - } - ); - - handler.on('GetData', function wphSetupGetData(data) { - pdfManager.requestLoadedStream(); - return pdfManager.onLoadedStream().then(function(stream) { - return stream.bytes; - }); - }); - - handler.on('GetStats', - function wphSetupGetStats(data) { - return pdfManager.pdfDocument.xref.stats; - } - ); - - handler.on('UpdatePassword', function wphSetupUpdatePassword(data) { - pdfManager.updatePassword(data); - }); - - handler.on('GetAnnotations', function wphSetupGetAnnotations(data) { - return pdfManager.getPage(data.pageIndex).then(function(page) { - return pdfManager.ensure(page, 'getAnnotationsData', []); - }); - }); - - handler.on('RenderPageRequest', function wphSetupRenderPage(data) { - pdfManager.getPage(data.pageIndex).then(function(page) { - - var pageNum = data.pageIndex + 1; - var start = Date.now(); - // Pre compile the pdf page and fetch the fonts/images. - page.getOperatorList(handler, data.intent).then(function(operatorList) { - - info('page=' + pageNum + ' - getOperatorList: time=' + - (Date.now() - start) + 'ms, len=' + operatorList.fnArray.length); - - }, function(e) { - - var minimumStackMessage = - 'worker.js: while trying to getPage() and getOperatorList()'; - - var wrappedException; - - // Turn the error into an obj that can be serialized - if (typeof e === 'string') { - wrappedException = { - message: e, - stack: minimumStackMessage - }; - } else if (typeof e === 'object') { - wrappedException = { - message: e.message || e.toString(), - stack: e.stack || minimumStackMessage - }; - } else { - wrappedException = { - message: 'Unknown exception type: ' + (typeof e), - stack: minimumStackMessage - }; - } - - handler.send('PageError', { - pageNum: pageNum, - error: wrappedException, - intent: data.intent - }); - }); - }); - }, this); - - handler.on('GetTextContent', function wphExtractText(data) { - return pdfManager.getPage(data.pageIndex).then(function(page) { - var pageNum = data.pageIndex + 1; - var start = Date.now(); - return page.extractTextContent().then(function(textContent) { - info('text indexing: page=' + pageNum + ' - time=' + - (Date.now() - start) + 'ms'); - return textContent; - }); - }); - }); - - handler.on('Cleanup', function wphCleanup(data) { - return pdfManager.cleanup(); - }); - - handler.on('Terminate', function wphTerminate(data) { - pdfManager.terminate(); - }); - } -}; - -var consoleTimer = {}; - -var workerConsole = { - log: function log() { - var args = Array.prototype.slice.call(arguments); - globalScope.postMessage({ - action: 'console_log', - data: args - }); - }, - - error: function error() { - var args = Array.prototype.slice.call(arguments); - globalScope.postMessage({ - action: 'console_error', - data: args - }); - throw 'pdf.js execution error'; - }, - - time: function time(name) { - consoleTimer[name] = Date.now(); - }, - - timeEnd: function timeEnd(name) { - var time = consoleTimer[name]; - if (!time) { - error('Unknown timer name ' + name); - } - this.log('Timer:', name, Date.now() - time); - } -}; - - -// Worker thread? -if (typeof window === 'undefined') { - if (!('console' in globalScope)) { - globalScope.console = workerConsole; - } - - // Listen for unsupported features so we can pass them on to the main thread. - PDFJS.UnsupportedManager.listen(function (msg) { - globalScope.postMessage({ - action: '_unsupported_feature', - data: msg - }); - }); - - var handler = new MessageHandler('worker_processor', this); - WorkerMessageHandler.setup(handler); -} - - -/* This class implements the QM Coder decoding as defined in - * JPEG 2000 Part I Final Committee Draft Version 1.0 - * Annex C.3 Arithmetic decoding procedure - * available at http://www.jpeg.org/public/fcd15444-1.pdf - * - * The arithmetic decoder is used in conjunction with context models to decode - * JPEG2000 and JBIG2 streams. - */ -var ArithmeticDecoder = (function ArithmeticDecoderClosure() { - // Table C-2 - var QeTable = [ - {qe: 0x5601, nmps: 1, nlps: 1, switchFlag: 1}, - {qe: 0x3401, nmps: 2, nlps: 6, switchFlag: 0}, - {qe: 0x1801, nmps: 3, nlps: 9, switchFlag: 0}, - {qe: 0x0AC1, nmps: 4, nlps: 12, switchFlag: 0}, - {qe: 0x0521, nmps: 5, nlps: 29, switchFlag: 0}, - {qe: 0x0221, nmps: 38, nlps: 33, switchFlag: 0}, - {qe: 0x5601, nmps: 7, nlps: 6, switchFlag: 1}, - {qe: 0x5401, nmps: 8, nlps: 14, switchFlag: 0}, - {qe: 0x4801, nmps: 9, nlps: 14, switchFlag: 0}, - {qe: 0x3801, nmps: 10, nlps: 14, switchFlag: 0}, - {qe: 0x3001, nmps: 11, nlps: 17, switchFlag: 0}, - {qe: 0x2401, nmps: 12, nlps: 18, switchFlag: 0}, - {qe: 0x1C01, nmps: 13, nlps: 20, switchFlag: 0}, - {qe: 0x1601, nmps: 29, nlps: 21, switchFlag: 0}, - {qe: 0x5601, nmps: 15, nlps: 14, switchFlag: 1}, - {qe: 0x5401, nmps: 16, nlps: 14, switchFlag: 0}, - {qe: 0x5101, nmps: 17, nlps: 15, switchFlag: 0}, - {qe: 0x4801, nmps: 18, nlps: 16, switchFlag: 0}, - {qe: 0x3801, nmps: 19, nlps: 17, switchFlag: 0}, - {qe: 0x3401, nmps: 20, nlps: 18, switchFlag: 0}, - {qe: 0x3001, nmps: 21, nlps: 19, switchFlag: 0}, - {qe: 0x2801, nmps: 22, nlps: 19, switchFlag: 0}, - {qe: 0x2401, nmps: 23, nlps: 20, switchFlag: 0}, - {qe: 0x2201, nmps: 24, nlps: 21, switchFlag: 0}, - {qe: 0x1C01, nmps: 25, nlps: 22, switchFlag: 0}, - {qe: 0x1801, nmps: 26, nlps: 23, switchFlag: 0}, - {qe: 0x1601, nmps: 27, nlps: 24, switchFlag: 0}, - {qe: 0x1401, nmps: 28, nlps: 25, switchFlag: 0}, - {qe: 0x1201, nmps: 29, nlps: 26, switchFlag: 0}, - {qe: 0x1101, nmps: 30, nlps: 27, switchFlag: 0}, - {qe: 0x0AC1, nmps: 31, nlps: 28, switchFlag: 0}, - {qe: 0x09C1, nmps: 32, nlps: 29, switchFlag: 0}, - {qe: 0x08A1, nmps: 33, nlps: 30, switchFlag: 0}, - {qe: 0x0521, nmps: 34, nlps: 31, switchFlag: 0}, - {qe: 0x0441, nmps: 35, nlps: 32, switchFlag: 0}, - {qe: 0x02A1, nmps: 36, nlps: 33, switchFlag: 0}, - {qe: 0x0221, nmps: 37, nlps: 34, switchFlag: 0}, - {qe: 0x0141, nmps: 38, nlps: 35, switchFlag: 0}, - {qe: 0x0111, nmps: 39, nlps: 36, switchFlag: 0}, - {qe: 0x0085, nmps: 40, nlps: 37, switchFlag: 0}, - {qe: 0x0049, nmps: 41, nlps: 38, switchFlag: 0}, - {qe: 0x0025, nmps: 42, nlps: 39, switchFlag: 0}, - {qe: 0x0015, nmps: 43, nlps: 40, switchFlag: 0}, - {qe: 0x0009, nmps: 44, nlps: 41, switchFlag: 0}, - {qe: 0x0005, nmps: 45, nlps: 42, switchFlag: 0}, - {qe: 0x0001, nmps: 45, nlps: 43, switchFlag: 0}, - {qe: 0x5601, nmps: 46, nlps: 46, switchFlag: 0} - ]; - - // C.3.5 Initialisation of the decoder (INITDEC) - function ArithmeticDecoder(data, start, end) { - this.data = data; - this.bp = start; - this.dataEnd = end; - - this.chigh = data[start]; - this.clow = 0; - - this.byteIn(); - - this.chigh = ((this.chigh << 7) & 0xFFFF) | ((this.clow >> 9) & 0x7F); - this.clow = (this.clow << 7) & 0xFFFF; - this.ct -= 7; - this.a = 0x8000; - } - - ArithmeticDecoder.prototype = { - // C.3.4 Compressed data input (BYTEIN) - byteIn: function ArithmeticDecoder_byteIn() { - var data = this.data; - var bp = this.bp; - if (data[bp] === 0xFF) { - var b1 = data[bp + 1]; - if (b1 > 0x8F) { - this.clow += 0xFF00; - this.ct = 8; - } else { - bp++; - this.clow += (data[bp] << 9); - this.ct = 7; - this.bp = bp; - } - } else { - bp++; - this.clow += bp < this.dataEnd ? (data[bp] << 8) : 0xFF00; - this.ct = 8; - this.bp = bp; - } - if (this.clow > 0xFFFF) { - this.chigh += (this.clow >> 16); - this.clow &= 0xFFFF; - } - }, - // C.3.2 Decoding a decision (DECODE) - readBit: function ArithmeticDecoder_readBit(contexts, pos) { - // contexts are packed into 1 byte: - // highest 7 bits carry cx.index, lowest bit carries cx.mps - var cx_index = contexts[pos] >> 1, cx_mps = contexts[pos] & 1; - var qeTableIcx = QeTable[cx_index]; - var qeIcx = qeTableIcx.qe; - var d; - var a = this.a - qeIcx; - - if (this.chigh < qeIcx) { - // exchangeLps - if (a < qeIcx) { - a = qeIcx; - d = cx_mps; - cx_index = qeTableIcx.nmps; - } else { - a = qeIcx; - d = 1 ^ cx_mps; - if (qeTableIcx.switchFlag === 1) { - cx_mps = d; - } - cx_index = qeTableIcx.nlps; - } - } else { - this.chigh -= qeIcx; - if ((a & 0x8000) !== 0) { - this.a = a; - return cx_mps; - } - // exchangeMps - if (a < qeIcx) { - d = 1 ^ cx_mps; - if (qeTableIcx.switchFlag === 1) { - cx_mps = d; - } - cx_index = qeTableIcx.nlps; - } else { - d = cx_mps; - cx_index = qeTableIcx.nmps; - } - } - // C.3.3 renormD; - do { - if (this.ct === 0) { - this.byteIn(); - } - - a <<= 1; - this.chigh = ((this.chigh << 1) & 0xFFFF) | ((this.clow >> 15) & 1); - this.clow = (this.clow << 1) & 0xFFFF; - this.ct--; - } while ((a & 0x8000) === 0); - this.a = a; - - contexts[pos] = cx_index << 1 | cx_mps; - return d; - } - }; - - return ArithmeticDecoder; -})(); - - -var JpegImage = (function jpegImage() { - var dctZigZag = new Uint8Array([ - 0, - 1, 8, - 16, 9, 2, - 3, 10, 17, 24, - 32, 25, 18, 11, 4, - 5, 12, 19, 26, 33, 40, - 48, 41, 34, 27, 20, 13, 6, - 7, 14, 21, 28, 35, 42, 49, 56, - 57, 50, 43, 36, 29, 22, 15, - 23, 30, 37, 44, 51, 58, - 59, 52, 45, 38, 31, - 39, 46, 53, 60, - 61, 54, 47, - 55, 62, - 63 - ]); - - var dctCos1 = 4017; // cos(pi/16) - var dctSin1 = 799; // sin(pi/16) - var dctCos3 = 3406; // cos(3*pi/16) - var dctSin3 = 2276; // sin(3*pi/16) - var dctCos6 = 1567; // cos(6*pi/16) - var dctSin6 = 3784; // sin(6*pi/16) - var dctSqrt2 = 5793; // sqrt(2) - var dctSqrt1d2 = 2896; // sqrt(2) / 2 - - function constructor() { - } - - function buildHuffmanTable(codeLengths, values) { - var k = 0, code = [], i, j, length = 16; - while (length > 0 && !codeLengths[length - 1]) { - length--; - } - code.push({children: [], index: 0}); - var p = code[0], q; - for (i = 0; i < length; i++) { - for (j = 0; j < codeLengths[i]; j++) { - p = code.pop(); - p.children[p.index] = values[k]; - while (p.index > 0) { - p = code.pop(); - } - p.index++; - code.push(p); - while (code.length <= i) { - code.push(q = {children: [], index: 0}); - p.children[p.index] = q.children; - p = q; - } - k++; - } - if (i + 1 < length) { - // p here points to last code - code.push(q = {children: [], index: 0}); - p.children[p.index] = q.children; - p = q; - } - } - return code[0].children; - } - - function getBlockBufferOffset(component, row, col) { - return 64 * ((component.blocksPerLine + 1) * row + col); - } - - function decodeScan(data, offset, frame, components, resetInterval, - spectralStart, spectralEnd, successivePrev, successive) { - var precision = frame.precision; - var samplesPerLine = frame.samplesPerLine; - var scanLines = frame.scanLines; - var mcusPerLine = frame.mcusPerLine; - var progressive = frame.progressive; - var maxH = frame.maxH, maxV = frame.maxV; - - var startOffset = offset, bitsData = 0, bitsCount = 0; - - function readBit() { - if (bitsCount > 0) { - bitsCount--; - return (bitsData >> bitsCount) & 1; - } - bitsData = data[offset++]; - if (bitsData === 0xFF) { - var nextByte = data[offset++]; - if (nextByte) { - throw 'unexpected marker: ' + - ((bitsData << 8) | nextByte).toString(16); - } - // unstuff 0 - } - bitsCount = 7; - return bitsData >>> 7; - } - - function decodeHuffman(tree) { - var node = tree; - while (true) { - node = node[readBit()]; - if (typeof node === 'number') { - return node; - } - if (typeof node !== 'object') { - throw 'invalid huffman sequence'; - } - } - } - - function receive(length) { - var n = 0; - while (length > 0) { - n = (n << 1) | readBit(); - length--; - } - return n; - } - - function receiveAndExtend(length) { - if (length === 1) { - return readBit() === 1 ? 1 : -1; - } - var n = receive(length); - if (n >= 1 << (length - 1)) { - return n; - } - return n + (-1 << length) + 1; - } - - function decodeBaseline(component, offset) { - var t = decodeHuffman(component.huffmanTableDC); - var diff = t === 0 ? 0 : receiveAndExtend(t); - component.blockData[offset] = (component.pred += diff); - var k = 1; - while (k < 64) { - var rs = decodeHuffman(component.huffmanTableAC); - var s = rs & 15, r = rs >> 4; - if (s === 0) { - if (r < 15) { - break; - } - k += 16; - continue; - } - k += r; - var z = dctZigZag[k]; - component.blockData[offset + z] = receiveAndExtend(s); - k++; - } - } - - function decodeDCFirst(component, offset) { - var t = decodeHuffman(component.huffmanTableDC); - var diff = t === 0 ? 0 : (receiveAndExtend(t) << successive); - component.blockData[offset] = (component.pred += diff); - } - - function decodeDCSuccessive(component, offset) { - component.blockData[offset] |= readBit() << successive; - } - - var eobrun = 0; - function decodeACFirst(component, offset) { - if (eobrun > 0) { - eobrun--; - return; - } - var k = spectralStart, e = spectralEnd; - while (k <= e) { - var rs = decodeHuffman(component.huffmanTableAC); - var s = rs & 15, r = rs >> 4; - if (s === 0) { - if (r < 15) { - eobrun = receive(r) + (1 << r) - 1; - break; - } - k += 16; - continue; - } - k += r; - var z = dctZigZag[k]; - component.blockData[offset + z] = - receiveAndExtend(s) * (1 << successive); - k++; - } - } - - var successiveACState = 0, successiveACNextValue; - function decodeACSuccessive(component, offset) { - var k = spectralStart; - var e = spectralEnd; - var r = 0; - var s; - var rs; - while (k <= e) { - var z = dctZigZag[k]; - switch (successiveACState) { - case 0: // initial state - rs = decodeHuffman(component.huffmanTableAC); - s = rs & 15; - r = rs >> 4; - if (s === 0) { - if (r < 15) { - eobrun = receive(r) + (1 << r); - successiveACState = 4; - } else { - r = 16; - successiveACState = 1; - } - } else { - if (s !== 1) { - throw 'invalid ACn encoding'; - } - successiveACNextValue = receiveAndExtend(s); - successiveACState = r ? 2 : 3; - } - continue; - case 1: // skipping r zero items - case 2: - if (component.blockData[offset + z]) { - component.blockData[offset + z] += (readBit() << successive); - } else { - r--; - if (r === 0) { - successiveACState = successiveACState === 2 ? 3 : 0; - } - } - break; - case 3: // set value for a zero item - if (component.blockData[offset + z]) { - component.blockData[offset + z] += (readBit() << successive); - } else { - component.blockData[offset + z] = - successiveACNextValue << successive; - successiveACState = 0; - } - break; - case 4: // eob - if (component.blockData[offset + z]) { - component.blockData[offset + z] += (readBit() << successive); - } - break; - } - k++; - } - if (successiveACState === 4) { - eobrun--; - if (eobrun === 0) { - successiveACState = 0; - } - } - } - - function decodeMcu(component, decode, mcu, row, col) { - var mcuRow = (mcu / mcusPerLine) | 0; - var mcuCol = mcu % mcusPerLine; - var blockRow = mcuRow * component.v + row; - var blockCol = mcuCol * component.h + col; - var offset = getBlockBufferOffset(component, blockRow, blockCol); - decode(component, offset); - } - - function decodeBlock(component, decode, mcu) { - var blockRow = (mcu / component.blocksPerLine) | 0; - var blockCol = mcu % component.blocksPerLine; - var offset = getBlockBufferOffset(component, blockRow, blockCol); - decode(component, offset); - } - - var componentsLength = components.length; - var component, i, j, k, n; - var decodeFn; - if (progressive) { - if (spectralStart === 0) { - decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive; - } else { - decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive; - } - } else { - decodeFn = decodeBaseline; - } - - var mcu = 0, marker; - var mcuExpected; - if (componentsLength === 1) { - mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn; - } else { - mcuExpected = mcusPerLine * frame.mcusPerColumn; - } - if (!resetInterval) { - resetInterval = mcuExpected; - } - - var h, v; - while (mcu < mcuExpected) { - // reset interval stuff - for (i = 0; i < componentsLength; i++) { - components[i].pred = 0; - } - eobrun = 0; - - if (componentsLength === 1) { - component = components[0]; - for (n = 0; n < resetInterval; n++) { - decodeBlock(component, decodeFn, mcu); - mcu++; - } - } else { - for (n = 0; n < resetInterval; n++) { - for (i = 0; i < componentsLength; i++) { - component = components[i]; - h = component.h; - v = component.v; - for (j = 0; j < v; j++) { - for (k = 0; k < h; k++) { - decodeMcu(component, decodeFn, mcu, j, k); - } - } - } - mcu++; - } - } - - // find marker - bitsCount = 0; - marker = (data[offset] << 8) | data[offset + 1]; - if (marker <= 0xFF00) { - throw 'marker was not found'; - } - - if (marker >= 0xFFD0 && marker <= 0xFFD7) { // RSTx - offset += 2; - } else { - break; - } - } - - return offset - startOffset; - } - - // A port of poppler's IDCT method which in turn is taken from: - // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, - // 'Practical Fast 1-D DCT Algorithms with 11 Multiplications', - // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, - // 988-991. - function quantizeAndInverse(component, blockBufferOffset, p) { - var qt = component.quantizationTable, blockData = component.blockData; - var v0, v1, v2, v3, v4, v5, v6, v7; - var p0, p1, p2, p3, p4, p5, p6, p7; - var t; - - // inverse DCT on rows - for (var row = 0; row < 64; row += 8) { - // gather block data - p0 = blockData[blockBufferOffset + row]; - p1 = blockData[blockBufferOffset + row + 1]; - p2 = blockData[blockBufferOffset + row + 2]; - p3 = blockData[blockBufferOffset + row + 3]; - p4 = blockData[blockBufferOffset + row + 4]; - p5 = blockData[blockBufferOffset + row + 5]; - p6 = blockData[blockBufferOffset + row + 6]; - p7 = blockData[blockBufferOffset + row + 7]; - - // dequant p0 - p0 *= qt[row]; - - // check for all-zero AC coefficients - if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) { - t = (dctSqrt2 * p0 + 512) >> 10; - p[row] = t; - p[row + 1] = t; - p[row + 2] = t; - p[row + 3] = t; - p[row + 4] = t; - p[row + 5] = t; - p[row + 6] = t; - p[row + 7] = t; - continue; - } - // dequant p1 ... p7 - p1 *= qt[row + 1]; - p2 *= qt[row + 2]; - p3 *= qt[row + 3]; - p4 *= qt[row + 4]; - p5 *= qt[row + 5]; - p6 *= qt[row + 6]; - p7 *= qt[row + 7]; - - // stage 4 - v0 = (dctSqrt2 * p0 + 128) >> 8; - v1 = (dctSqrt2 * p4 + 128) >> 8; - v2 = p2; - v3 = p6; - v4 = (dctSqrt1d2 * (p1 - p7) + 128) >> 8; - v7 = (dctSqrt1d2 * (p1 + p7) + 128) >> 8; - v5 = p3 << 4; - v6 = p5 << 4; - - // stage 3 - v0 = (v0 + v1 + 1) >> 1; - v1 = v0 - v1; - t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8; - v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8; - v3 = t; - v4 = (v4 + v6 + 1) >> 1; - v6 = v4 - v6; - v7 = (v7 + v5 + 1) >> 1; - v5 = v7 - v5; - - // stage 2 - v0 = (v0 + v3 + 1) >> 1; - v3 = v0 - v3; - v1 = (v1 + v2 + 1) >> 1; - v2 = v1 - v2; - t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12; - v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12; - v7 = t; - t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12; - v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12; - v6 = t; - - // stage 1 - p[row] = v0 + v7; - p[row + 7] = v0 - v7; - p[row + 1] = v1 + v6; - p[row + 6] = v1 - v6; - p[row + 2] = v2 + v5; - p[row + 5] = v2 - v5; - p[row + 3] = v3 + v4; - p[row + 4] = v3 - v4; - } - - // inverse DCT on columns - for (var col = 0; col < 8; ++col) { - p0 = p[col]; - p1 = p[col + 8]; - p2 = p[col + 16]; - p3 = p[col + 24]; - p4 = p[col + 32]; - p5 = p[col + 40]; - p6 = p[col + 48]; - p7 = p[col + 56]; - - // check for all-zero AC coefficients - if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) { - t = (dctSqrt2 * p0 + 8192) >> 14; - // convert to 8 bit - t = (t < -2040) ? 0 : (t >= 2024) ? 255 : (t + 2056) >> 4; - blockData[blockBufferOffset + col] = t; - blockData[blockBufferOffset + col + 8] = t; - blockData[blockBufferOffset + col + 16] = t; - blockData[blockBufferOffset + col + 24] = t; - blockData[blockBufferOffset + col + 32] = t; - blockData[blockBufferOffset + col + 40] = t; - blockData[blockBufferOffset + col + 48] = t; - blockData[blockBufferOffset + col + 56] = t; - continue; - } - - // stage 4 - v0 = (dctSqrt2 * p0 + 2048) >> 12; - v1 = (dctSqrt2 * p4 + 2048) >> 12; - v2 = p2; - v3 = p6; - v4 = (dctSqrt1d2 * (p1 - p7) + 2048) >> 12; - v7 = (dctSqrt1d2 * (p1 + p7) + 2048) >> 12; - v5 = p3; - v6 = p5; - - // stage 3 - // Shift v0 by 128.5 << 5 here, so we don't need to shift p0...p7 when - // converting to UInt8 range later. - v0 = ((v0 + v1 + 1) >> 1) + 4112; - v1 = v0 - v1; - t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12; - v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12; - v3 = t; - v4 = (v4 + v6 + 1) >> 1; - v6 = v4 - v6; - v7 = (v7 + v5 + 1) >> 1; - v5 = v7 - v5; - - // stage 2 - v0 = (v0 + v3 + 1) >> 1; - v3 = v0 - v3; - v1 = (v1 + v2 + 1) >> 1; - v2 = v1 - v2; - t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12; - v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12; - v7 = t; - t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12; - v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12; - v6 = t; - - // stage 1 - p0 = v0 + v7; - p7 = v0 - v7; - p1 = v1 + v6; - p6 = v1 - v6; - p2 = v2 + v5; - p5 = v2 - v5; - p3 = v3 + v4; - p4 = v3 - v4; - - // convert to 8-bit integers - p0 = (p0 < 16) ? 0 : (p0 >= 4080) ? 255 : p0 >> 4; - p1 = (p1 < 16) ? 0 : (p1 >= 4080) ? 255 : p1 >> 4; - p2 = (p2 < 16) ? 0 : (p2 >= 4080) ? 255 : p2 >> 4; - p3 = (p3 < 16) ? 0 : (p3 >= 4080) ? 255 : p3 >> 4; - p4 = (p4 < 16) ? 0 : (p4 >= 4080) ? 255 : p4 >> 4; - p5 = (p5 < 16) ? 0 : (p5 >= 4080) ? 255 : p5 >> 4; - p6 = (p6 < 16) ? 0 : (p6 >= 4080) ? 255 : p6 >> 4; - p7 = (p7 < 16) ? 0 : (p7 >= 4080) ? 255 : p7 >> 4; - - // store block data - blockData[blockBufferOffset + col] = p0; - blockData[blockBufferOffset + col + 8] = p1; - blockData[blockBufferOffset + col + 16] = p2; - blockData[blockBufferOffset + col + 24] = p3; - blockData[blockBufferOffset + col + 32] = p4; - blockData[blockBufferOffset + col + 40] = p5; - blockData[blockBufferOffset + col + 48] = p6; - blockData[blockBufferOffset + col + 56] = p7; - } - } - - function buildComponentData(frame, component) { - var blocksPerLine = component.blocksPerLine; - var blocksPerColumn = component.blocksPerColumn; - var computationBuffer = new Int16Array(64); - - for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) { - for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) { - var offset = getBlockBufferOffset(component, blockRow, blockCol); - quantizeAndInverse(component, offset, computationBuffer); - } - } - return component.blockData; - } - - function clamp0to255(a) { - return a <= 0 ? 0 : a >= 255 ? 255 : a; - } - - constructor.prototype = { - parse: function parse(data) { - - function readUint16() { - var value = (data[offset] << 8) | data[offset + 1]; - offset += 2; - return value; - } - - function readDataBlock() { - var length = readUint16(); - var array = data.subarray(offset, offset + length - 2); - offset += array.length; - return array; - } - - function prepareComponents(frame) { - var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH); - var mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV); - for (var i = 0; i < frame.components.length; i++) { - component = frame.components[i]; - var blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * - component.h / frame.maxH); - var blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * - component.v / frame.maxV); - var blocksPerLineForMcu = mcusPerLine * component.h; - var blocksPerColumnForMcu = mcusPerColumn * component.v; - - var blocksBufferSize = 64 * blocksPerColumnForMcu * - (blocksPerLineForMcu + 1); - component.blockData = new Int16Array(blocksBufferSize); - component.blocksPerLine = blocksPerLine; - component.blocksPerColumn = blocksPerColumn; - } - frame.mcusPerLine = mcusPerLine; - frame.mcusPerColumn = mcusPerColumn; - } - - var offset = 0, length = data.length; - var jfif = null; - var adobe = null; - var pixels = null; - var frame, resetInterval; - var quantizationTables = []; - var huffmanTablesAC = [], huffmanTablesDC = []; - var fileMarker = readUint16(); - if (fileMarker !== 0xFFD8) { // SOI (Start of Image) - throw 'SOI not found'; - } - - fileMarker = readUint16(); - while (fileMarker !== 0xFFD9) { // EOI (End of image) - var i, j, l; - switch(fileMarker) { - case 0xFFE0: // APP0 (Application Specific) - case 0xFFE1: // APP1 - case 0xFFE2: // APP2 - case 0xFFE3: // APP3 - case 0xFFE4: // APP4 - case 0xFFE5: // APP5 - case 0xFFE6: // APP6 - case 0xFFE7: // APP7 - case 0xFFE8: // APP8 - case 0xFFE9: // APP9 - case 0xFFEA: // APP10 - case 0xFFEB: // APP11 - case 0xFFEC: // APP12 - case 0xFFED: // APP13 - case 0xFFEE: // APP14 - case 0xFFEF: // APP15 - case 0xFFFE: // COM (Comment) - var appData = readDataBlock(); - - if (fileMarker === 0xFFE0) { - if (appData[0] === 0x4A && appData[1] === 0x46 && - appData[2] === 0x49 && appData[3] === 0x46 && - appData[4] === 0) { // 'JFIF\x00' - jfif = { - version: { major: appData[5], minor: appData[6] }, - densityUnits: appData[7], - xDensity: (appData[8] << 8) | appData[9], - yDensity: (appData[10] << 8) | appData[11], - thumbWidth: appData[12], - thumbHeight: appData[13], - thumbData: appData.subarray(14, 14 + - 3 * appData[12] * appData[13]) - }; - } - } - // TODO APP1 - Exif - if (fileMarker === 0xFFEE) { - if (appData[0] === 0x41 && appData[1] === 0x64 && - appData[2] === 0x6F && appData[3] === 0x62 && - appData[4] === 0x65) { // 'Adobe' - adobe = { - version: (appData[5] << 8) | appData[6], - flags0: (appData[7] << 8) | appData[8], - flags1: (appData[9] << 8) | appData[10], - transformCode: appData[11] - }; - } - } - break; - - case 0xFFDB: // DQT (Define Quantization Tables) - var quantizationTablesLength = readUint16(); - var quantizationTablesEnd = quantizationTablesLength + offset - 2; - var z; - while (offset < quantizationTablesEnd) { - var quantizationTableSpec = data[offset++]; - var tableData = new Uint16Array(64); - if ((quantizationTableSpec >> 4) === 0) { // 8 bit values - for (j = 0; j < 64; j++) { - z = dctZigZag[j]; - tableData[z] = data[offset++]; - } - } else if ((quantizationTableSpec >> 4) === 1) { //16 bit - for (j = 0; j < 64; j++) { - z = dctZigZag[j]; - tableData[z] = readUint16(); - } - } else { - throw 'DQT: invalid table spec'; - } - quantizationTables[quantizationTableSpec & 15] = tableData; - } - break; - - case 0xFFC0: // SOF0 (Start of Frame, Baseline DCT) - case 0xFFC1: // SOF1 (Start of Frame, Extended DCT) - case 0xFFC2: // SOF2 (Start of Frame, Progressive DCT) - if (frame) { - throw 'Only single frame JPEGs supported'; - } - readUint16(); // skip data length - frame = {}; - frame.extended = (fileMarker === 0xFFC1); - frame.progressive = (fileMarker === 0xFFC2); - frame.precision = data[offset++]; - frame.scanLines = readUint16(); - frame.samplesPerLine = readUint16(); - frame.components = []; - frame.componentIds = {}; - var componentsCount = data[offset++], componentId; - var maxH = 0, maxV = 0; - for (i = 0; i < componentsCount; i++) { - componentId = data[offset]; - var h = data[offset + 1] >> 4; - var v = data[offset + 1] & 15; - if (maxH < h) { - maxH = h; - } - if (maxV < v) { - maxV = v; - } - var qId = data[offset + 2]; - l = frame.components.push({ - h: h, - v: v, - quantizationTable: quantizationTables[qId] - }); - frame.componentIds[componentId] = l - 1; - offset += 3; - } - frame.maxH = maxH; - frame.maxV = maxV; - prepareComponents(frame); - break; - - case 0xFFC4: // DHT (Define Huffman Tables) - var huffmanLength = readUint16(); - for (i = 2; i < huffmanLength;) { - var huffmanTableSpec = data[offset++]; - var codeLengths = new Uint8Array(16); - var codeLengthSum = 0; - for (j = 0; j < 16; j++, offset++) { - codeLengthSum += (codeLengths[j] = data[offset]); - } - var huffmanValues = new Uint8Array(codeLengthSum); - for (j = 0; j < codeLengthSum; j++, offset++) { - huffmanValues[j] = data[offset]; - } - i += 17 + codeLengthSum; - - ((huffmanTableSpec >> 4) === 0 ? - huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = - buildHuffmanTable(codeLengths, huffmanValues); - } - break; - - case 0xFFDD: // DRI (Define Restart Interval) - readUint16(); // skip data length - resetInterval = readUint16(); - break; - - case 0xFFDA: // SOS (Start of Scan) - var scanLength = readUint16(); - var selectorsCount = data[offset++]; - var components = [], component; - for (i = 0; i < selectorsCount; i++) { - var componentIndex = frame.componentIds[data[offset++]]; - component = frame.components[componentIndex]; - var tableSpec = data[offset++]; - component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4]; - component.huffmanTableAC = huffmanTablesAC[tableSpec & 15]; - components.push(component); - } - var spectralStart = data[offset++]; - var spectralEnd = data[offset++]; - var successiveApproximation = data[offset++]; - var processed = decodeScan(data, offset, - frame, components, resetInterval, - spectralStart, spectralEnd, - successiveApproximation >> 4, successiveApproximation & 15); - offset += processed; - break; - - case 0xFFFF: // Fill bytes - if (data[offset] !== 0xFF) { // Avoid skipping a valid marker. - offset--; - } - break; - - default: - if (data[offset - 3] === 0xFF && - data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) { - // could be incorrect encoding -- last 0xFF byte of the previous - // block was eaten by the encoder - offset -= 3; - break; - } - throw 'unknown JPEG marker ' + fileMarker.toString(16); - } - fileMarker = readUint16(); - } - - this.width = frame.samplesPerLine; - this.height = frame.scanLines; - this.jfif = jfif; - this.adobe = adobe; - this.components = []; - for (i = 0; i < frame.components.length; i++) { - component = frame.components[i]; - this.components.push({ - output: buildComponentData(frame, component), - scaleX: component.h / frame.maxH, - scaleY: component.v / frame.maxV, - blocksPerLine: component.blocksPerLine, - blocksPerColumn: component.blocksPerColumn - }); - } - this.numComponents = this.components.length; - }, - - _getLinearizedBlockData: function getLinearizedBlockData(width, height) { - var scaleX = this.width / width, scaleY = this.height / height; - - var component, componentScaleX, componentScaleY, blocksPerScanline; - var x, y, i, j, k; - var index; - var offset = 0; - var output; - var numComponents = this.components.length; - var dataLength = width * height * numComponents; - var data = new Uint8Array(dataLength); - var xScaleBlockOffset = new Uint32Array(width); - var mask3LSB = 0xfffffff8; // used to clear the 3 LSBs - - for (i = 0; i < numComponents; i++) { - component = this.components[i]; - componentScaleX = component.scaleX * scaleX; - componentScaleY = component.scaleY * scaleY; - offset = i; - output = component.output; - blocksPerScanline = (component.blocksPerLine + 1) << 3; - // precalculate the xScaleBlockOffset - for (x = 0; x < width; x++) { - j = 0 | (x * componentScaleX); - xScaleBlockOffset[x] = ((j & mask3LSB) << 3) | (j & 7); - } - // linearize the blocks of the component - for (y = 0; y < height; y++) { - j = 0 | (y * componentScaleY); - index = blocksPerScanline * (j & mask3LSB) | ((j & 7) << 3); - for (x = 0; x < width; x++) { - data[offset] = output[index + xScaleBlockOffset[x]]; - offset += numComponents; - } - } - } - - // decodeTransform contains pairs of multiplier (-256..256) and additive - var transform = this.decodeTransform; - if (transform) { - for (i = 0; i < dataLength;) { - for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) { - data[i] = ((data[i] * transform[k]) >> 8) + transform[k + 1]; - } - } - } - return data; - }, - - _isColorConversionNeeded: function isColorConversionNeeded() { - if (this.adobe && this.adobe.transformCode) { - // The adobe transform marker overrides any previous setting - return true; - } else if (this.numComponents === 3) { - return true; - } else { - return false; - } - }, - - _convertYccToRgb: function convertYccToRgb(data) { - var Y, Cb, Cr; - for (var i = 0, length = data.length; i < length; i += 3) { - Y = data[i ]; - Cb = data[i + 1]; - Cr = data[i + 2]; - data[i ] = clamp0to255(Y - 179.456 + 1.402 * Cr); - data[i + 1] = clamp0to255(Y + 135.459 - 0.344 * Cb - 0.714 * Cr); - data[i + 2] = clamp0to255(Y - 226.816 + 1.772 * Cb); - } - return data; - }, - - _convertYcckToRgb: function convertYcckToRgb(data) { - var Y, Cb, Cr, k; - var offset = 0; - for (var i = 0, length = data.length; i < length; i += 4) { - Y = data[i]; - Cb = data[i + 1]; - Cr = data[i + 2]; - k = data[i + 3]; - - var r = -122.67195406894 + - Cb * (-6.60635669420364e-5 * Cb + 0.000437130475926232 * Cr - - 5.4080610064599e-5 * Y + 0.00048449797120281 * k - - 0.154362151871126) + - Cr * (-0.000957964378445773 * Cr + 0.000817076911346625 * Y - - 0.00477271405408747 * k + 1.53380253221734) + - Y * (0.000961250184130688 * Y - 0.00266257332283933 * k + - 0.48357088451265) + - k * (-0.000336197177618394 * k + 0.484791561490776); - - var g = 107.268039397724 + - Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + - 0.000659397001245577 * Y + 0.000426105652938837 * k - - 0.176491792462875) + - Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + - 0.000770482631801132 * k - 0.151051492775562) + - Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + - 0.25802910206845) + - k * (-0.000318913117588328 * k - 0.213742400323665); - - var b = -20.810012546947 + - Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + - 0.0020741088115012 * Y - 0.00288260236853442 * k + - 0.814272968359295) + - Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + - 0.000560833691242812 * k - 0.195152027534049) + - Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + - 0.116935020465145) + - k * (-0.000343531996510555 * k + 0.24165260232407); - - data[offset++] = clamp0to255(r); - data[offset++] = clamp0to255(g); - data[offset++] = clamp0to255(b); - } - return data; - }, - - _convertYcckToCmyk: function convertYcckToCmyk(data) { - var Y, Cb, Cr; - for (var i = 0, length = data.length; i < length; i += 4) { - Y = data[i]; - Cb = data[i + 1]; - Cr = data[i + 2]; - data[i ] = clamp0to255(434.456 - Y - 1.402 * Cr); - data[i + 1] = clamp0to255(119.541 - Y + 0.344 * Cb + 0.714 * Cr); - data[i + 2] = clamp0to255(481.816 - Y - 1.772 * Cb); - // K in data[i + 3] is unchanged - } - return data; - }, - - _convertCmykToRgb: function convertCmykToRgb(data) { - var c, m, y, k; - var offset = 0; - var min = -255 * 255 * 255; - var scale = 1 / 255 / 255; - for (var i = 0, length = data.length; i < length; i += 4) { - c = data[i]; - m = data[i + 1]; - y = data[i + 2]; - k = data[i + 3]; - - var r = - c * (-4.387332384609988 * c + 54.48615194189176 * m + - 18.82290502165302 * y + 212.25662451639585 * k - - 72734.4411664936) + - m * (1.7149763477362134 * m - 5.6096736904047315 * y - - 17.873870861415444 * k - 1401.7366389350734) + - y * (-2.5217340131683033 * y - 21.248923337353073 * k + - 4465.541406466231) - - k * (21.86122147463605 * k + 48317.86113160301); - var g = - c * (8.841041422036149 * c + 60.118027045597366 * m + - 6.871425592049007 * y + 31.159100130055922 * k - - 20220.756542821975) + - m * (-15.310361306967817 * m + 17.575251261109482 * y + - 131.35250912493976 * k - 48691.05921601825) + - y * (4.444339102852739 * y + 9.8632861493405 * k - - 6341.191035517494) - - k * (20.737325471181034 * k + 47890.15695978492); - var b = - c * (0.8842522430003296 * c + 8.078677503112928 * m + - 30.89978309703729 * y - 0.23883238689178934 * k - - 3616.812083916688) + - m * (10.49593273432072 * m + 63.02378494754052 * y + - 50.606957656360734 * k - 28620.90484698408) + - y * (0.03296041114873217 * y + 115.60384449646641 * k - - 49363.43385999684) - - k * (22.33816807309886 * k + 45932.16563550634); - - data[offset++] = r >= 0 ? 255 : r <= min ? 0 : 255 + r * scale | 0; - data[offset++] = g >= 0 ? 255 : g <= min ? 0 : 255 + g * scale | 0; - data[offset++] = b >= 0 ? 255 : b <= min ? 0 : 255 + b * scale | 0; - } - return data; - }, - - getData: function getData(width, height, forceRGBoutput) { - if (this.numComponents > 4) { - throw 'Unsupported color mode'; - } - // type of data: Uint8Array(width * height * numComponents) - var data = this._getLinearizedBlockData(width, height); - - if (this.numComponents === 3) { - return this._convertYccToRgb(data); - } else if (this.numComponents === 4) { - if (this._isColorConversionNeeded()) { - if (forceRGBoutput) { - return this._convertYcckToRgb(data); - } else { - return this._convertYcckToCmyk(data); - } - } else if (forceRGBoutput) { - return this._convertCmykToRgb(data); - } - } - return data; - } - }; - - return constructor; -})(); - - -var JpxImage = (function JpxImageClosure() { - // Table E.1 - var SubbandsGainLog2 = { - 'LL': 0, - 'LH': 1, - 'HL': 1, - 'HH': 2 - }; - function JpxImage() { - this.failOnCorruptedImage = false; - } - JpxImage.prototype = { - parse: function JpxImage_parse(data) { - - var head = readUint16(data, 0); - // No box header, immediate start of codestream (SOC) - if (head === 0xFF4F) { - this.parseCodestream(data, 0, data.length); - return; - } - - var position = 0, length = data.length; - while (position < length) { - var headerSize = 8; - var lbox = readUint32(data, position); - var tbox = readUint32(data, position + 4); - position += headerSize; - if (lbox === 1) { - // XLBox: read UInt64 according to spec. - // JavaScript's int precision of 53 bit should be sufficient here. - lbox = readUint32(data, position) * 4294967296 + - readUint32(data, position + 4); - position += 8; - headerSize += 8; - } - if (lbox === 0) { - lbox = length - position + headerSize; - } - if (lbox < headerSize) { - throw new Error('JPX Error: Invalid box field size'); - } - var dataLength = lbox - headerSize; - var jumpDataLength = true; - switch (tbox) { - case 0x6A703268: // 'jp2h' - jumpDataLength = false; // parsing child boxes - break; - case 0x636F6C72: // 'colr' - // Colorspaces are not used, the CS from the PDF is used. - var method = data[position]; - var precedence = data[position + 1]; - var approximation = data[position + 2]; - if (method === 1) { - // enumerated colorspace - var colorspace = readUint32(data, position + 3); - switch (colorspace) { - case 16: // this indicates a sRGB colorspace - case 17: // this indicates a grayscale colorspace - case 18: // this indicates a YUV colorspace - break; - default: - warn('Unknown colorspace ' + colorspace); - break; - } - } else if (method === 2) { - info('ICC profile not supported'); - } - break; - case 0x6A703263: // 'jp2c' - this.parseCodestream(data, position, position + dataLength); - break; - case 0x6A502020: // 'jP\024\024' - if (0x0d0a870a !== readUint32(data, position)) { - warn('Invalid JP2 signature'); - } - break; - // The following header types are valid but currently not used: - case 0x6A501A1A: // 'jP\032\032' - case 0x66747970: // 'ftyp' - case 0x72726571: // 'rreq' - case 0x72657320: // 'res ' - case 0x69686472: // 'ihdr' - break; - default: - var headerType = String.fromCharCode((tbox >> 24) & 0xFF, - (tbox >> 16) & 0xFF, - (tbox >> 8) & 0xFF, - tbox & 0xFF); - warn('Unsupported header type ' + tbox + ' (' + headerType + ')'); - break; - } - if (jumpDataLength) { - position += dataLength; - } - } - }, - parseImageProperties: function JpxImage_parseImageProperties(stream) { - var newByte = stream.getByte(); - while (newByte >= 0) { - var oldByte = newByte; - newByte = stream.getByte(); - var code = (oldByte << 8) | newByte; - // Image and tile size (SIZ) - if (code === 0xFF51) { - stream.skip(4); - var Xsiz = stream.getInt32() >>> 0; // Byte 4 - var Ysiz = stream.getInt32() >>> 0; // Byte 8 - var XOsiz = stream.getInt32() >>> 0; // Byte 12 - var YOsiz = stream.getInt32() >>> 0; // Byte 16 - stream.skip(16); - var Csiz = stream.getUint16(); // Byte 36 - this.width = Xsiz - XOsiz; - this.height = Ysiz - YOsiz; - this.componentsCount = Csiz; - // Results are always returned as Uint8Arrays - this.bitsPerComponent = 8; - return; - } - } - throw new Error('JPX Error: No size marker found in JPX stream'); - }, - parseCodestream: function JpxImage_parseCodestream(data, start, end) { - var context = {}; - try { - var doNotRecover = false; - var position = start; - while (position + 1 < end) { - var code = readUint16(data, position); - position += 2; - - var length = 0, j, sqcd, spqcds, spqcdSize, scalarExpounded, tile; - switch (code) { - case 0xFF4F: // Start of codestream (SOC) - context.mainHeader = true; - break; - case 0xFFD9: // End of codestream (EOC) - break; - case 0xFF51: // Image and tile size (SIZ) - length = readUint16(data, position); - var siz = {}; - siz.Xsiz = readUint32(data, position + 4); - siz.Ysiz = readUint32(data, position + 8); - siz.XOsiz = readUint32(data, position + 12); - siz.YOsiz = readUint32(data, position + 16); - siz.XTsiz = readUint32(data, position + 20); - siz.YTsiz = readUint32(data, position + 24); - siz.XTOsiz = readUint32(data, position + 28); - siz.YTOsiz = readUint32(data, position + 32); - var componentsCount = readUint16(data, position + 36); - siz.Csiz = componentsCount; - var components = []; - j = position + 38; - for (var i = 0; i < componentsCount; i++) { - var component = { - precision: (data[j] & 0x7F) + 1, - isSigned: !!(data[j] & 0x80), - XRsiz: data[j + 1], - YRsiz: data[j + 1] - }; - calculateComponentDimensions(component, siz); - components.push(component); - } - context.SIZ = siz; - context.components = components; - calculateTileGrids(context, components); - context.QCC = []; - context.COC = []; - break; - case 0xFF5C: // Quantization default (QCD) - length = readUint16(data, position); - var qcd = {}; - j = position + 2; - sqcd = data[j++]; - switch (sqcd & 0x1F) { - case 0: - spqcdSize = 8; - scalarExpounded = true; - break; - case 1: - spqcdSize = 16; - scalarExpounded = false; - break; - case 2: - spqcdSize = 16; - scalarExpounded = true; - break; - default: - throw new Error('JPX Error: Invalid SQcd value ' + sqcd); - } - qcd.noQuantization = (spqcdSize === 8); - qcd.scalarExpounded = scalarExpounded; - qcd.guardBits = sqcd >> 5; - spqcds = []; - while (j < length + position) { - var spqcd = {}; - if (spqcdSize === 8) { - spqcd.epsilon = data[j++] >> 3; - spqcd.mu = 0; - } else { - spqcd.epsilon = data[j] >> 3; - spqcd.mu = ((data[j] & 0x7) << 8) | data[j + 1]; - j += 2; - } - spqcds.push(spqcd); - } - qcd.SPqcds = spqcds; - if (context.mainHeader) { - context.QCD = qcd; - } else { - context.currentTile.QCD = qcd; - context.currentTile.QCC = []; - } - break; - case 0xFF5D: // Quantization component (QCC) - length = readUint16(data, position); - var qcc = {}; - j = position + 2; - var cqcc; - if (context.SIZ.Csiz < 257) { - cqcc = data[j++]; - } else { - cqcc = readUint16(data, j); - j += 2; - } - sqcd = data[j++]; - switch (sqcd & 0x1F) { - case 0: - spqcdSize = 8; - scalarExpounded = true; - break; - case 1: - spqcdSize = 16; - scalarExpounded = false; - break; - case 2: - spqcdSize = 16; - scalarExpounded = true; - break; - default: - throw new Error('JPX Error: Invalid SQcd value ' + sqcd); - } - qcc.noQuantization = (spqcdSize === 8); - qcc.scalarExpounded = scalarExpounded; - qcc.guardBits = sqcd >> 5; - spqcds = []; - while (j < (length + position)) { - spqcd = {}; - if (spqcdSize === 8) { - spqcd.epsilon = data[j++] >> 3; - spqcd.mu = 0; - } else { - spqcd.epsilon = data[j] >> 3; - spqcd.mu = ((data[j] & 0x7) << 8) | data[j + 1]; - j += 2; - } - spqcds.push(spqcd); - } - qcc.SPqcds = spqcds; - if (context.mainHeader) { - context.QCC[cqcc] = qcc; - } else { - context.currentTile.QCC[cqcc] = qcc; - } - break; - case 0xFF52: // Coding style default (COD) - length = readUint16(data, position); - var cod = {}; - j = position + 2; - var scod = data[j++]; - cod.entropyCoderWithCustomPrecincts = !!(scod & 1); - cod.sopMarkerUsed = !!(scod & 2); - cod.ephMarkerUsed = !!(scod & 4); - cod.progressionOrder = data[j++]; - cod.layersCount = readUint16(data, j); - j += 2; - cod.multipleComponentTransform = data[j++]; - - cod.decompositionLevelsCount = data[j++]; - cod.xcb = (data[j++] & 0xF) + 2; - cod.ycb = (data[j++] & 0xF) + 2; - var blockStyle = data[j++]; - cod.selectiveArithmeticCodingBypass = !!(blockStyle & 1); - cod.resetContextProbabilities = !!(blockStyle & 2); - cod.terminationOnEachCodingPass = !!(blockStyle & 4); - cod.verticalyStripe = !!(blockStyle & 8); - cod.predictableTermination = !!(blockStyle & 16); - cod.segmentationSymbolUsed = !!(blockStyle & 32); - cod.reversibleTransformation = data[j++]; - if (cod.entropyCoderWithCustomPrecincts) { - var precinctsSizes = []; - while (j < length + position) { - var precinctsSize = data[j++]; - precinctsSizes.push({ - PPx: precinctsSize & 0xF, - PPy: precinctsSize >> 4 - }); - } - cod.precinctsSizes = precinctsSizes; - } - var unsupported = []; - if (cod.selectiveArithmeticCodingBypass) { - unsupported.push('selectiveArithmeticCodingBypass'); - } - if (cod.resetContextProbabilities) { - unsupported.push('resetContextProbabilities'); - } - if (cod.terminationOnEachCodingPass) { - unsupported.push('terminationOnEachCodingPass'); - } - if (cod.verticalyStripe) { - unsupported.push('verticalyStripe'); - } - if (cod.predictableTermination) { - unsupported.push('predictableTermination'); - } - if (unsupported.length > 0) { - doNotRecover = true; - throw new Error('JPX Error: Unsupported COD options (' + - unsupported.join(', ') + ')'); - } - if (context.mainHeader) { - context.COD = cod; - } else { - context.currentTile.COD = cod; - context.currentTile.COC = []; - } - break; - case 0xFF90: // Start of tile-part (SOT) - length = readUint16(data, position); - tile = {}; - tile.index = readUint16(data, position + 2); - tile.length = readUint32(data, position + 4); - tile.dataEnd = tile.length + position - 2; - tile.partIndex = data[position + 8]; - tile.partsCount = data[position + 9]; - - context.mainHeader = false; - if (tile.partIndex === 0) { - // reset component specific settings - tile.COD = context.COD; - tile.COC = context.COC.slice(0); // clone of the global COC - tile.QCD = context.QCD; - tile.QCC = context.QCC.slice(0); // clone of the global COC - } - context.currentTile = tile; - break; - case 0xFF93: // Start of data (SOD) - tile = context.currentTile; - if (tile.partIndex === 0) { - initializeTile(context, tile.index); - buildPackets(context); - } - - // moving to the end of the data - length = tile.dataEnd - position; - parseTilePackets(context, data, position, length); - break; - case 0xFF55: // Tile-part lengths, main header (TLM) - case 0xFF57: // Packet length, main header (PLM) - case 0xFF58: // Packet length, tile-part header (PLT) - case 0xFF64: // Comment (COM) - length = readUint16(data, position); - // skipping content - break; - case 0xFF53: // Coding style component (COC) - throw new Error('JPX Error: Codestream code 0xFF53 (COC) is ' + - 'not implemented'); - default: - throw new Error('JPX Error: Unknown codestream code: ' + - code.toString(16)); - } - position += length; - } - } catch (e) { - if (doNotRecover || this.failOnCorruptedImage) { - throw e; - } else { - warn('Trying to recover from ' + e.message); - } - } - this.tiles = transformComponents(context); - this.width = context.SIZ.Xsiz - context.SIZ.XOsiz; - this.height = context.SIZ.Ysiz - context.SIZ.YOsiz; - this.componentsCount = context.SIZ.Csiz; - } - }; - function calculateComponentDimensions(component, siz) { - // Section B.2 Component mapping - component.x0 = Math.ceil(siz.XOsiz / component.XRsiz); - component.x1 = Math.ceil(siz.Xsiz / component.XRsiz); - component.y0 = Math.ceil(siz.YOsiz / component.YRsiz); - component.y1 = Math.ceil(siz.Ysiz / component.YRsiz); - component.width = component.x1 - component.x0; - component.height = component.y1 - component.y0; - } - function calculateTileGrids(context, components) { - var siz = context.SIZ; - // Section B.3 Division into tile and tile-components - var tile, tiles = []; - var numXtiles = Math.ceil((siz.Xsiz - siz.XTOsiz) / siz.XTsiz); - var numYtiles = Math.ceil((siz.Ysiz - siz.YTOsiz) / siz.YTsiz); - for (var q = 0; q < numYtiles; q++) { - for (var p = 0; p < numXtiles; p++) { - tile = {}; - tile.tx0 = Math.max(siz.XTOsiz + p * siz.XTsiz, siz.XOsiz); - tile.ty0 = Math.max(siz.YTOsiz + q * siz.YTsiz, siz.YOsiz); - tile.tx1 = Math.min(siz.XTOsiz + (p + 1) * siz.XTsiz, siz.Xsiz); - tile.ty1 = Math.min(siz.YTOsiz + (q + 1) * siz.YTsiz, siz.Ysiz); - tile.width = tile.tx1 - tile.tx0; - tile.height = tile.ty1 - tile.ty0; - tile.components = []; - tiles.push(tile); - } - } - context.tiles = tiles; - - var componentsCount = siz.Csiz; - for (var i = 0, ii = componentsCount; i < ii; i++) { - var component = components[i]; - for (var j = 0, jj = tiles.length; j < jj; j++) { - var tileComponent = {}; - tile = tiles[j]; - tileComponent.tcx0 = Math.ceil(tile.tx0 / component.XRsiz); - tileComponent.tcy0 = Math.ceil(tile.ty0 / component.YRsiz); - tileComponent.tcx1 = Math.ceil(tile.tx1 / component.XRsiz); - tileComponent.tcy1 = Math.ceil(tile.ty1 / component.YRsiz); - tileComponent.width = tileComponent.tcx1 - tileComponent.tcx0; - tileComponent.height = tileComponent.tcy1 - tileComponent.tcy0; - tile.components[i] = tileComponent; - } - } - } - function getBlocksDimensions(context, component, r) { - var codOrCoc = component.codingStyleParameters; - var result = {}; - if (!codOrCoc.entropyCoderWithCustomPrecincts) { - result.PPx = 15; - result.PPy = 15; - } else { - result.PPx = codOrCoc.precinctsSizes[r].PPx; - result.PPy = codOrCoc.precinctsSizes[r].PPy; - } - // calculate codeblock size as described in section B.7 - result.xcb_ = (r > 0 ? Math.min(codOrCoc.xcb, result.PPx - 1) : - Math.min(codOrCoc.xcb, result.PPx)); - result.ycb_ = (r > 0 ? Math.min(codOrCoc.ycb, result.PPy - 1) : - Math.min(codOrCoc.ycb, result.PPy)); - return result; - } - function buildPrecincts(context, resolution, dimensions) { - // Section B.6 Division resolution to precincts - var precinctWidth = 1 << dimensions.PPx; - var precinctHeight = 1 << dimensions.PPy; - // Jasper introduces codeblock groups for mapping each subband codeblocks - // to precincts. Precinct partition divides a resolution according to width - // and height parameters. The subband that belongs to the resolution level - // has a different size than the level, unless it is the zero resolution. - - // From Jasper documentation: jpeg2000.pdf, section K: Tier-2 coding: - // The precinct partitioning for a particular subband is derived from a - // partitioning of its parent LL band (i.e., the LL band at the next higher - // resolution level)... The LL band associated with each resolution level is - // divided into precincts... Each of the resulting precinct regions is then - // mapped into its child subbands (if any) at the next lower resolution - // level. This is accomplished by using the coordinate transformation - // (u, v) = (ceil(x/2), ceil(y/2)) where (x, y) and (u, v) are the - // coordinates of a point in the LL band and child subband, respectively. - var isZeroRes = resolution.resLevel === 0; - var precinctWidthInSubband = 1 << (dimensions.PPx + (isZeroRes ? 0 : -1)); - var precinctHeightInSubband = 1 << (dimensions.PPy + (isZeroRes ? 0 : -1)); - var numprecinctswide = (resolution.trx1 > resolution.trx0 ? - Math.ceil(resolution.trx1 / precinctWidth) - - Math.floor(resolution.trx0 / precinctWidth) : 0); - var numprecinctshigh = (resolution.try1 > resolution.try0 ? - Math.ceil(resolution.try1 / precinctHeight) - - Math.floor(resolution.try0 / precinctHeight) : 0); - var numprecincts = numprecinctswide * numprecinctshigh; - - resolution.precinctParameters = { - precinctWidth: precinctWidth, - precinctHeight: precinctHeight, - numprecinctswide: numprecinctswide, - numprecinctshigh: numprecinctshigh, - numprecincts: numprecincts, - precinctWidthInSubband: precinctWidthInSubband, - precinctHeightInSubband: precinctHeightInSubband - }; - } - function buildCodeblocks(context, subband, dimensions) { - // Section B.7 Division sub-band into code-blocks - var xcb_ = dimensions.xcb_; - var ycb_ = dimensions.ycb_; - var codeblockWidth = 1 << xcb_; - var codeblockHeight = 1 << ycb_; - var cbx0 = subband.tbx0 >> xcb_; - var cby0 = subband.tby0 >> ycb_; - var cbx1 = (subband.tbx1 + codeblockWidth - 1) >> xcb_; - var cby1 = (subband.tby1 + codeblockHeight - 1) >> ycb_; - var precinctParameters = subband.resolution.precinctParameters; - var codeblocks = []; - var precincts = []; - var i, j, codeblock, precinctNumber; - for (j = cby0; j < cby1; j++) { - for (i = cbx0; i < cbx1; i++) { - codeblock = { - cbx: i, - cby: j, - tbx0: codeblockWidth * i, - tby0: codeblockHeight * j, - tbx1: codeblockWidth * (i + 1), - tby1: codeblockHeight * (j + 1) - }; - - codeblock.tbx0_ = Math.max(subband.tbx0, codeblock.tbx0); - codeblock.tby0_ = Math.max(subband.tby0, codeblock.tby0); - codeblock.tbx1_ = Math.min(subband.tbx1, codeblock.tbx1); - codeblock.tby1_ = Math.min(subband.tby1, codeblock.tby1); - - // Calculate precinct number for this codeblock, codeblock position - // should be relative to its subband, use actual dimension and position - // See comment about codeblock group width and height - var pi = Math.floor((codeblock.tbx0_ - subband.tbx0) / - precinctParameters.precinctWidthInSubband); - var pj = Math.floor((codeblock.tby0_ - subband.tby0) / - precinctParameters.precinctHeightInSubband); - precinctNumber = pi + (pj * precinctParameters.numprecinctswide); - - codeblock.precinctNumber = precinctNumber; - codeblock.subbandType = subband.type; - codeblock.Lblock = 3; - - if (codeblock.tbx1_ <= codeblock.tbx0_ || - codeblock.tby1_ <= codeblock.tby0_) { - continue; - } - codeblocks.push(codeblock); - // building precinct for the sub-band - var precinct = precincts[precinctNumber]; - if (precinct !== undefined) { - if (i < precinct.cbxMin) { - precinct.cbxMin = i; - } else if (i > precinct.cbxMax) { - precinct.cbxMax = i; - } - if (j < precinct.cbyMin) { - precinct.cbxMin = j; - } else if (j > precinct.cbyMax) { - precinct.cbyMax = j; - } - } else { - precincts[precinctNumber] = precinct = { - cbxMin: i, - cbyMin: j, - cbxMax: i, - cbyMax: j - }; - } - codeblock.precinct = precinct; - } - } - subband.codeblockParameters = { - codeblockWidth: xcb_, - codeblockHeight: ycb_, - numcodeblockwide: cbx1 - cbx0 + 1, - numcodeblockhigh: cby1 - cby0 + 1 - }; - subband.codeblocks = codeblocks; - subband.precincts = precincts; - } - function createPacket(resolution, precinctNumber, layerNumber) { - var precinctCodeblocks = []; - // Section B.10.8 Order of info in packet - var subbands = resolution.subbands; - // sub-bands already ordered in 'LL', 'HL', 'LH', and 'HH' sequence - for (var i = 0, ii = subbands.length; i < ii; i++) { - var subband = subbands[i]; - var codeblocks = subband.codeblocks; - for (var j = 0, jj = codeblocks.length; j < jj; j++) { - var codeblock = codeblocks[j]; - if (codeblock.precinctNumber !== precinctNumber) { - continue; - } - precinctCodeblocks.push(codeblock); - } - } - return { - layerNumber: layerNumber, - codeblocks: precinctCodeblocks - }; - } - function LayerResolutionComponentPositionIterator(context) { - var siz = context.SIZ; - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var layersCount = tile.codingStyleDefaultParameters.layersCount; - var componentsCount = siz.Csiz; - var maxDecompositionLevelsCount = 0; - for (var q = 0; q < componentsCount; q++) { - maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, - tile.components[q].codingStyleParameters.decompositionLevelsCount); - } - - var l = 0, r = 0, i = 0, k = 0; - - this.nextPacket = function JpxImage_nextPacket() { - // Section B.12.1.1 Layer-resolution-component-position - for (; l < layersCount; l++) { - for (; r <= maxDecompositionLevelsCount; r++) { - for (; i < componentsCount; i++) { - var component = tile.components[i]; - if (r > component.codingStyleParameters.decompositionLevelsCount) { - continue; - } - - var resolution = component.resolutions[r]; - var numprecincts = resolution.precinctParameters.numprecincts; - for (; k < numprecincts;) { - var packet = createPacket(resolution, k, l); - k++; - return packet; - } - k = 0; - } - i = 0; - } - r = 0; - } - throw new Error('JPX Error: Out of packets'); - }; - } - function ResolutionLayerComponentPositionIterator(context) { - var siz = context.SIZ; - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var layersCount = tile.codingStyleDefaultParameters.layersCount; - var componentsCount = siz.Csiz; - var maxDecompositionLevelsCount = 0; - for (var q = 0; q < componentsCount; q++) { - maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, - tile.components[q].codingStyleParameters.decompositionLevelsCount); - } - - var r = 0, l = 0, i = 0, k = 0; - - this.nextPacket = function JpxImage_nextPacket() { - // Section B.12.1.2 Resolution-layer-component-position - for (; r <= maxDecompositionLevelsCount; r++) { - for (; l < layersCount; l++) { - for (; i < componentsCount; i++) { - var component = tile.components[i]; - if (r > component.codingStyleParameters.decompositionLevelsCount) { - continue; - } - - var resolution = component.resolutions[r]; - var numprecincts = resolution.precinctParameters.numprecincts; - for (; k < numprecincts;) { - var packet = createPacket(resolution, k, l); - k++; - return packet; - } - k = 0; - } - i = 0; - } - l = 0; - } - throw new Error('JPX Error: Out of packets'); - }; - } - function ResolutionPositionComponentLayerIterator(context) { - var siz = context.SIZ; - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var layersCount = tile.codingStyleDefaultParameters.layersCount; - var componentsCount = siz.Csiz; - var l, r, c, p; - var maxDecompositionLevelsCount = 0; - for (c = 0; c < componentsCount; c++) { - var component = tile.components[c]; - maxDecompositionLevelsCount = Math.max(maxDecompositionLevelsCount, - component.codingStyleParameters.decompositionLevelsCount); - } - var maxNumPrecinctsInLevel = new Int32Array( - maxDecompositionLevelsCount + 1); - for (r = 0; r <= maxDecompositionLevelsCount; ++r) { - var maxNumPrecincts = 0; - for (c = 0; c < componentsCount; ++c) { - var resolutions = tile.components[c].resolutions; - if (r < resolutions.length) { - maxNumPrecincts = Math.max(maxNumPrecincts, - resolutions[r].precinctParameters.numprecincts); - } - } - maxNumPrecinctsInLevel[r] = maxNumPrecincts; - } - l = 0; - r = 0; - c = 0; - p = 0; - - this.nextPacket = function JpxImage_nextPacket() { - // Section B.12.1.3 Resolution-position-component-layer - for (; r <= maxDecompositionLevelsCount; r++) { - for (; p < maxNumPrecinctsInLevel[r]; p++) { - for (; c < componentsCount; c++) { - var component = tile.components[c]; - if (r > component.codingStyleParameters.decompositionLevelsCount) { - continue; - } - var resolution = component.resolutions[r]; - var numprecincts = resolution.precinctParameters.numprecincts; - if (p >= numprecincts) { - continue; - } - for (; l < layersCount;) { - var packet = createPacket(resolution, p, l); - l++; - return packet; - } - l = 0; - } - c = 0; - } - p = 0; - } - throw new Error('JPX Error: Out of packets'); - }; - } - function PositionComponentResolutionLayerIterator(context) { - var siz = context.SIZ; - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var layersCount = tile.codingStyleDefaultParameters.layersCount; - var componentsCount = siz.Csiz; - var precinctsSizes = getPrecinctSizesInImageScale(tile); - var precinctsIterationSizes = precinctsSizes; - var l = 0, r = 0, c = 0, px = 0, py = 0; - - this.nextPacket = function JpxImage_nextPacket() { - // Section B.12.1.4 Position-component-resolution-layer - for (; py < precinctsIterationSizes.maxNumHigh; py++) { - for (; px < precinctsIterationSizes.maxNumWide; px++) { - for (; c < componentsCount; c++) { - var component = tile.components[c]; - var decompositionLevelsCount = - component.codingStyleParameters.decompositionLevelsCount; - for (; r <= decompositionLevelsCount; r++) { - var resolution = component.resolutions[r]; - var sizeInImageScale = - precinctsSizes.components[c].resolutions[r]; - var k = getPrecinctIndexIfExist( - px, - py, - sizeInImageScale, - precinctsIterationSizes, - resolution); - if (k === null) { - continue; - } - for (; l < layersCount;) { - var packet = createPacket(resolution, k, l); - l++; - return packet; - } - l = 0; - } - r = 0; - } - c = 0; - } - px = 0; - } - throw new Error('JPX Error: Out of packets'); - }; - } - function ComponentPositionResolutionLayerIterator(context) { - var siz = context.SIZ; - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var layersCount = tile.codingStyleDefaultParameters.layersCount; - var componentsCount = siz.Csiz; - var precinctsSizes = getPrecinctSizesInImageScale(tile); - var l = 0, r = 0, c = 0, px = 0, py = 0; - - this.nextPacket = function JpxImage_nextPacket() { - // Section B.12.1.5 Component-position-resolution-layer - for (; c < componentsCount; ++c) { - var component = tile.components[c]; - var precinctsIterationSizes = precinctsSizes.components[c]; - var decompositionLevelsCount = - component.codingStyleParameters.decompositionLevelsCount; - for (; py < precinctsIterationSizes.maxNumHigh; py++) { - for (; px < precinctsIterationSizes.maxNumWide; px++) { - for (; r <= decompositionLevelsCount; r++) { - var resolution = component.resolutions[r]; - var sizeInImageScale = precinctsIterationSizes.resolutions[r]; - var k = getPrecinctIndexIfExist( - px, - py, - sizeInImageScale, - precinctsIterationSizes, - resolution); - if (k === null) { - continue; - } - for (; l < layersCount;) { - var packet = createPacket(resolution, k, l); - l++; - return packet; - } - l = 0; - } - r = 0; - } - px = 0; - } - py = 0; - } - throw new Error('JPX Error: Out of packets'); - }; - } - function getPrecinctIndexIfExist( - pxIndex, pyIndex, sizeInImageScale, precinctIterationSizes, resolution) { - var posX = pxIndex * precinctIterationSizes.minWidth; - var posY = pyIndex * precinctIterationSizes.minHeight; - if (posX % sizeInImageScale.width !== 0 || - posY % sizeInImageScale.height !== 0) { - return null; - } - var startPrecinctRowIndex = - (posY / sizeInImageScale.width) * - resolution.precinctParameters.numprecinctswide; - return (posX / sizeInImageScale.height) + startPrecinctRowIndex; - } - function getPrecinctSizesInImageScale(tile) { - var componentsCount = tile.components.length; - var minWidth = Number.MAX_VALUE; - var minHeight = Number.MAX_VALUE; - var maxNumWide = 0; - var maxNumHigh = 0; - var sizePerComponent = new Array(componentsCount); - for (var c = 0; c < componentsCount; c++) { - var component = tile.components[c]; - var decompositionLevelsCount = - component.codingStyleParameters.decompositionLevelsCount; - var sizePerResolution = new Array(decompositionLevelsCount + 1); - var minWidthCurrentComponent = Number.MAX_VALUE; - var minHeightCurrentComponent = Number.MAX_VALUE; - var maxNumWideCurrentComponent = 0; - var maxNumHighCurrentComponent = 0; - var scale = 1; - for (var r = decompositionLevelsCount; r >= 0; --r) { - var resolution = component.resolutions[r]; - var widthCurrentResolution = - scale * resolution.precinctParameters.precinctWidth; - var heightCurrentResolution = - scale * resolution.precinctParameters.precinctHeight; - minWidthCurrentComponent = Math.min( - minWidthCurrentComponent, - widthCurrentResolution); - minHeightCurrentComponent = Math.min( - minHeightCurrentComponent, - heightCurrentResolution); - maxNumWideCurrentComponent = Math.max(maxNumWideCurrentComponent, - resolution.precinctParameters.numprecinctswide); - maxNumHighCurrentComponent = Math.max(maxNumHighCurrentComponent, - resolution.precinctParameters.numprecinctshigh); - sizePerResolution[r] = { - width: widthCurrentResolution, - height: heightCurrentResolution - }; - scale <<= 1; - } - minWidth = Math.min(minWidth, minWidthCurrentComponent); - minHeight = Math.min(minHeight, minHeightCurrentComponent); - maxNumWide = Math.max(maxNumWide, maxNumWideCurrentComponent); - maxNumHigh = Math.max(maxNumHigh, maxNumHighCurrentComponent); - sizePerComponent[c] = { - resolutions: sizePerResolution, - minWidth: minWidthCurrentComponent, - minHeight: minHeightCurrentComponent, - maxNumWide: maxNumWideCurrentComponent, - maxNumHigh: maxNumHighCurrentComponent - }; - } - return { - components: sizePerComponent, - minWidth: minWidth, - minHeight: minHeight, - maxNumWide: maxNumWide, - maxNumHigh: maxNumHigh - }; - } - function buildPackets(context) { - var siz = context.SIZ; - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var componentsCount = siz.Csiz; - // Creating resolutions and sub-bands for each component - for (var c = 0; c < componentsCount; c++) { - var component = tile.components[c]; - var decompositionLevelsCount = - component.codingStyleParameters.decompositionLevelsCount; - // Section B.5 Resolution levels and sub-bands - var resolutions = []; - var subbands = []; - for (var r = 0; r <= decompositionLevelsCount; r++) { - var blocksDimensions = getBlocksDimensions(context, component, r); - var resolution = {}; - var scale = 1 << (decompositionLevelsCount - r); - resolution.trx0 = Math.ceil(component.tcx0 / scale); - resolution.try0 = Math.ceil(component.tcy0 / scale); - resolution.trx1 = Math.ceil(component.tcx1 / scale); - resolution.try1 = Math.ceil(component.tcy1 / scale); - resolution.resLevel = r; - buildPrecincts(context, resolution, blocksDimensions); - resolutions.push(resolution); - - var subband; - if (r === 0) { - // one sub-band (LL) with last decomposition - subband = {}; - subband.type = 'LL'; - subband.tbx0 = Math.ceil(component.tcx0 / scale); - subband.tby0 = Math.ceil(component.tcy0 / scale); - subband.tbx1 = Math.ceil(component.tcx1 / scale); - subband.tby1 = Math.ceil(component.tcy1 / scale); - subband.resolution = resolution; - buildCodeblocks(context, subband, blocksDimensions); - subbands.push(subband); - resolution.subbands = [subband]; - } else { - var bscale = 1 << (decompositionLevelsCount - r + 1); - var resolutionSubbands = []; - // three sub-bands (HL, LH and HH) with rest of decompositions - subband = {}; - subband.type = 'HL'; - subband.tbx0 = Math.ceil(component.tcx0 / bscale - 0.5); - subband.tby0 = Math.ceil(component.tcy0 / bscale); - subband.tbx1 = Math.ceil(component.tcx1 / bscale - 0.5); - subband.tby1 = Math.ceil(component.tcy1 / bscale); - subband.resolution = resolution; - buildCodeblocks(context, subband, blocksDimensions); - subbands.push(subband); - resolutionSubbands.push(subband); - - subband = {}; - subband.type = 'LH'; - subband.tbx0 = Math.ceil(component.tcx0 / bscale); - subband.tby0 = Math.ceil(component.tcy0 / bscale - 0.5); - subband.tbx1 = Math.ceil(component.tcx1 / bscale); - subband.tby1 = Math.ceil(component.tcy1 / bscale - 0.5); - subband.resolution = resolution; - buildCodeblocks(context, subband, blocksDimensions); - subbands.push(subband); - resolutionSubbands.push(subband); - - subband = {}; - subband.type = 'HH'; - subband.tbx0 = Math.ceil(component.tcx0 / bscale - 0.5); - subband.tby0 = Math.ceil(component.tcy0 / bscale - 0.5); - subband.tbx1 = Math.ceil(component.tcx1 / bscale - 0.5); - subband.tby1 = Math.ceil(component.tcy1 / bscale - 0.5); - subband.resolution = resolution; - buildCodeblocks(context, subband, blocksDimensions); - subbands.push(subband); - resolutionSubbands.push(subband); - - resolution.subbands = resolutionSubbands; - } - } - component.resolutions = resolutions; - component.subbands = subbands; - } - // Generate the packets sequence - var progressionOrder = tile.codingStyleDefaultParameters.progressionOrder; - switch (progressionOrder) { - case 0: - tile.packetsIterator = - new LayerResolutionComponentPositionIterator(context); - break; - case 1: - tile.packetsIterator = - new ResolutionLayerComponentPositionIterator(context); - break; - case 2: - tile.packetsIterator = - new ResolutionPositionComponentLayerIterator(context); - break; - case 3: - tile.packetsIterator = - new PositionComponentResolutionLayerIterator(context); - break; - case 4: - tile.packetsIterator = - new ComponentPositionResolutionLayerIterator(context); - break; - default: - throw new Error('JPX Error: Unsupported progression order ' + - progressionOrder); - } - } - function parseTilePackets(context, data, offset, dataLength) { - var position = 0; - var buffer, bufferSize = 0, skipNextBit = false; - function readBits(count) { - while (bufferSize < count) { - var b = data[offset + position]; - position++; - if (skipNextBit) { - buffer = (buffer << 7) | b; - bufferSize += 7; - skipNextBit = false; - } else { - buffer = (buffer << 8) | b; - bufferSize += 8; - } - if (b === 0xFF) { - skipNextBit = true; - } - } - bufferSize -= count; - return (buffer >>> bufferSize) & ((1 << count) - 1); - } - function skipMarkerIfEqual(value) { - if (data[offset + position - 1] === 0xFF && - data[offset + position] === value) { - skipBytes(1); - return true; - } else if (data[offset + position] === 0xFF && - data[offset + position + 1] === value) { - skipBytes(2); - return true; - } - return false; - } - function skipBytes(count) { - position += count; - } - function alignToByte() { - bufferSize = 0; - if (skipNextBit) { - position++; - skipNextBit = false; - } - } - function readCodingpasses() { - if (readBits(1) === 0) { - return 1; - } - if (readBits(1) === 0) { - return 2; - } - var value = readBits(2); - if (value < 3) { - return value + 3; - } - value = readBits(5); - if (value < 31) { - return value + 6; - } - value = readBits(7); - return value + 37; - } - var tileIndex = context.currentTile.index; - var tile = context.tiles[tileIndex]; - var sopMarkerUsed = context.COD.sopMarkerUsed; - var ephMarkerUsed = context.COD.ephMarkerUsed; - var packetsIterator = tile.packetsIterator; - while (position < dataLength) { - alignToByte(); - if (sopMarkerUsed && skipMarkerIfEqual(0x91)) { - // Skip also marker segment length and packet sequence ID - skipBytes(4); - } - var packet = packetsIterator.nextPacket(); - if (!readBits(1)) { - continue; - } - var layerNumber = packet.layerNumber; - var queue = [], codeblock; - for (var i = 0, ii = packet.codeblocks.length; i < ii; i++) { - codeblock = packet.codeblocks[i]; - var precinct = codeblock.precinct; - var codeblockColumn = codeblock.cbx - precinct.cbxMin; - var codeblockRow = codeblock.cby - precinct.cbyMin; - var codeblockIncluded = false; - var firstTimeInclusion = false; - var valueReady; - if (codeblock['included'] !== undefined) { - codeblockIncluded = !!readBits(1); - } else { - // reading inclusion tree - precinct = codeblock.precinct; - var inclusionTree, zeroBitPlanesTree; - if (precinct['inclusionTree'] !== undefined) { - inclusionTree = precinct.inclusionTree; - } else { - // building inclusion and zero bit-planes trees - var width = precinct.cbxMax - precinct.cbxMin + 1; - var height = precinct.cbyMax - precinct.cbyMin + 1; - inclusionTree = new InclusionTree(width, height, layerNumber); - zeroBitPlanesTree = new TagTree(width, height); - precinct.inclusionTree = inclusionTree; - precinct.zeroBitPlanesTree = zeroBitPlanesTree; - } - - if (inclusionTree.reset(codeblockColumn, codeblockRow, layerNumber)) { - while (true) { - if (readBits(1)) { - valueReady = !inclusionTree.nextLevel(); - if (valueReady) { - codeblock.included = true; - codeblockIncluded = firstTimeInclusion = true; - break; - } - } else { - inclusionTree.incrementValue(layerNumber); - break; - } - } - } - } - if (!codeblockIncluded) { - continue; - } - if (firstTimeInclusion) { - zeroBitPlanesTree = precinct.zeroBitPlanesTree; - zeroBitPlanesTree.reset(codeblockColumn, codeblockRow); - while (true) { - if (readBits(1)) { - valueReady = !zeroBitPlanesTree.nextLevel(); - if (valueReady) { - break; - } - } else { - zeroBitPlanesTree.incrementValue(); - } - } - codeblock.zeroBitPlanes = zeroBitPlanesTree.value; - } - var codingpasses = readCodingpasses(); - while (readBits(1)) { - codeblock.Lblock++; - } - var codingpassesLog2 = log2(codingpasses); - // rounding down log2 - var bits = ((codingpasses < (1 << codingpassesLog2)) ? - codingpassesLog2 - 1 : codingpassesLog2) + codeblock.Lblock; - var codedDataLength = readBits(bits); - queue.push({ - codeblock: codeblock, - codingpasses: codingpasses, - dataLength: codedDataLength - }); - } - alignToByte(); - if (ephMarkerUsed) { - skipMarkerIfEqual(0x92); - } - while (queue.length > 0) { - var packetItem = queue.shift(); - codeblock = packetItem.codeblock; - if (codeblock['data'] === undefined) { - codeblock.data = []; - } - codeblock.data.push({ - data: data, - start: offset + position, - end: offset + position + packetItem.dataLength, - codingpasses: packetItem.codingpasses - }); - position += packetItem.dataLength; - } - } - return position; - } - function copyCoefficients(coefficients, levelWidth, levelHeight, subband, - delta, mb, reversible, segmentationSymbolUsed) { - var x0 = subband.tbx0; - var y0 = subband.tby0; - var width = subband.tbx1 - subband.tbx0; - var codeblocks = subband.codeblocks; - var right = subband.type.charAt(0) === 'H' ? 1 : 0; - var bottom = subband.type.charAt(1) === 'H' ? levelWidth : 0; - - for (var i = 0, ii = codeblocks.length; i < ii; ++i) { - var codeblock = codeblocks[i]; - var blockWidth = codeblock.tbx1_ - codeblock.tbx0_; - var blockHeight = codeblock.tby1_ - codeblock.tby0_; - if (blockWidth === 0 || blockHeight === 0) { - continue; - } - if (codeblock['data'] === undefined) { - continue; - } - - var bitModel, currentCodingpassType; - bitModel = new BitModel(blockWidth, blockHeight, codeblock.subbandType, - codeblock.zeroBitPlanes, mb); - currentCodingpassType = 2; // first bit plane starts from cleanup - - // collect data - var data = codeblock.data, totalLength = 0, codingpasses = 0; - var j, jj, dataItem; - for (j = 0, jj = data.length; j < jj; j++) { - dataItem = data[j]; - totalLength += dataItem.end - dataItem.start; - codingpasses += dataItem.codingpasses; - } - var encodedData = new Uint8Array(totalLength); - var position = 0; - for (j = 0, jj = data.length; j < jj; j++) { - dataItem = data[j]; - var chunk = dataItem.data.subarray(dataItem.start, dataItem.end); - encodedData.set(chunk, position); - position += chunk.length; - } - // decoding the item - var decoder = new ArithmeticDecoder(encodedData, 0, totalLength); - bitModel.setDecoder(decoder); - - for (j = 0; j < codingpasses; j++) { - switch (currentCodingpassType) { - case 0: - bitModel.runSignificancePropogationPass(); - break; - case 1: - bitModel.runMagnitudeRefinementPass(); - break; - case 2: - bitModel.runCleanupPass(); - if (segmentationSymbolUsed) { - bitModel.checkSegmentationSymbol(); - } - break; - } - currentCodingpassType = (currentCodingpassType + 1) % 3; - } - - var offset = (codeblock.tbx0_ - x0) + (codeblock.tby0_ - y0) * width; - var sign = bitModel.coefficentsSign; - var magnitude = bitModel.coefficentsMagnitude; - var bitsDecoded = bitModel.bitsDecoded; - var magnitudeCorrection = reversible ? 0 : 0.5; - var k, n, nb; - position = 0; - // Do the interleaving of Section F.3.3 here, so we do not need - // to copy later. LL level is not interleaved, just copied. - var interleave = (subband.type !== 'LL'); - for (j = 0; j < blockHeight; j++) { - var row = (offset / width) | 0; // row in the non-interleaved subband - var levelOffset = 2 * row * (levelWidth - width) + right + bottom; - for (k = 0; k < blockWidth; k++) { - n = magnitude[position]; - if (n !== 0) { - n = (n + magnitudeCorrection) * delta; - if (sign[position] !== 0) { - n = -n; - } - nb = bitsDecoded[position]; - var pos = interleave ? (levelOffset + (offset << 1)) : offset; - if (reversible && (nb >= mb)) { - coefficients[pos] = n; - } else { - coefficients[pos] = n * (1 << (mb - nb)); - } - } - offset++; - position++; - } - offset += width - blockWidth; - } - } - } - function transformTile(context, tile, c) { - var component = tile.components[c]; - var codingStyleParameters = component.codingStyleParameters; - var quantizationParameters = component.quantizationParameters; - var decompositionLevelsCount = - codingStyleParameters.decompositionLevelsCount; - var spqcds = quantizationParameters.SPqcds; - var scalarExpounded = quantizationParameters.scalarExpounded; - var guardBits = quantizationParameters.guardBits; - var segmentationSymbolUsed = codingStyleParameters.segmentationSymbolUsed; - var precision = context.components[c].precision; - - var reversible = codingStyleParameters.reversibleTransformation; - var transform = (reversible ? new ReversibleTransform() : - new IrreversibleTransform()); - - var subbandCoefficients = []; - var b = 0; - for (var i = 0; i <= decompositionLevelsCount; i++) { - var resolution = component.resolutions[i]; - - var width = resolution.trx1 - resolution.trx0; - var height = resolution.try1 - resolution.try0; - // Allocate space for the whole sublevel. - var coefficients = new Float32Array(width * height); - - for (var j = 0, jj = resolution.subbands.length; j < jj; j++) { - var mu, epsilon; - if (!scalarExpounded) { - // formula E-5 - mu = spqcds[0].mu; - epsilon = spqcds[0].epsilon + (i > 0 ? 1 - i : 0); - } else { - mu = spqcds[b].mu; - epsilon = spqcds[b].epsilon; - b++; - } - - var subband = resolution.subbands[j]; - var gainLog2 = SubbandsGainLog2[subband.type]; - - // calulate quantization coefficient (Section E.1.1.1) - var delta = (reversible ? 1 : - Math.pow(2, precision + gainLog2 - epsilon) * (1 + mu / 2048)); - var mb = (guardBits + epsilon - 1); - - // In the first resolution level, copyCoefficients will fill the - // whole array with coefficients. In the succeding passes, - // copyCoefficients will consecutively fill in the values that belong - // to the interleaved positions of the HL, LH, and HH coefficients. - // The LL coefficients will then be interleaved in Transform.iterate(). - copyCoefficients(coefficients, width, height, subband, delta, mb, - reversible, segmentationSymbolUsed); - } - subbandCoefficients.push({ - width: width, - height: height, - items: coefficients - }); - } - - var result = transform.calculate(subbandCoefficients, - component.tcx0, component.tcy0); - return { - left: component.tcx0, - top: component.tcy0, - width: result.width, - height: result.height, - items: result.items - }; - } - function transformComponents(context) { - var siz = context.SIZ; - var components = context.components; - var componentsCount = siz.Csiz; - var resultImages = []; - for (var i = 0, ii = context.tiles.length; i < ii; i++) { - var tile = context.tiles[i]; - var transformedTiles = []; - var c; - for (c = 0; c < componentsCount; c++) { - transformedTiles[c] = transformTile(context, tile, c); - } - var tile0 = transformedTiles[0]; - var out = new Uint8Array(tile0.items.length * componentsCount); - var result = { - left: tile0.left, - top: tile0.top, - width: tile0.width, - height: tile0.height, - items: out - }; - - // Section G.2.2 Inverse multi component transform - var shift, offset, max, min, maxK; - var pos = 0, j, jj, y0, y1, y2, r, g, b, k, val; - if (tile.codingStyleDefaultParameters.multipleComponentTransform) { - var fourComponents = componentsCount === 4; - var y0items = transformedTiles[0].items; - var y1items = transformedTiles[1].items; - var y2items = transformedTiles[2].items; - var y3items = fourComponents ? transformedTiles[3].items : null; - - // HACK: The multiple component transform formulas below assume that - // all components have the same precision. With this in mind, we - // compute shift and offset only once. - shift = components[0].precision - 8; - offset = (128 << shift) + 0.5; - max = 255 * (1 << shift); - maxK = max * 0.5; - min = -maxK; - - var component0 = tile.components[0]; - var alpha01 = componentsCount - 3; - jj = y0items.length; - if (!component0.codingStyleParameters.reversibleTransformation) { - // inverse irreversible multiple component transform - for (j = 0; j < jj; j++, pos += alpha01) { - y0 = y0items[j] + offset; - y1 = y1items[j]; - y2 = y2items[j]; - r = y0 + 1.402 * y2; - g = y0 - 0.34413 * y1 - 0.71414 * y2; - b = y0 + 1.772 * y1; - out[pos++] = r <= 0 ? 0 : r >= max ? 255 : r >> shift; - out[pos++] = g <= 0 ? 0 : g >= max ? 255 : g >> shift; - out[pos++] = b <= 0 ? 0 : b >= max ? 255 : b >> shift; - } - } else { - // inverse reversible multiple component transform - for (j = 0; j < jj; j++, pos += alpha01) { - y0 = y0items[j] + offset; - y1 = y1items[j]; - y2 = y2items[j]; - g = y0 - ((y2 + y1) >> 2); - r = g + y2; - b = g + y1; - out[pos++] = r <= 0 ? 0 : r >= max ? 255 : r >> shift; - out[pos++] = g <= 0 ? 0 : g >= max ? 255 : g >> shift; - out[pos++] = b <= 0 ? 0 : b >= max ? 255 : b >> shift; - } - } - if (fourComponents) { - for (j = 0, pos = 3; j < jj; j++, pos += 4) { - k = y3items[j]; - out[pos] = k <= min ? 0 : k >= maxK ? 255 : (k + offset) >> shift; - } - } - } else { // no multi-component transform - for (c = 0; c < componentsCount; c++) { - var items = transformedTiles[c].items; - shift = components[c].precision - 8; - offset = (128 << shift) + 0.5; - max = (127.5 * (1 << shift)); - min = -max; - for (pos = c, j = 0, jj = items.length; j < jj; j++) { - val = items[j]; - out[pos] = val <= min ? 0 : - val >= max ? 255 : (val + offset) >> shift; - pos += componentsCount; - } - } - } - resultImages.push(result); - } - return resultImages; - } - function initializeTile(context, tileIndex) { - var siz = context.SIZ; - var componentsCount = siz.Csiz; - var tile = context.tiles[tileIndex]; - for (var c = 0; c < componentsCount; c++) { - var component = tile.components[c]; - var qcdOrQcc = (context.currentTile.QCC[c] !== undefined ? - context.currentTile.QCC[c] : context.currentTile.QCD); - component.quantizationParameters = qcdOrQcc; - var codOrCoc = (context.currentTile.COC[c] !== undefined ? - context.currentTile.COC[c] : context.currentTile.COD); - component.codingStyleParameters = codOrCoc; - } - tile.codingStyleDefaultParameters = context.currentTile.COD; - } - - // Section B.10.2 Tag trees - var TagTree = (function TagTreeClosure() { - function TagTree(width, height) { - var levelsLength = log2(Math.max(width, height)) + 1; - this.levels = []; - for (var i = 0; i < levelsLength; i++) { - var level = { - width: width, - height: height, - items: [] - }; - this.levels.push(level); - width = Math.ceil(width / 2); - height = Math.ceil(height / 2); - } - } - TagTree.prototype = { - reset: function TagTree_reset(i, j) { - var currentLevel = 0, value = 0, level; - while (currentLevel < this.levels.length) { - level = this.levels[currentLevel]; - var index = i + j * level.width; - if (level.items[index] !== undefined) { - value = level.items[index]; - break; - } - level.index = index; - i >>= 1; - j >>= 1; - currentLevel++; - } - currentLevel--; - level = this.levels[currentLevel]; - level.items[level.index] = value; - this.currentLevel = currentLevel; - delete this.value; - }, - incrementValue: function TagTree_incrementValue() { - var level = this.levels[this.currentLevel]; - level.items[level.index]++; - }, - nextLevel: function TagTree_nextLevel() { - var currentLevel = this.currentLevel; - var level = this.levels[currentLevel]; - var value = level.items[level.index]; - currentLevel--; - if (currentLevel < 0) { - this.value = value; - return false; - } - - this.currentLevel = currentLevel; - level = this.levels[currentLevel]; - level.items[level.index] = value; - return true; - } - }; - return TagTree; - })(); - - var InclusionTree = (function InclusionTreeClosure() { - function InclusionTree(width, height, defaultValue) { - var levelsLength = log2(Math.max(width, height)) + 1; - this.levels = []; - for (var i = 0; i < levelsLength; i++) { - var items = new Uint8Array(width * height); - for (var j = 0, jj = items.length; j < jj; j++) { - items[j] = defaultValue; - } - - var level = { - width: width, - height: height, - items: items - }; - this.levels.push(level); - - width = Math.ceil(width / 2); - height = Math.ceil(height / 2); - } - } - InclusionTree.prototype = { - reset: function InclusionTree_reset(i, j, stopValue) { - var currentLevel = 0; - while (currentLevel < this.levels.length) { - var level = this.levels[currentLevel]; - var index = i + j * level.width; - level.index = index; - var value = level.items[index]; - - if (value === 0xFF) { - break; - } - - if (value > stopValue) { - this.currentLevel = currentLevel; - // already know about this one, propagating the value to top levels - this.propagateValues(); - return false; - } - - i >>= 1; - j >>= 1; - currentLevel++; - } - this.currentLevel = currentLevel - 1; - return true; - }, - incrementValue: function InclusionTree_incrementValue(stopValue) { - var level = this.levels[this.currentLevel]; - level.items[level.index] = stopValue + 1; - this.propagateValues(); - }, - propagateValues: function InclusionTree_propagateValues() { - var levelIndex = this.currentLevel; - var level = this.levels[levelIndex]; - var currentValue = level.items[level.index]; - while (--levelIndex >= 0) { - level = this.levels[levelIndex]; - level.items[level.index] = currentValue; - } - }, - nextLevel: function InclusionTree_nextLevel() { - var currentLevel = this.currentLevel; - var level = this.levels[currentLevel]; - var value = level.items[level.index]; - level.items[level.index] = 0xFF; - currentLevel--; - if (currentLevel < 0) { - return false; - } - - this.currentLevel = currentLevel; - level = this.levels[currentLevel]; - level.items[level.index] = value; - return true; - } - }; - return InclusionTree; - })(); - - // Section D. Coefficient bit modeling - var BitModel = (function BitModelClosure() { - var UNIFORM_CONTEXT = 17; - var RUNLENGTH_CONTEXT = 18; - // Table D-1 - // The index is binary presentation: 0dddvvhh, ddd - sum of Di (0..4), - // vv - sum of Vi (0..2), and hh - sum of Hi (0..2) - var LLAndLHContextsLabel = new Uint8Array([ - 0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4, - 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, - 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8 - ]); - var HLContextLabel = new Uint8Array([ - 0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8, - 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, - 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8 - ]); - var HHContextLabel = new Uint8Array([ - 0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5, - 5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8, - 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8 - ]); - - function BitModel(width, height, subband, zeroBitPlanes, mb) { - this.width = width; - this.height = height; - - this.contextLabelTable = (subband === 'HH' ? HHContextLabel : - (subband === 'HL' ? HLContextLabel : LLAndLHContextsLabel)); - - var coefficientCount = width * height; - - // coefficients outside the encoding region treated as insignificant - // add border state cells for significanceState - this.neighborsSignificance = new Uint8Array(coefficientCount); - this.coefficentsSign = new Uint8Array(coefficientCount); - this.coefficentsMagnitude = mb > 14 ? new Uint32Array(coefficientCount) : - mb > 6 ? new Uint16Array(coefficientCount) : - new Uint8Array(coefficientCount); - this.processingFlags = new Uint8Array(coefficientCount); - - var bitsDecoded = new Uint8Array(coefficientCount); - if (zeroBitPlanes !== 0) { - for (var i = 0; i < coefficientCount; i++) { - bitsDecoded[i] = zeroBitPlanes; - } - } - this.bitsDecoded = bitsDecoded; - - this.reset(); - } - - BitModel.prototype = { - setDecoder: function BitModel_setDecoder(decoder) { - this.decoder = decoder; - }, - reset: function BitModel_reset() { - // We have 17 contexts that are accessed via context labels, - // plus the uniform and runlength context. - this.contexts = new Int8Array(19); - - // Contexts are packed into 1 byte: - // highest 7 bits carry the index, lowest bit carries mps - this.contexts[0] = (4 << 1) | 0; - this.contexts[UNIFORM_CONTEXT] = (46 << 1) | 0; - this.contexts[RUNLENGTH_CONTEXT] = (3 << 1) | 0; - }, - setNeighborsSignificance: - function BitModel_setNeighborsSignificance(row, column, index) { - var neighborsSignificance = this.neighborsSignificance; - var width = this.width, height = this.height; - var left = (column > 0); - var right = (column + 1 < width); - var i; - - if (row > 0) { - i = index - width; - if (left) { - neighborsSignificance[i - 1] += 0x10; - } - if (right) { - neighborsSignificance[i + 1] += 0x10; - } - neighborsSignificance[i] += 0x04; - } - - if (row + 1 < height) { - i = index + width; - if (left) { - neighborsSignificance[i - 1] += 0x10; - } - if (right) { - neighborsSignificance[i + 1] += 0x10; - } - neighborsSignificance[i] += 0x04; - } - - if (left) { - neighborsSignificance[index - 1] += 0x01; - } - if (right) { - neighborsSignificance[index + 1] += 0x01; - } - neighborsSignificance[index] |= 0x80; - }, - runSignificancePropogationPass: - function BitModel_runSignificancePropogationPass() { - var decoder = this.decoder; - var width = this.width, height = this.height; - var coefficentsMagnitude = this.coefficentsMagnitude; - var coefficentsSign = this.coefficentsSign; - var neighborsSignificance = this.neighborsSignificance; - var processingFlags = this.processingFlags; - var contexts = this.contexts; - var labels = this.contextLabelTable; - var bitsDecoded = this.bitsDecoded; - var processedInverseMask = ~1; - var processedMask = 1; - var firstMagnitudeBitMask = 2; - - for (var i0 = 0; i0 < height; i0 += 4) { - for (var j = 0; j < width; j++) { - var index = i0 * width + j; - for (var i1 = 0; i1 < 4; i1++, index += width) { - var i = i0 + i1; - if (i >= height) { - break; - } - // clear processed flag first - processingFlags[index] &= processedInverseMask; - - if (coefficentsMagnitude[index] || - !neighborsSignificance[index]) { - continue; - } - - var contextLabel = labels[neighborsSignificance[index]]; - var decision = decoder.readBit(contexts, contextLabel); - if (decision) { - var sign = this.decodeSignBit(i, j, index); - coefficentsSign[index] = sign; - coefficentsMagnitude[index] = 1; - this.setNeighborsSignificance(i, j, index); - processingFlags[index] |= firstMagnitudeBitMask; - } - bitsDecoded[index]++; - processingFlags[index] |= processedMask; - } - } - } - }, - decodeSignBit: function BitModel_decodeSignBit(row, column, index) { - var width = this.width, height = this.height; - var coefficentsMagnitude = this.coefficentsMagnitude; - var coefficentsSign = this.coefficentsSign; - var contribution, sign0, sign1, significance1; - var contextLabel, decoded; - - // calculate horizontal contribution - significance1 = (column > 0 && coefficentsMagnitude[index - 1] !== 0); - if (column + 1 < width && coefficentsMagnitude[index + 1] !== 0) { - sign1 = coefficentsSign[index + 1]; - if (significance1) { - sign0 = coefficentsSign[index - 1]; - contribution = 1 - sign1 - sign0; - } else { - contribution = 1 - sign1 - sign1; - } - } else if (significance1) { - sign0 = coefficentsSign[index - 1]; - contribution = 1 - sign0 - sign0; - } else { - contribution = 0; - } - var horizontalContribution = 3 * contribution; - - // calculate vertical contribution and combine with the horizontal - significance1 = (row > 0 && coefficentsMagnitude[index - width] !== 0); - if (row + 1 < height && coefficentsMagnitude[index + width] !== 0) { - sign1 = coefficentsSign[index + width]; - if (significance1) { - sign0 = coefficentsSign[index - width]; - contribution = 1 - sign1 - sign0 + horizontalContribution; - } else { - contribution = 1 - sign1 - sign1 + horizontalContribution; - } - } else if (significance1) { - sign0 = coefficentsSign[index - width]; - contribution = 1 - sign0 - sign0 + horizontalContribution; - } else { - contribution = horizontalContribution; - } - - if (contribution >= 0) { - contextLabel = 9 + contribution; - decoded = this.decoder.readBit(this.contexts, contextLabel); - } else { - contextLabel = 9 - contribution; - decoded = this.decoder.readBit(this.contexts, contextLabel) ^ 1; - } - return decoded; - }, - runMagnitudeRefinementPass: - function BitModel_runMagnitudeRefinementPass() { - var decoder = this.decoder; - var width = this.width, height = this.height; - var coefficentsMagnitude = this.coefficentsMagnitude; - var neighborsSignificance = this.neighborsSignificance; - var contexts = this.contexts; - var bitsDecoded = this.bitsDecoded; - var processingFlags = this.processingFlags; - var processedMask = 1; - var firstMagnitudeBitMask = 2; - var length = width * height; - var width4 = width * 4; - - for (var index0 = 0, indexNext; index0 < length; index0 = indexNext) { - indexNext = Math.min(length, index0 + width4); - for (var j = 0; j < width; j++) { - for (var index = index0 + j; index < indexNext; index += width) { - - // significant but not those that have just become - if (!coefficentsMagnitude[index] || - (processingFlags[index] & processedMask) !== 0) { - continue; - } - - var contextLabel = 16; - if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) { - processingFlags[index] ^= firstMagnitudeBitMask; - // first refinement - var significance = neighborsSignificance[index] & 127; - contextLabel = significance === 0 ? 15 : 14; - } - - var bit = decoder.readBit(contexts, contextLabel); - coefficentsMagnitude[index] = - (coefficentsMagnitude[index] << 1) | bit; - bitsDecoded[index]++; - processingFlags[index] |= processedMask; - } - } - } - }, - runCleanupPass: function BitModel_runCleanupPass() { - var decoder = this.decoder; - var width = this.width, height = this.height; - var neighborsSignificance = this.neighborsSignificance; - var coefficentsMagnitude = this.coefficentsMagnitude; - var coefficentsSign = this.coefficentsSign; - var contexts = this.contexts; - var labels = this.contextLabelTable; - var bitsDecoded = this.bitsDecoded; - var processingFlags = this.processingFlags; - var processedMask = 1; - var firstMagnitudeBitMask = 2; - var oneRowDown = width; - var twoRowsDown = width * 2; - var threeRowsDown = width * 3; - var iNext; - for (var i0 = 0; i0 < height; i0 = iNext) { - iNext = Math.min(i0 + 4, height); - var indexBase = i0 * width; - var checkAllEmpty = i0 + 3 < height; - for (var j = 0; j < width; j++) { - var index0 = indexBase + j; - // using the property: labels[neighborsSignificance[index]] === 0 - // when neighborsSignificance[index] === 0 - var allEmpty = (checkAllEmpty && - processingFlags[index0] === 0 && - processingFlags[index0 + oneRowDown] === 0 && - processingFlags[index0 + twoRowsDown] === 0 && - processingFlags[index0 + threeRowsDown] === 0 && - neighborsSignificance[index0] === 0 && - neighborsSignificance[index0 + oneRowDown] === 0 && - neighborsSignificance[index0 + twoRowsDown] === 0 && - neighborsSignificance[index0 + threeRowsDown] === 0); - var i1 = 0, index = index0; - var i = i0, sign; - if (allEmpty) { - var hasSignificantCoefficent = - decoder.readBit(contexts, RUNLENGTH_CONTEXT); - if (!hasSignificantCoefficent) { - bitsDecoded[index0]++; - bitsDecoded[index0 + oneRowDown]++; - bitsDecoded[index0 + twoRowsDown]++; - bitsDecoded[index0 + threeRowsDown]++; - continue; // next column - } - i1 = (decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) | - decoder.readBit(contexts, UNIFORM_CONTEXT); - if (i1 !== 0) { - i = i0 + i1; - index += i1 * width; - } - - sign = this.decodeSignBit(i, j, index); - coefficentsSign[index] = sign; - coefficentsMagnitude[index] = 1; - this.setNeighborsSignificance(i, j, index); - processingFlags[index] |= firstMagnitudeBitMask; - - index = index0; - for (var i2 = i0; i2 <= i; i2++, index += width) { - bitsDecoded[index]++; - } - - i1++; - } - for (i = i0 + i1; i < iNext; i++, index += width) { - if (coefficentsMagnitude[index] || - (processingFlags[index] & processedMask) !== 0) { - continue; - } - - var contextLabel = labels[neighborsSignificance[index]]; - var decision = decoder.readBit(contexts, contextLabel); - if (decision === 1) { - sign = this.decodeSignBit(i, j, index); - coefficentsSign[index] = sign; - coefficentsMagnitude[index] = 1; - this.setNeighborsSignificance(i, j, index); - processingFlags[index] |= firstMagnitudeBitMask; - } - bitsDecoded[index]++; - } - } - } - }, - checkSegmentationSymbol: function BitModel_checkSegmentationSymbol() { - var decoder = this.decoder; - var contexts = this.contexts; - var symbol = (decoder.readBit(contexts, UNIFORM_CONTEXT) << 3) | - (decoder.readBit(contexts, UNIFORM_CONTEXT) << 2) | - (decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) | - decoder.readBit(contexts, UNIFORM_CONTEXT); - if (symbol !== 0xA) { - throw new Error('JPX Error: Invalid segmentation symbol'); - } - } - }; - - return BitModel; - })(); - - // Section F, Discrete wavelet transformation - var Transform = (function TransformClosure() { - function Transform() {} - - Transform.prototype.calculate = - function transformCalculate(subbands, u0, v0) { - var ll = subbands[0]; - for (var i = 1, ii = subbands.length; i < ii; i++) { - ll = this.iterate(ll, subbands[i], u0, v0); - } - return ll; - }; - Transform.prototype.extend = function extend(buffer, offset, size) { - // Section F.3.7 extending... using max extension of 4 - var i1 = offset - 1, j1 = offset + 1; - var i2 = offset + size - 2, j2 = offset + size; - buffer[i1--] = buffer[j1++]; - buffer[j2++] = buffer[i2--]; - buffer[i1--] = buffer[j1++]; - buffer[j2++] = buffer[i2--]; - buffer[i1--] = buffer[j1++]; - buffer[j2++] = buffer[i2--]; - buffer[i1] = buffer[j1]; - buffer[j2] = buffer[i2]; - }; - Transform.prototype.iterate = function Transform_iterate(ll, hl_lh_hh, - u0, v0) { - var llWidth = ll.width, llHeight = ll.height, llItems = ll.items; - var width = hl_lh_hh.width; - var height = hl_lh_hh.height; - var items = hl_lh_hh.items; - var i, j, k, l, u, v; - - // Interleave LL according to Section F.3.3 - for (k = 0, i = 0; i < llHeight; i++) { - l = i * 2 * width; - for (j = 0; j < llWidth; j++, k++, l += 2) { - items[l] = llItems[k]; - } - } - // The LL band is not needed anymore. - llItems = ll.items = null; - - var bufferPadding = 4; - var rowBuffer = new Float32Array(width + 2 * bufferPadding); - - // Section F.3.4 HOR_SR - if (width === 1) { - // if width = 1, when u0 even keep items as is, when odd divide by 2 - if ((u0 & 1) !== 0) { - for (v = 0, k = 0; v < height; v++, k += width) { - items[k] *= 0.5; - } - } - } else { - for (v = 0, k = 0; v < height; v++, k += width) { - rowBuffer.set(items.subarray(k, k + width), bufferPadding); - - this.extend(rowBuffer, bufferPadding, width); - this.filter(rowBuffer, bufferPadding, width); - - items.set( - rowBuffer.subarray(bufferPadding, bufferPadding + width), - k); - } - } - - // Accesses to the items array can take long, because it may not fit into - // CPU cache and has to be fetched from main memory. Since subsequent - // accesses to the items array are not local when reading columns, we - // have a cache miss every time. To reduce cache misses, get up to - // 'numBuffers' items at a time and store them into the individual - // buffers. The colBuffers should be small enough to fit into CPU cache. - var numBuffers = 16; - var colBuffers = []; - for (i = 0; i < numBuffers; i++) { - colBuffers.push(new Float32Array(height + 2 * bufferPadding)); - } - var b, currentBuffer = 0; - ll = bufferPadding + height; - - // Section F.3.5 VER_SR - if (height === 1) { - // if height = 1, when v0 even keep items as is, when odd divide by 2 - if ((v0 & 1) !== 0) { - for (u = 0; u < width; u++) { - items[u] *= 0.5; - } - } - } else { - for (u = 0; u < width; u++) { - // if we ran out of buffers, copy several image columns at once - if (currentBuffer === 0) { - numBuffers = Math.min(width - u, numBuffers); - for (k = u, l = bufferPadding; l < ll; k += width, l++) { - for (b = 0; b < numBuffers; b++) { - colBuffers[b][l] = items[k + b]; - } - } - currentBuffer = numBuffers; - } - - currentBuffer--; - var buffer = colBuffers[currentBuffer]; - this.extend(buffer, bufferPadding, height); - this.filter(buffer, bufferPadding, height); - - // If this is last buffer in this group of buffers, flush all buffers. - if (currentBuffer === 0) { - k = u - numBuffers + 1; - for (l = bufferPadding; l < ll; k += width, l++) { - for (b = 0; b < numBuffers; b++) { - items[k + b] = colBuffers[b][l]; - } - } - } - } - } - - return { - width: width, - height: height, - items: items - }; - }; - return Transform; - })(); - - // Section 3.8.2 Irreversible 9-7 filter - var IrreversibleTransform = (function IrreversibleTransformClosure() { - function IrreversibleTransform() { - Transform.call(this); - } - - IrreversibleTransform.prototype = Object.create(Transform.prototype); - IrreversibleTransform.prototype.filter = - function irreversibleTransformFilter(x, offset, length) { - var len = length >> 1; - offset = offset | 0; - var j, n, current, next; - - var alpha = -1.586134342059924; - var beta = -0.052980118572961; - var gamma = 0.882911075530934; - var delta = 0.443506852043971; - var K = 1.230174104914001; - var K_ = 1 / K; - - // step 1 is combined with step 3 - - // step 2 - j = offset - 3; - for (n = len + 4; n--; j += 2) { - x[j] *= K_; - } - - // step 1 & 3 - j = offset - 2; - current = delta * x[j -1]; - for (n = len + 3; n--; j += 2) { - next = delta * x[j + 1]; - x[j] = K * x[j] - current - next; - if (n--) { - j += 2; - current = delta * x[j + 1]; - x[j] = K * x[j] - current - next; - } else { - break; - } - } - - // step 4 - j = offset - 1; - current = gamma * x[j - 1]; - for (n = len + 2; n--; j += 2) { - next = gamma * x[j + 1]; - x[j] -= current + next; - if (n--) { - j += 2; - current = gamma * x[j + 1]; - x[j] -= current + next; - } else { - break; - } - } - - // step 5 - j = offset; - current = beta * x[j - 1]; - for (n = len + 1; n--; j += 2) { - next = beta * x[j + 1]; - x[j] -= current + next; - if (n--) { - j += 2; - current = beta * x[j + 1]; - x[j] -= current + next; - } else { - break; - } - } - - // step 6 - if (len !== 0) { - j = offset + 1; - current = alpha * x[j - 1]; - for (n = len; n--; j += 2) { - next = alpha * x[j + 1]; - x[j] -= current + next; - if (n--) { - j += 2; - current = alpha * x[j + 1]; - x[j] -= current + next; - } else { - break; - } - } - } - }; - - return IrreversibleTransform; - })(); - - // Section 3.8.1 Reversible 5-3 filter - var ReversibleTransform = (function ReversibleTransformClosure() { - function ReversibleTransform() { - Transform.call(this); - } - - ReversibleTransform.prototype = Object.create(Transform.prototype); - ReversibleTransform.prototype.filter = - function reversibleTransformFilter(x, offset, length) { - var len = length >> 1; - offset = offset | 0; - var j, n; - - for (j = offset, n = len + 1; n--; j += 2) { - x[j] -= (x[j - 1] + x[j + 1] + 2) >> 2; - } - - for (j = offset + 1, n = len; n--; j += 2) { - x[j] += (x[j - 1] + x[j + 1]) >> 1; - } - }; - - return ReversibleTransform; - })(); - - return JpxImage; -})(); - - -var Jbig2Image = (function Jbig2ImageClosure() { - // Utility data structures - function ContextCache() {} - - ContextCache.prototype = { - getContexts: function(id) { - if (id in this) { - return this[id]; - } - return (this[id] = new Int8Array(1 << 16)); - } - }; - - function DecodingContext(data, start, end) { - this.data = data; - this.start = start; - this.end = end; - } - - DecodingContext.prototype = { - get decoder() { - var decoder = new ArithmeticDecoder(this.data, this.start, this.end); - return shadow(this, 'decoder', decoder); - }, - get contextCache() { - var cache = new ContextCache(); - return shadow(this, 'contextCache', cache); - } - }; - - // Annex A. Arithmetic Integer Decoding Procedure - // A.2 Procedure for decoding values - function decodeInteger(contextCache, procedure, decoder) { - var contexts = contextCache.getContexts(procedure); - var prev = 1; - - function readBits(length) { - var v = 0; - for (var i = 0; i < length; i++) { - var bit = decoder.readBit(contexts, prev); - prev = (prev < 256 ? (prev << 1) | bit : - (((prev << 1) | bit) & 511) | 256); - v = (v << 1) | bit; - } - return v >>> 0; - } - - var sign = readBits(1); - var value = readBits(1) ? - (readBits(1) ? - (readBits(1) ? - (readBits(1) ? - (readBits(1) ? - (readBits(32) + 4436) : - readBits(12) + 340) : - readBits(8) + 84) : - readBits(6) + 20) : - readBits(4) + 4) : - readBits(2); - return (sign === 0 ? value : (value > 0 ? -value : null)); - } - - // A.3 The IAID decoding procedure - function decodeIAID(contextCache, decoder, codeLength) { - var contexts = contextCache.getContexts('IAID'); - - var prev = 1; - for (var i = 0; i < codeLength; i++) { - var bit = decoder.readBit(contexts, prev); - prev = (prev << 1) | bit; - } - if (codeLength < 31) { - return prev & ((1 << codeLength) - 1); - } - return prev & 0x7FFFFFFF; - } - - // 7.3 Segment types - var SegmentTypes = [ - 'SymbolDictionary', null, null, null, 'IntermediateTextRegion', null, - 'ImmediateTextRegion', 'ImmediateLosslessTextRegion', null, null, null, - null, null, null, null, null, 'patternDictionary', null, null, null, - 'IntermediateHalftoneRegion', null, 'ImmediateHalftoneRegion', - 'ImmediateLosslessHalftoneRegion', null, null, null, null, null, null, null, - null, null, null, null, null, 'IntermediateGenericRegion', null, - 'ImmediateGenericRegion', 'ImmediateLosslessGenericRegion', - 'IntermediateGenericRefinementRegion', null, - 'ImmediateGenericRefinementRegion', - 'ImmediateLosslessGenericRefinementRegion', null, null, null, null, - 'PageInformation', 'EndOfPage', 'EndOfStripe', 'EndOfFile', 'Profiles', - 'Tables', null, null, null, null, null, null, null, null, - 'Extension' - ]; - - var CodingTemplates = [ - [{x: -1, y: -2}, {x: 0, y: -2}, {x: 1, y: -2}, {x: -2, y: -1}, - {x: -1, y: -1}, {x: 0, y: -1}, {x: 1, y: -1}, {x: 2, y: -1}, - {x: -4, y: 0}, {x: -3, y: 0}, {x: -2, y: 0}, {x: -1, y: 0}], - [{x: -1, y: -2}, {x: 0, y: -2}, {x: 1, y: -2}, {x: 2, y: -2}, - {x: -2, y: -1}, {x: -1, y: -1}, {x: 0, y: -1}, {x: 1, y: -1}, - {x: 2, y: -1}, {x: -3, y: 0}, {x: -2, y: 0}, {x: -1, y: 0}], - [{x: -1, y: -2}, {x: 0, y: -2}, {x: 1, y: -2}, {x: -2, y: -1}, - {x: -1, y: -1}, {x: 0, y: -1}, {x: 1, y: -1}, {x: -2, y: 0}, - {x: -1, y: 0}], - [{x: -3, y: -1}, {x: -2, y: -1}, {x: -1, y: -1}, {x: 0, y: -1}, - {x: 1, y: -1}, {x: -4, y: 0}, {x: -3, y: 0}, {x: -2, y: 0}, {x: -1, y: 0}] - ]; - - var RefinementTemplates = [ - { - coding: [{x: 0, y: -1}, {x: 1, y: -1}, {x: -1, y: 0}], - reference: [{x: 0, y: -1}, {x: 1, y: -1}, {x: -1, y: 0}, {x: 0, y: 0}, - {x: 1, y: 0}, {x: -1, y: 1}, {x: 0, y: 1}, {x: 1, y: 1}] - }, - { - coding: [{x: -1, y: -1}, {x: 0, y: -1}, {x: 1, y: -1}, {x: -1, y: 0}], - reference: [{x: 0, y: -1}, {x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}, - {x: 0, y: 1}, {x: 1, y: 1}] - } - ]; - - // See 6.2.5.7 Decoding the bitmap. - var ReusedContexts = [ - 0x9B25, // 10011 0110010 0101 - 0x0795, // 0011 110010 101 - 0x00E5, // 001 11001 01 - 0x0195 // 011001 0101 - ]; - - var RefinementReusedContexts = [ - 0x0020, // '000' + '0' (coding) + '00010000' + '0' (reference) - 0x0008 // '0000' + '001000' - ]; - - function decodeBitmapTemplate0(width, height, decodingContext) { - var decoder = decodingContext.decoder; - var contexts = decodingContext.contextCache.getContexts('GB'); - var contextLabel, i, j, pixel, row, row1, row2, bitmap = []; - - // ...ooooo.... - // ..ooooooo... Context template for current pixel (X) - // .ooooX...... (concatenate values of 'o'-pixels to get contextLabel) - var OLD_PIXEL_MASK = 0x7BF7; // 01111 0111111 0111 - - for (i = 0; i < height; i++) { - row = bitmap[i] = new Uint8Array(width); - row1 = (i < 1) ? row : bitmap[i - 1]; - row2 = (i < 2) ? row : bitmap[i - 2]; - - // At the beginning of each row: - // Fill contextLabel with pixels that are above/right of (X) - contextLabel = (row2[0] << 13) | (row2[1] << 12) | (row2[2] << 11) | - (row1[0] << 7) | (row1[1] << 6) | (row1[2] << 5) | - (row1[3] << 4); - - for (j = 0; j < width; j++) { - row[j] = pixel = decoder.readBit(contexts, contextLabel); - - // At each pixel: Clear contextLabel pixels that are shifted - // out of the context, then add new ones. - contextLabel = ((contextLabel & OLD_PIXEL_MASK) << 1) | - (j + 3 < width ? row2[j + 3] << 11 : 0) | - (j + 4 < width ? row1[j + 4] << 4 : 0) | pixel; - } - } - - return bitmap; - } - - // 6.2 Generic Region Decoding Procedure - function decodeBitmap(mmr, width, height, templateIndex, prediction, skip, at, - decodingContext) { - if (mmr) { - error('JBIG2 error: MMR encoding is not supported'); - } - - // Use optimized version for the most common case - if (templateIndex === 0 && !skip && !prediction && at.length === 4 && - at[0].x === 3 && at[0].y === -1 && at[1].x === -3 && at[1].y === -1 && - at[2].x === 2 && at[2].y === -2 && at[3].x === -2 && at[3].y === -2) { - return decodeBitmapTemplate0(width, height, decodingContext); - } - - var useskip = !!skip; - var template = CodingTemplates[templateIndex].concat(at); - - // Sorting is non-standard, and it is not required. But sorting increases - // the number of template bits that can be reused from the previous - // contextLabel in the main loop. - template.sort(function (a, b) { - return (a.y - b.y) || (a.x - b.x); - }); - - var templateLength = template.length; - var templateX = new Int8Array(templateLength); - var templateY = new Int8Array(templateLength); - var changingTemplateEntries = []; - var reuseMask = 0, minX = 0, maxX = 0, minY = 0; - var c, k; - - for (k = 0; k < templateLength; k++) { - templateX[k] = template[k].x; - templateY[k] = template[k].y; - minX = Math.min(minX, template[k].x); - maxX = Math.max(maxX, template[k].x); - minY = Math.min(minY, template[k].y); - // Check if the template pixel appears in two consecutive context labels, - // so it can be reused. Otherwise, we add it to the list of changing - // template entries. - if (k < templateLength - 1 && - template[k].y === template[k + 1].y && - template[k].x === template[k + 1].x - 1) { - reuseMask |= 1 << (templateLength - 1 - k); - } else { - changingTemplateEntries.push(k); - } - } - var changingEntriesLength = changingTemplateEntries.length; - - var changingTemplateX = new Int8Array(changingEntriesLength); - var changingTemplateY = new Int8Array(changingEntriesLength); - var changingTemplateBit = new Uint16Array(changingEntriesLength); - for (c = 0; c < changingEntriesLength; c++) { - k = changingTemplateEntries[c]; - changingTemplateX[c] = template[k].x; - changingTemplateY[c] = template[k].y; - changingTemplateBit[c] = 1 << (templateLength - 1 - k); - } - - // Get the safe bounding box edges from the width, height, minX, maxX, minY - var sbb_left = -minX; - var sbb_top = -minY; - var sbb_right = width - maxX; - - var pseudoPixelContext = ReusedContexts[templateIndex]; - var row = new Uint8Array(width); - var bitmap = []; - - var decoder = decodingContext.decoder; - var contexts = decodingContext.contextCache.getContexts('GB'); - - var ltp = 0, j, i0, j0, contextLabel = 0, bit, shift; - for (var i = 0; i < height; i++) { - if (prediction) { - var sltp = decoder.readBit(contexts, pseudoPixelContext); - ltp ^= sltp; - if (ltp) { - bitmap.push(row); // duplicate previous row - continue; - } - } - row = new Uint8Array(row); - bitmap.push(row); - for (j = 0; j < width; j++) { - if (useskip && skip[i][j]) { - row[j] = 0; - continue; - } - // Are we in the middle of a scanline, so we can reuse contextLabel - // bits? - if (j >= sbb_left && j < sbb_right && i >= sbb_top) { - // If yes, we can just shift the bits that are reusable and only - // fetch the remaining ones. - contextLabel = (contextLabel << 1) & reuseMask; - for (k = 0; k < changingEntriesLength; k++) { - i0 = i + changingTemplateY[k]; - j0 = j + changingTemplateX[k]; - bit = bitmap[i0][j0]; - if (bit) { - bit = changingTemplateBit[k]; - contextLabel |= bit; - } - } - } else { - // compute the contextLabel from scratch - contextLabel = 0; - shift = templateLength - 1; - for (k = 0; k < templateLength; k++, shift--) { - j0 = j + templateX[k]; - if (j0 >= 0 && j0 < width) { - i0 = i + templateY[k]; - if (i0 >= 0) { - bit = bitmap[i0][j0]; - if (bit) { - contextLabel |= bit << shift; - } - } - } - } - } - var pixel = decoder.readBit(contexts, contextLabel); - row[j] = pixel; - } - } - return bitmap; - } - - // 6.3.2 Generic Refinement Region Decoding Procedure - function decodeRefinement(width, height, templateIndex, referenceBitmap, - offsetX, offsetY, prediction, at, - decodingContext) { - var codingTemplate = RefinementTemplates[templateIndex].coding; - if (templateIndex === 0) { - codingTemplate = codingTemplate.concat([at[0]]); - } - var codingTemplateLength = codingTemplate.length; - var codingTemplateX = new Int32Array(codingTemplateLength); - var codingTemplateY = new Int32Array(codingTemplateLength); - var k; - for (k = 0; k < codingTemplateLength; k++) { - codingTemplateX[k] = codingTemplate[k].x; - codingTemplateY[k] = codingTemplate[k].y; - } - - var referenceTemplate = RefinementTemplates[templateIndex].reference; - if (templateIndex === 0) { - referenceTemplate = referenceTemplate.concat([at[1]]); - } - var referenceTemplateLength = referenceTemplate.length; - var referenceTemplateX = new Int32Array(referenceTemplateLength); - var referenceTemplateY = new Int32Array(referenceTemplateLength); - for (k = 0; k < referenceTemplateLength; k++) { - referenceTemplateX[k] = referenceTemplate[k].x; - referenceTemplateY[k] = referenceTemplate[k].y; - } - var referenceWidth = referenceBitmap[0].length; - var referenceHeight = referenceBitmap.length; - - var pseudoPixelContext = RefinementReusedContexts[templateIndex]; - var bitmap = []; - - var decoder = decodingContext.decoder; - var contexts = decodingContext.contextCache.getContexts('GR'); - - var ltp = 0; - for (var i = 0; i < height; i++) { - if (prediction) { - var sltp = decoder.readBit(contexts, pseudoPixelContext); - ltp ^= sltp; - if (ltp) { - error('JBIG2 error: prediction is not supported'); - } - } - var row = new Uint8Array(width); - bitmap.push(row); - for (var j = 0; j < width; j++) { - var i0, j0; - var contextLabel = 0; - for (k = 0; k < codingTemplateLength; k++) { - i0 = i + codingTemplateY[k]; - j0 = j + codingTemplateX[k]; - if (i0 < 0 || j0 < 0 || j0 >= width) { - contextLabel <<= 1; // out of bound pixel - } else { - contextLabel = (contextLabel << 1) | bitmap[i0][j0]; - } - } - for (k = 0; k < referenceTemplateLength; k++) { - i0 = i + referenceTemplateY[k] + offsetY; - j0 = j + referenceTemplateX[k] + offsetX; - if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || - j0 >= referenceWidth) { - contextLabel <<= 1; // out of bound pixel - } else { - contextLabel = (contextLabel << 1) | referenceBitmap[i0][j0]; - } - } - var pixel = decoder.readBit(contexts, contextLabel); - row[j] = pixel; - } - } - - return bitmap; - } - - // 6.5.5 Decoding the symbol dictionary - function decodeSymbolDictionary(huffman, refinement, symbols, - numberOfNewSymbols, numberOfExportedSymbols, - huffmanTables, templateIndex, at, - refinementTemplateIndex, refinementAt, - decodingContext) { - if (huffman) { - error('JBIG2 error: huffman is not supported'); - } - - var newSymbols = []; - var currentHeight = 0; - var symbolCodeLength = log2(symbols.length + numberOfNewSymbols); - - var decoder = decodingContext.decoder; - var contextCache = decodingContext.contextCache; - - while (newSymbols.length < numberOfNewSymbols) { - var deltaHeight = decodeInteger(contextCache, 'IADH', decoder); // 6.5.6 - currentHeight += deltaHeight; - var currentWidth = 0; - var totalWidth = 0; - while (true) { - var deltaWidth = decodeInteger(contextCache, 'IADW', decoder); // 6.5.7 - if (deltaWidth === null) { - break; // OOB - } - currentWidth += deltaWidth; - totalWidth += currentWidth; - var bitmap; - if (refinement) { - // 6.5.8.2 Refinement/aggregate-coded symbol bitmap - var numberOfInstances = decodeInteger(contextCache, 'IAAI', decoder); - if (numberOfInstances > 1) { - bitmap = decodeTextRegion(huffman, refinement, - currentWidth, currentHeight, 0, - numberOfInstances, 1, //strip size - symbols.concat(newSymbols), - symbolCodeLength, - 0, //transposed - 0, //ds offset - 1, //top left 7.4.3.1.1 - 0, //OR operator - huffmanTables, - refinementTemplateIndex, refinementAt, - decodingContext); - } else { - var symbolId = decodeIAID(contextCache, decoder, symbolCodeLength); - var rdx = decodeInteger(contextCache, 'IARDX', decoder); // 6.4.11.3 - var rdy = decodeInteger(contextCache, 'IARDY', decoder); // 6.4.11.4 - var symbol = (symbolId < symbols.length ? symbols[symbolId] : - newSymbols[symbolId - symbols.length]); - bitmap = decodeRefinement(currentWidth, currentHeight, - refinementTemplateIndex, symbol, rdx, rdy, false, refinementAt, - decodingContext); - } - } else { - // 6.5.8.1 Direct-coded symbol bitmap - bitmap = decodeBitmap(false, currentWidth, currentHeight, - templateIndex, false, null, at, decodingContext); - } - newSymbols.push(bitmap); - } - } - // 6.5.10 Exported symbols - var exportedSymbols = []; - var flags = [], currentFlag = false; - var totalSymbolsLength = symbols.length + numberOfNewSymbols; - while (flags.length < totalSymbolsLength) { - var runLength = decodeInteger(contextCache, 'IAEX', decoder); - while (runLength--) { - flags.push(currentFlag); - } - currentFlag = !currentFlag; - } - for (var i = 0, ii = symbols.length; i < ii; i++) { - if (flags[i]) { - exportedSymbols.push(symbols[i]); - } - } - for (var j = 0; j < numberOfNewSymbols; i++, j++) { - if (flags[i]) { - exportedSymbols.push(newSymbols[j]); - } - } - return exportedSymbols; - } - - function decodeTextRegion(huffman, refinement, width, height, - defaultPixelValue, numberOfSymbolInstances, - stripSize, inputSymbols, symbolCodeLength, - transposed, dsOffset, referenceCorner, - combinationOperator, huffmanTables, - refinementTemplateIndex, refinementAt, - decodingContext) { - if (huffman) { - error('JBIG2 error: huffman is not supported'); - } - - // Prepare bitmap - var bitmap = []; - var i, row; - for (i = 0; i < height; i++) { - row = new Uint8Array(width); - if (defaultPixelValue) { - for (var j = 0; j < width; j++) { - row[j] = defaultPixelValue; - } - } - bitmap.push(row); - } - - var decoder = decodingContext.decoder; - var contextCache = decodingContext.contextCache; - var stripT = -decodeInteger(contextCache, 'IADT', decoder); // 6.4.6 - var firstS = 0; - i = 0; - while (i < numberOfSymbolInstances) { - var deltaT = decodeInteger(contextCache, 'IADT', decoder); // 6.4.6 - stripT += deltaT; - - var deltaFirstS = decodeInteger(contextCache, 'IAFS', decoder); // 6.4.7 - firstS += deltaFirstS; - var currentS = firstS; - do { - var currentT = (stripSize === 1 ? 0 : - decodeInteger(contextCache, 'IAIT', decoder)); // 6.4.9 - var t = stripSize * stripT + currentT; - var symbolId = decodeIAID(contextCache, decoder, symbolCodeLength); - var applyRefinement = (refinement && - decodeInteger(contextCache, 'IARI', decoder)); - var symbolBitmap = inputSymbols[symbolId]; - var symbolWidth = symbolBitmap[0].length; - var symbolHeight = symbolBitmap.length; - if (applyRefinement) { - var rdw = decodeInteger(contextCache, 'IARDW', decoder); // 6.4.11.1 - var rdh = decodeInteger(contextCache, 'IARDH', decoder); // 6.4.11.2 - var rdx = decodeInteger(contextCache, 'IARDX', decoder); // 6.4.11.3 - var rdy = decodeInteger(contextCache, 'IARDY', decoder); // 6.4.11.4 - symbolWidth += rdw; - symbolHeight += rdh; - symbolBitmap = decodeRefinement(symbolWidth, symbolHeight, - refinementTemplateIndex, symbolBitmap, (rdw >> 1) + rdx, - (rdh >> 1) + rdy, false, refinementAt, - decodingContext); - } - var offsetT = t - ((referenceCorner & 1) ? 0 : symbolHeight); - var offsetS = currentS - ((referenceCorner & 2) ? symbolWidth : 0); - var s2, t2, symbolRow; - if (transposed) { - // Place Symbol Bitmap from T1,S1 - for (s2 = 0; s2 < symbolHeight; s2++) { - row = bitmap[offsetS + s2]; - if (!row) { - continue; - } - symbolRow = symbolBitmap[s2]; - // To ignore Parts of Symbol bitmap which goes - // outside bitmap region - var maxWidth = Math.min(width - offsetT, symbolWidth); - switch (combinationOperator) { - case 0: // OR - for (t2 = 0; t2 < maxWidth; t2++) { - row[offsetT + t2] |= symbolRow[t2]; - } - break; - case 2: // XOR - for (t2 = 0; t2 < maxWidth; t2++) { - row[offsetT + t2] ^= symbolRow[t2]; - } - break; - default: - error('JBIG2 error: operator ' + combinationOperator + - ' is not supported'); - } - } - currentS += symbolHeight - 1; - } else { - for (t2 = 0; t2 < symbolHeight; t2++) { - row = bitmap[offsetT + t2]; - if (!row) { - continue; - } - symbolRow = symbolBitmap[t2]; - switch (combinationOperator) { - case 0: // OR - for (s2 = 0; s2 < symbolWidth; s2++) { - row[offsetS + s2] |= symbolRow[s2]; - } - break; - case 2: // XOR - for (s2 = 0; s2 < symbolWidth; s2++) { - row[offsetS + s2] ^= symbolRow[s2]; - } - break; - default: - error('JBIG2 error: operator ' + combinationOperator + - ' is not supported'); - } - } - currentS += symbolWidth - 1; - } - i++; - var deltaS = decodeInteger(contextCache, 'IADS', decoder); // 6.4.8 - if (deltaS === null) { - break; // OOB - } - currentS += deltaS + dsOffset; - } while (true); - } - return bitmap; - } - - function readSegmentHeader(data, start) { - var segmentHeader = {}; - segmentHeader.number = readUint32(data, start); - var flags = data[start + 4]; - var segmentType = flags & 0x3F; - if (!SegmentTypes[segmentType]) { - error('JBIG2 error: invalid segment type: ' + segmentType); - } - segmentHeader.type = segmentType; - segmentHeader.typeName = SegmentTypes[segmentType]; - segmentHeader.deferredNonRetain = !!(flags & 0x80); - - var pageAssociationFieldSize = !!(flags & 0x40); - var referredFlags = data[start + 5]; - var referredToCount = (referredFlags >> 5) & 7; - var retainBits = [referredFlags & 31]; - var position = start + 6; - if (referredFlags === 7) { - referredToCount = readUint32(data, position - 1) & 0x1FFFFFFF; - position += 3; - var bytes = (referredToCount + 7) >> 3; - retainBits[0] = data[position++]; - while (--bytes > 0) { - retainBits.push(data[position++]); - } - } else if (referredFlags === 5 || referredFlags === 6) { - error('JBIG2 error: invalid referred-to flags'); - } - - segmentHeader.retainBits = retainBits; - var referredToSegmentNumberSize = (segmentHeader.number <= 256 ? 1 : - (segmentHeader.number <= 65536 ? 2 : 4)); - var referredTo = []; - var i, ii; - for (i = 0; i < referredToCount; i++) { - var number = (referredToSegmentNumberSize === 1 ? data[position] : - (referredToSegmentNumberSize === 2 ? readUint16(data, position) : - readUint32(data, position))); - referredTo.push(number); - position += referredToSegmentNumberSize; - } - segmentHeader.referredTo = referredTo; - if (!pageAssociationFieldSize) { - segmentHeader.pageAssociation = data[position++]; - } else { - segmentHeader.pageAssociation = readUint32(data, position); - position += 4; - } - segmentHeader.length = readUint32(data, position); - position += 4; - - if (segmentHeader.length === 0xFFFFFFFF) { - // 7.2.7 Segment data length, unknown segment length - if (segmentType === 38) { // ImmediateGenericRegion - var genericRegionInfo = readRegionSegmentInformation(data, position); - var genericRegionSegmentFlags = data[position + - RegionSegmentInformationFieldLength]; - var genericRegionMmr = !!(genericRegionSegmentFlags & 1); - // searching for the segment end - var searchPatternLength = 6; - var searchPattern = new Uint8Array(searchPatternLength); - if (!genericRegionMmr) { - searchPattern[0] = 0xFF; - searchPattern[1] = 0xAC; - } - searchPattern[2] = (genericRegionInfo.height >>> 24) & 0xFF; - searchPattern[3] = (genericRegionInfo.height >> 16) & 0xFF; - searchPattern[4] = (genericRegionInfo.height >> 8) & 0xFF; - searchPattern[5] = genericRegionInfo.height & 0xFF; - for (i = position, ii = data.length; i < ii; i++) { - var j = 0; - while (j < searchPatternLength && searchPattern[j] === data[i + j]) { - j++; - } - if (j === searchPatternLength) { - segmentHeader.length = i + searchPatternLength; - break; - } - } - if (segmentHeader.length === 0xFFFFFFFF) { - error('JBIG2 error: segment end was not found'); - } - } else { - error('JBIG2 error: invalid unknown segment length'); - } - } - segmentHeader.headerEnd = position; - return segmentHeader; - } - - function readSegments(header, data, start, end) { - var segments = []; - var position = start; - while (position < end) { - var segmentHeader = readSegmentHeader(data, position); - position = segmentHeader.headerEnd; - var segment = { - header: segmentHeader, - data: data - }; - if (!header.randomAccess) { - segment.start = position; - position += segmentHeader.length; - segment.end = position; - } - segments.push(segment); - if (segmentHeader.type === 51) { - break; // end of file is found - } - } - if (header.randomAccess) { - for (var i = 0, ii = segments.length; i < ii; i++) { - segments[i].start = position; - position += segments[i].header.length; - segments[i].end = position; - } - } - return segments; - } - - // 7.4.1 Region segment information field - function readRegionSegmentInformation(data, start) { - return { - width: readUint32(data, start), - height: readUint32(data, start + 4), - x: readUint32(data, start + 8), - y: readUint32(data, start + 12), - combinationOperator: data[start + 16] & 7 - }; - } - var RegionSegmentInformationFieldLength = 17; - - function processSegment(segment, visitor) { - var header = segment.header; - - var data = segment.data, position = segment.start, end = segment.end; - var args, at, i, atLength; - switch (header.type) { - case 0: // SymbolDictionary - // 7.4.2 Symbol dictionary segment syntax - var dictionary = {}; - var dictionaryFlags = readUint16(data, position); // 7.4.2.1.1 - dictionary.huffman = !!(dictionaryFlags & 1); - dictionary.refinement = !!(dictionaryFlags & 2); - dictionary.huffmanDHSelector = (dictionaryFlags >> 2) & 3; - dictionary.huffmanDWSelector = (dictionaryFlags >> 4) & 3; - dictionary.bitmapSizeSelector = (dictionaryFlags >> 6) & 1; - dictionary.aggregationInstancesSelector = (dictionaryFlags >> 7) & 1; - dictionary.bitmapCodingContextUsed = !!(dictionaryFlags & 256); - dictionary.bitmapCodingContextRetained = !!(dictionaryFlags & 512); - dictionary.template = (dictionaryFlags >> 10) & 3; - dictionary.refinementTemplate = (dictionaryFlags >> 12) & 1; - position += 2; - if (!dictionary.huffman) { - atLength = dictionary.template === 0 ? 4 : 1; - at = []; - for (i = 0; i < atLength; i++) { - at.push({ - x: readInt8(data, position), - y: readInt8(data, position + 1) - }); - position += 2; - } - dictionary.at = at; - } - if (dictionary.refinement && !dictionary.refinementTemplate) { - at = []; - for (i = 0; i < 2; i++) { - at.push({ - x: readInt8(data, position), - y: readInt8(data, position + 1) - }); - position += 2; - } - dictionary.refinementAt = at; - } - dictionary.numberOfExportedSymbols = readUint32(data, position); - position += 4; - dictionary.numberOfNewSymbols = readUint32(data, position); - position += 4; - args = [dictionary, header.number, header.referredTo, - data, position, end]; - break; - case 6: // ImmediateTextRegion - case 7: // ImmediateLosslessTextRegion - var textRegion = {}; - textRegion.info = readRegionSegmentInformation(data, position); - position += RegionSegmentInformationFieldLength; - var textRegionSegmentFlags = readUint16(data, position); - position += 2; - textRegion.huffman = !!(textRegionSegmentFlags & 1); - textRegion.refinement = !!(textRegionSegmentFlags & 2); - textRegion.stripSize = 1 << ((textRegionSegmentFlags >> 2) & 3); - textRegion.referenceCorner = (textRegionSegmentFlags >> 4) & 3; - textRegion.transposed = !!(textRegionSegmentFlags & 64); - textRegion.combinationOperator = (textRegionSegmentFlags >> 7) & 3; - textRegion.defaultPixelValue = (textRegionSegmentFlags >> 9) & 1; - textRegion.dsOffset = (textRegionSegmentFlags << 17) >> 27; - textRegion.refinementTemplate = (textRegionSegmentFlags >> 15) & 1; - if (textRegion.huffman) { - var textRegionHuffmanFlags = readUint16(data, position); - position += 2; - textRegion.huffmanFS = (textRegionHuffmanFlags) & 3; - textRegion.huffmanDS = (textRegionHuffmanFlags >> 2) & 3; - textRegion.huffmanDT = (textRegionHuffmanFlags >> 4) & 3; - textRegion.huffmanRefinementDW = (textRegionHuffmanFlags >> 6) & 3; - textRegion.huffmanRefinementDH = (textRegionHuffmanFlags >> 8) & 3; - textRegion.huffmanRefinementDX = (textRegionHuffmanFlags >> 10) & 3; - textRegion.huffmanRefinementDY = (textRegionHuffmanFlags >> 12) & 3; - textRegion.huffmanRefinementSizeSelector = - !!(textRegionHuffmanFlags & 14); - } - if (textRegion.refinement && !textRegion.refinementTemplate) { - at = []; - for (i = 0; i < 2; i++) { - at.push({ - x: readInt8(data, position), - y: readInt8(data, position + 1) - }); - position += 2; - } - textRegion.refinementAt = at; - } - textRegion.numberOfSymbolInstances = readUint32(data, position); - position += 4; - // TODO 7.4.3.1.7 Symbol ID Huffman table decoding - if (textRegion.huffman) { - error('JBIG2 error: huffman is not supported'); - } - args = [textRegion, header.referredTo, data, position, end]; - break; - case 38: // ImmediateGenericRegion - case 39: // ImmediateLosslessGenericRegion - var genericRegion = {}; - genericRegion.info = readRegionSegmentInformation(data, position); - position += RegionSegmentInformationFieldLength; - var genericRegionSegmentFlags = data[position++]; - genericRegion.mmr = !!(genericRegionSegmentFlags & 1); - genericRegion.template = (genericRegionSegmentFlags >> 1) & 3; - genericRegion.prediction = !!(genericRegionSegmentFlags & 8); - if (!genericRegion.mmr) { - atLength = genericRegion.template === 0 ? 4 : 1; - at = []; - for (i = 0; i < atLength; i++) { - at.push({ - x: readInt8(data, position), - y: readInt8(data, position + 1) - }); - position += 2; - } - genericRegion.at = at; - } - args = [genericRegion, data, position, end]; - break; - case 48: // PageInformation - var pageInfo = { - width: readUint32(data, position), - height: readUint32(data, position + 4), - resolutionX: readUint32(data, position + 8), - resolutionY: readUint32(data, position + 12) - }; - if (pageInfo.height === 0xFFFFFFFF) { - delete pageInfo.height; - } - var pageSegmentFlags = data[position + 16]; - var pageStripingInformatiom = readUint16(data, position + 17); - pageInfo.lossless = !!(pageSegmentFlags & 1); - pageInfo.refinement = !!(pageSegmentFlags & 2); - pageInfo.defaultPixelValue = (pageSegmentFlags >> 2) & 1; - pageInfo.combinationOperator = (pageSegmentFlags >> 3) & 3; - pageInfo.requiresBuffer = !!(pageSegmentFlags & 32); - pageInfo.combinationOperatorOverride = !!(pageSegmentFlags & 64); - args = [pageInfo]; - break; - case 49: // EndOfPage - break; - case 50: // EndOfStripe - break; - case 51: // EndOfFile - break; - case 62: // 7.4.15 defines 2 extension types which - // are comments and can be ignored. - break; - default: - error('JBIG2 error: segment type ' + header.typeName + '(' + - header.type + ') is not implemented'); - } - var callbackName = 'on' + header.typeName; - if (callbackName in visitor) { - visitor[callbackName].apply(visitor, args); - } - } - - function processSegments(segments, visitor) { - for (var i = 0, ii = segments.length; i < ii; i++) { - processSegment(segments[i], visitor); - } - } - - function parseJbig2(data, start, end) { - var position = start; - if (data[position] !== 0x97 || data[position + 1] !== 0x4A || - data[position + 2] !== 0x42 || data[position + 3] !== 0x32 || - data[position + 4] !== 0x0D || data[position + 5] !== 0x0A || - data[position + 6] !== 0x1A || data[position + 7] !== 0x0A) { - error('JBIG2 error: invalid header'); - } - var header = {}; - position += 8; - var flags = data[position++]; - header.randomAccess = !(flags & 1); - if (!(flags & 2)) { - header.numberOfPages = readUint32(data, position); - position += 4; - } - var segments = readSegments(header, data, position, end); - error('Not implemented'); - // processSegments(segments, new SimpleSegmentVisitor()); - } - - function parseJbig2Chunks(chunks) { - var visitor = new SimpleSegmentVisitor(); - for (var i = 0, ii = chunks.length; i < ii; i++) { - var chunk = chunks[i]; - var segments = readSegments({}, chunk.data, chunk.start, chunk.end); - processSegments(segments, visitor); - } - return visitor.buffer; - } - - function SimpleSegmentVisitor() {} - - SimpleSegmentVisitor.prototype = { - onPageInformation: function SimpleSegmentVisitor_onPageInformation(info) { - this.currentPageInfo = info; - var rowSize = (info.width + 7) >> 3; - var buffer = new Uint8Array(rowSize * info.height); - // The contents of ArrayBuffers are initialized to 0. - // Fill the buffer with 0xFF only if info.defaultPixelValue is set - if (info.defaultPixelValue) { - for (var i = 0, ii = buffer.length; i < ii; i++) { - buffer[i] = 0xFF; - } - } - this.buffer = buffer; - }, - drawBitmap: function SimpleSegmentVisitor_drawBitmap(regionInfo, bitmap) { - var pageInfo = this.currentPageInfo; - var width = regionInfo.width, height = regionInfo.height; - var rowSize = (pageInfo.width + 7) >> 3; - var combinationOperator = pageInfo.combinationOperatorOverride ? - regionInfo.combinationOperator : pageInfo.combinationOperator; - var buffer = this.buffer; - var mask0 = 128 >> (regionInfo.x & 7); - var offset0 = regionInfo.y * rowSize + (regionInfo.x >> 3); - var i, j, mask, offset; - switch (combinationOperator) { - case 0: // OR - for (i = 0; i < height; i++) { - mask = mask0; - offset = offset0; - for (j = 0; j < width; j++) { - if (bitmap[i][j]) { - buffer[offset] |= mask; - } - mask >>= 1; - if (!mask) { - mask = 128; - offset++; - } - } - offset0 += rowSize; - } - break; - case 2: // XOR - for (i = 0; i < height; i++) { - mask = mask0; - offset = offset0; - for (j = 0; j < width; j++) { - if (bitmap[i][j]) { - buffer[offset] ^= mask; - } - mask >>= 1; - if (!mask) { - mask = 128; - offset++; - } - } - offset0 += rowSize; - } - break; - default: - error('JBIG2 error: operator ' + combinationOperator + - ' is not supported'); - } - }, - onImmediateGenericRegion: - function SimpleSegmentVisitor_onImmediateGenericRegion(region, data, - start, end) { - var regionInfo = region.info; - var decodingContext = new DecodingContext(data, start, end); - var bitmap = decodeBitmap(region.mmr, regionInfo.width, regionInfo.height, - region.template, region.prediction, null, - region.at, decodingContext); - this.drawBitmap(regionInfo, bitmap); - }, - onImmediateLosslessGenericRegion: - function SimpleSegmentVisitor_onImmediateLosslessGenericRegion() { - this.onImmediateGenericRegion.apply(this, arguments); - }, - onSymbolDictionary: - function SimpleSegmentVisitor_onSymbolDictionary(dictionary, - currentSegment, - referredSegments, - data, start, end) { - var huffmanTables; - if (dictionary.huffman) { - error('JBIG2 error: huffman is not supported'); - } - - // Combines exported symbols from all referred segments - var symbols = this.symbols; - if (!symbols) { - this.symbols = symbols = {}; - } - - var inputSymbols = []; - for (var i = 0, ii = referredSegments.length; i < ii; i++) { - inputSymbols = inputSymbols.concat(symbols[referredSegments[i]]); - } - - var decodingContext = new DecodingContext(data, start, end); - symbols[currentSegment] = decodeSymbolDictionary(dictionary.huffman, - dictionary.refinement, inputSymbols, dictionary.numberOfNewSymbols, - dictionary.numberOfExportedSymbols, huffmanTables, - dictionary.template, dictionary.at, - dictionary.refinementTemplate, dictionary.refinementAt, - decodingContext); - }, - onImmediateTextRegion: - function SimpleSegmentVisitor_onImmediateTextRegion(region, - referredSegments, - data, start, end) { - var regionInfo = region.info; - var huffmanTables; - - // Combines exported symbols from all referred segments - var symbols = this.symbols; - var inputSymbols = []; - for (var i = 0, ii = referredSegments.length; i < ii; i++) { - inputSymbols = inputSymbols.concat(symbols[referredSegments[i]]); - } - var symbolCodeLength = log2(inputSymbols.length); - - var decodingContext = new DecodingContext(data, start, end); - var bitmap = decodeTextRegion(region.huffman, region.refinement, - regionInfo.width, regionInfo.height, region.defaultPixelValue, - region.numberOfSymbolInstances, region.stripSize, inputSymbols, - symbolCodeLength, region.transposed, region.dsOffset, - region.referenceCorner, region.combinationOperator, huffmanTables, - region.refinementTemplate, region.refinementAt, decodingContext); - this.drawBitmap(regionInfo, bitmap); - }, - onImmediateLosslessTextRegion: - function SimpleSegmentVisitor_onImmediateLosslessTextRegion() { - this.onImmediateTextRegion.apply(this, arguments); - } - }; - - function Jbig2Image() {} - - Jbig2Image.prototype = { - parseChunks: function Jbig2Image_parseChunks(chunks) { - return parseJbig2Chunks(chunks); - } - }; - - return Jbig2Image; -})(); - - -var bidi = PDFJS.bidi = (function bidiClosure() { - // Character types for symbols from 0000 to 00FF. - var baseTypes = [ - 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS', - 'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', - 'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET', 'ET', 'ET', 'ON', - 'ON', 'ON', 'ON', 'ON', 'ON', 'CS', 'ON', 'CS', 'ON', 'EN', 'EN', 'EN', - 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'ON', 'ON', 'ON', 'ON', 'ON', - 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON', - 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'ON', 'ON', 'ON', 'ON', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN', - 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', - 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', - 'BN', 'CS', 'ON', 'ET', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON', - 'ON', 'ON', 'ON', 'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON', - 'EN', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', - 'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L' - ]; - - // Character types for symbols from 0600 to 06FF - var arabicTypes = [ - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', - 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', - 'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', - 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'ON', 'NSM', - 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', - 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL' - ]; - - function isOdd(i) { - return (i & 1) !== 0; - } - - function isEven(i) { - return (i & 1) === 0; - } - - function findUnequal(arr, start, value) { - for (var j = start, jj = arr.length; j < jj; ++j) { - if (arr[j] !== value) { - return j; - } - } - return j; - } - - function setValues(arr, start, end, value) { - for (var j = start; j < end; ++j) { - arr[j] = value; - } - } - - function reverseValues(arr, start, end) { - for (var i = start, j = end - 1; i < j; ++i, --j) { - var temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - } - - function createBidiText(str, isLTR, vertical) { - return { - str: str, - dir: (vertical ? 'ttb' : (isLTR ? 'ltr' : 'rtl')) - }; - } - - // These are used in bidi(), which is called frequently. We re-use them on - // each call to avoid unnecessary allocations. - var chars = []; - var types = []; - - function bidi(str, startLevel, vertical) { - var isLTR = true; - var strLength = str.length; - if (strLength === 0 || vertical) { - return createBidiText(str, isLTR, vertical); - } - - // Get types and fill arrays - chars.length = strLength; - types.length = strLength; - var numBidi = 0; - - var i, ii; - for (i = 0; i < strLength; ++i) { - chars[i] = str.charAt(i); - - var charCode = str.charCodeAt(i); - var charType = 'L'; - if (charCode <= 0x00ff) { - charType = baseTypes[charCode]; - } else if (0x0590 <= charCode && charCode <= 0x05f4) { - charType = 'R'; - } else if (0x0600 <= charCode && charCode <= 0x06ff) { - charType = arabicTypes[charCode & 0xff]; - } else if (0x0700 <= charCode && charCode <= 0x08AC) { - charType = 'AL'; - } - if (charType === 'R' || charType === 'AL' || charType === 'AN') { - numBidi++; - } - types[i] = charType; - } - - // Detect the bidi method - // - If there are no rtl characters then no bidi needed - // - If less than 30% chars are rtl then string is primarily ltr - // - If more than 30% chars are rtl then string is primarily rtl - if (numBidi === 0) { - isLTR = true; - return createBidiText(str, isLTR); - } - - if (startLevel === -1) { - if ((strLength / numBidi) < 0.3) { - isLTR = true; - startLevel = 0; - } else { - isLTR = false; - startLevel = 1; - } - } - - var levels = []; - for (i = 0; i < strLength; ++i) { - levels[i] = startLevel; - } - - /* - X1-X10: skip most of this, since we are NOT doing the embeddings. - */ - var e = (isOdd(startLevel) ? 'R' : 'L'); - var sor = e; - var eor = sor; - - /* - W1. Examine each non-spacing mark (NSM) in the level run, and change the - type of the NSM to the type of the previous character. If the NSM is at the - start of the level run, it will get the type of sor. - */ - var lastType = sor; - for (i = 0; i < strLength; ++i) { - if (types[i] === 'NSM') { - types[i] = lastType; - } else { - lastType = types[i]; - } - } - - /* - W2. Search backwards from each instance of a European number until the - first strong type (R, L, AL, or sor) is found. If an AL is found, change - the type of the European number to Arabic number. - */ - lastType = sor; - var t; - for (i = 0; i < strLength; ++i) { - t = types[i]; - if (t === 'EN') { - types[i] = (lastType === 'AL') ? 'AN' : 'EN'; - } else if (t === 'R' || t === 'L' || t === 'AL') { - lastType = t; - } - } - - /* - W3. Change all ALs to R. - */ - for (i = 0; i < strLength; ++i) { - t = types[i]; - if (t === 'AL') { - types[i] = 'R'; - } - } - - /* - W4. A single European separator between two European numbers changes to a - European number. A single common separator between two numbers of the same - type changes to that type: - */ - for (i = 1; i < strLength - 1; ++i) { - if (types[i] === 'ES' && types[i - 1] === 'EN' && types[i + 1] === 'EN') { - types[i] = 'EN'; - } - if (types[i] === 'CS' && - (types[i - 1] === 'EN' || types[i - 1] === 'AN') && - types[i + 1] === types[i - 1]) { - types[i] = types[i - 1]; - } - } - - /* - W5. A sequence of European terminators adjacent to European numbers changes - to all European numbers: - */ - for (i = 0; i < strLength; ++i) { - if (types[i] === 'EN') { - // do before - var j; - for (j = i - 1; j >= 0; --j) { - if (types[j] !== 'ET') { - break; - } - types[j] = 'EN'; - } - // do after - for (j = i + 1; j < strLength; --j) { - if (types[j] !== 'ET') { - break; - } - types[j] = 'EN'; - } - } - } - - /* - W6. Otherwise, separators and terminators change to Other Neutral: - */ - for (i = 0; i < strLength; ++i) { - t = types[i]; - if (t === 'WS' || t === 'ES' || t === 'ET' || t === 'CS') { - types[i] = 'ON'; - } - } - - /* - W7. Search backwards from each instance of a European number until the - first strong type (R, L, or sor) is found. If an L is found, then change - the type of the European number to L. - */ - lastType = sor; - for (i = 0; i < strLength; ++i) { - t = types[i]; - if (t === 'EN') { - types[i] = ((lastType === 'L') ? 'L' : 'EN'); - } else if (t === 'R' || t === 'L') { - lastType = t; - } - } - - /* - N1. A sequence of neutrals takes the direction of the surrounding strong - text if the text on both sides has the same direction. European and Arabic - numbers are treated as though they were R. Start-of-level-run (sor) and - end-of-level-run (eor) are used at level run boundaries. - */ - for (i = 0; i < strLength; ++i) { - if (types[i] === 'ON') { - var end = findUnequal(types, i + 1, 'ON'); - var before = sor; - if (i > 0) { - before = types[i - 1]; - } - - var after = eor; - if (end + 1 < strLength) { - after = types[end + 1]; - } - if (before !== 'L') { - before = 'R'; - } - if (after !== 'L') { - after = 'R'; - } - if (before === after) { - setValues(types, i, end, before); - } - i = end - 1; // reset to end (-1 so next iteration is ok) - } - } - - /* - N2. Any remaining neutrals take the embedding direction. - */ - for (i = 0; i < strLength; ++i) { - if (types[i] === 'ON') { - types[i] = e; - } - } - - /* - I1. For all characters with an even (left-to-right) embedding direction, - those of type R go up one level and those of type AN or EN go up two - levels. - I2. For all characters with an odd (right-to-left) embedding direction, - those of type L, EN or AN go up one level. - */ - for (i = 0; i < strLength; ++i) { - t = types[i]; - if (isEven(levels[i])) { - if (t === 'R') { - levels[i] += 1; - } else if (t === 'AN' || t === 'EN') { - levels[i] += 2; - } - } else { // isOdd - if (t === 'L' || t === 'AN' || t === 'EN') { - levels[i] += 1; - } - } - } - - /* - L1. On each line, reset the embedding level of the following characters to - the paragraph embedding level: - - segment separators, - paragraph separators, - any sequence of whitespace characters preceding a segment separator or - paragraph separator, and any sequence of white space characters at the end - of the line. - */ - - // don't bother as text is only single line - - /* - L2. From the highest level found in the text to the lowest odd level on - each line, reverse any contiguous sequence of characters that are at that - level or higher. - */ - - // find highest level & lowest odd level - var highestLevel = -1; - var lowestOddLevel = 99; - var level; - for (i = 0, ii = levels.length; i < ii; ++i) { - level = levels[i]; - if (highestLevel < level) { - highestLevel = level; - } - if (lowestOddLevel > level && isOdd(level)) { - lowestOddLevel = level; - } - } - - // now reverse between those limits - for (level = highestLevel; level >= lowestOddLevel; --level) { - // find segments to reverse - var start = -1; - for (i = 0, ii = levels.length; i < ii; ++i) { - if (levels[i] < level) { - if (start >= 0) { - reverseValues(chars, start, i); - start = -1; - } - } else if (start < 0) { - start = i; - } - } - if (start >= 0) { - reverseValues(chars, start, levels.length); - } - } - - /* - L3. Combining marks applied to a right-to-left base character will at this - point precede their base character. If the rendering engine expects them to - follow the base characters in the final display process, then the ordering - of the marks and the base character must be reversed. - */ - - // don't bother for now - - /* - L4. A character that possesses the mirrored property as specified by - Section 4.7, Mirrored, must be depicted by a mirrored glyph if the resolved - directionality of that character is R. - */ - - // don't mirror as characters are already mirrored in the pdf - - // Finally, return string - var result = ''; - for (i = 0, ii = chars.length; i < ii; ++i) { - var ch = chars[i]; - if (ch !== '<' && ch !== '>') { - result += ch; - } - } - return createBidiText(result, isLTR); - } - - return bidi; -})(); - -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -/* Copyright 2014 Opera Software ASA - * - * 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. - * - * - * Based on https://code.google.com/p/smhasher/wiki/MurmurHash3. - * Hashes roughly 100 KB per millisecond on i7 3.4 GHz. - */ -/* globals Uint32ArrayView */ - -'use strict'; - -var MurmurHash3_64 = (function MurmurHash3_64Closure (seed) { - // Workaround for missing math precison in JS. - var MASK_HIGH = 0xffff0000; - var MASK_LOW = 0xffff; - - function MurmurHash3_64 (seed) { - var SEED = 0xc3d2e1f0; - this.h1 = seed ? seed & 0xffffffff : SEED; - this.h2 = seed ? seed & 0xffffffff : SEED; - } - - var alwaysUseUint32ArrayView = false; -//#if !(FIREFOX || MOZCENTRAL || B2G || CHROME) - // old webkits have issues with non-aligned arrays - try { - new Uint32Array(new Uint8Array(5).buffer, 0, 1); - } catch (e) { - alwaysUseUint32ArrayView = true; - } -//#endif - - MurmurHash3_64.prototype = { - update: function MurmurHash3_64_update(input) { - var useUint32ArrayView = alwaysUseUint32ArrayView; - var i; - if (typeof input === 'string') { - var data = new Uint8Array(input.length * 2); - var length = 0; - for (i = 0; i < input.length; i++) { - var code = input.charCodeAt(i); - if (code <= 0xff) { - data[length++] = code; - } - else { - data[length++] = code >>> 8; - data[length++] = code & 0xff; - } - } - } else if (input instanceof Uint8Array) { - data = input; - length = data.length; - } else if (typeof input === 'object' && ('length' in input)) { - // processing regular arrays as well, e.g. for IE9 - data = input; - length = data.length; - useUint32ArrayView = true; - } else { - throw new Error('Wrong data format in MurmurHash3_64_update. ' + - 'Input must be a string or array.'); - } - - var blockCounts = length >> 2; - var tailLength = length - blockCounts * 4; - // we don't care about endianness here - var dataUint32 = useUint32ArrayView ? - new Uint32ArrayView(data, blockCounts) : - new Uint32Array(data.buffer, 0, blockCounts); - var k1 = 0; - var k2 = 0; - var h1 = this.h1; - var h2 = this.h2; - var C1 = 0xcc9e2d51; - var C2 = 0x1b873593; - var C1_LOW = C1 & MASK_LOW; - var C2_LOW = C2 & MASK_LOW; - - for (i = 0; i < blockCounts; i++) { - if (i & 1) { - k1 = dataUint32[i]; - k1 = (k1 * C1 & MASK_HIGH) | (k1 * C1_LOW & MASK_LOW); - k1 = k1 << 15 | k1 >>> 17; - k1 = (k1 * C2 & MASK_HIGH) | (k1 * C2_LOW & MASK_LOW); - h1 ^= k1; - h1 = h1 << 13 | h1 >>> 19; - h1 = h1 * 5 + 0xe6546b64; - } else { - k2 = dataUint32[i]; - k2 = (k2 * C1 & MASK_HIGH) | (k2 * C1_LOW & MASK_LOW); - k2 = k2 << 15 | k2 >>> 17; - k2 = (k2 * C2 & MASK_HIGH) | (k2 * C2_LOW & MASK_LOW); - h2 ^= k2; - h2 = h2 << 13 | h2 >>> 19; - h2 = h2 * 5 + 0xe6546b64; - } - } - - k1 = 0; - - switch (tailLength) { - case 3: - k1 ^= data[blockCounts * 4 + 2] << 16; - /* falls through */ - case 2: - k1 ^= data[blockCounts * 4 + 1] << 8; - /* falls through */ - case 1: - k1 ^= data[blockCounts * 4]; - /* falls through */ - k1 = (k1 * C1 & MASK_HIGH) | (k1 * C1_LOW & MASK_LOW); - k1 = k1 << 15 | k1 >>> 17; - k1 = (k1 * C2 & MASK_HIGH) | (k1 * C2_LOW & MASK_LOW); - if (blockCounts & 1) { - h1 ^= k1; - } else { - h2 ^= k1; - } - } - - this.h1 = h1; - this.h2 = h2; - return this; - }, - - hexdigest: function MurmurHash3_64_hexdigest () { - var h1 = this.h1; - var h2 = this.h2; - - h1 ^= h2 >>> 1; - h1 = (h1 * 0xed558ccd & MASK_HIGH) | (h1 * 0x8ccd & MASK_LOW); - h2 = (h2 * 0xff51afd7 & MASK_HIGH) | - (((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16); - h1 ^= h2 >>> 1; - h1 = (h1 * 0x1a85ec53 & MASK_HIGH) | (h1 * 0xec53 & MASK_LOW); - h2 = (h2 * 0xc4ceb9fe & MASK_HIGH) | - (((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16); - h1 ^= h2 >>> 1; - - for (var i = 0, arr = [h1, h2], str = ''; i < arr.length; i++) { - var hex = (arr[i] >>> 0).toString(16); - while (hex.length < 8) { - hex = '0' + hex; - } - str += hex; - } - - return str; - } - }; - - return MurmurHash3_64; -})(); - - -}).call((typeof window === 'undefined') ? this : window); - -if (!PDFJS.workerSrc && typeof document !== 'undefined') { - // workerSrc is not set -- using last script url to define default location - PDFJS.workerSrc = (function () { - 'use strict'; - var scriptTagContainer = document.body || - document.getElementsByTagName('head')[0]; - var pdfjsSrc = scriptTagContainer.lastChild.src; - return pdfjsSrc && pdfjsSrc.replace(/\.js$/i, '.worker.js'); - })(); -} - diff --git a/plugins/pdf_viewer/v/pdfjsversion.js b/plugins/pdf_viewer/v/pdfjsversion.js deleted file mode 100755 index 7aefe44..0000000 --- a/plugins/pdf_viewer/v/pdfjsversion.js +++ /dev/null @@ -1 +0,0 @@ -var /**@const{!string}*/pdfjs_version = "v1.1.114"; diff --git a/plugins/pdf_viewer/v/text_layer_builder.js b/plugins/pdf_viewer/v/text_layer_builder.js deleted file mode 100755 index 7483c02..0000000 --- a/plugins/pdf_viewer/v/text_layer_builder.js +++ /dev/null @@ -1,419 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 CustomStyle, PDFJS */ - -'use strict'; - -var MAX_TEXT_DIVS_TO_RENDER = 100000; - -var NonWhitespaceRegexp = /\S/; - -function isAllWhitespace(str) { - return !NonWhitespaceRegexp.test(str); -} - -/** - * @typedef {Object} TextLayerBuilderOptions - * @property {HTMLDivElement} textLayerDiv - The text layer container. - * @property {number} pageIndex - The page index. - * @property {PageViewport} viewport - The viewport of the text layer. - * @property {PDFFindController} findController - */ - -/** - * TextLayerBuilder provides text-selection functionality for the PDF. - * It does this by creating overlay divs over the PDF text. These divs - * contain text that matches the PDF text they are overlaying. This object - * also provides a way to highlight text that is being searched for. - * @class - */ -var TextLayerBuilder = (function TextLayerBuilderClosure() { - function TextLayerBuilder(options) { - this.textLayerDiv = options.textLayerDiv; - this.renderingDone = false; - this.divContentDone = false; - this.pageIdx = options.pageIndex; - this.pageNumber = this.pageIdx + 1; - this.matches = []; - this.viewport = options.viewport; - this.textDivs = []; - this.findController = options.findController || null; - } - - TextLayerBuilder.prototype = { - _finishRendering: function TextLayerBuilder_finishRendering() { - this.renderingDone = true; - - var event = document.createEvent('CustomEvent'); - event.initCustomEvent('textlayerrendered', true, true, { - pageNumber: this.pageNumber - }); - this.textLayerDiv.dispatchEvent(event); - }, - - renderLayer: function TextLayerBuilder_renderLayer() { - var textLayerFrag = document.createDocumentFragment(); - var textDivs = this.textDivs; - var textDivsLength = textDivs.length; - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - - // No point in rendering many divs as it would make the browser - // unusable even after the divs are rendered. - if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) { - this._finishRendering(); - return; - } - - var lastFontSize; - var lastFontFamily; - for (var i = 0; i < textDivsLength; i++) { - var textDiv = textDivs[i]; - if (textDiv.dataset.isWhitespace !== undefined) { - continue; - } - - var fontSize = textDiv.style.fontSize; - var fontFamily = textDiv.style.fontFamily; - - // Only build font string and set to context if different from last. - if (fontSize !== lastFontSize || fontFamily !== lastFontFamily) { - ctx.font = fontSize + ' ' + fontFamily; - lastFontSize = fontSize; - lastFontFamily = fontFamily; - } - - var width = ctx.measureText(textDiv.textContent).width; - if (width > 0) { - textLayerFrag.appendChild(textDiv); - var transform; - if (textDiv.dataset.canvasWidth !== undefined) { - // Dataset values come of type string. - var textScale = textDiv.dataset.canvasWidth / width; - transform = 'scaleX(' + textScale + ')'; - } else { - transform = ''; - } - var rotation = textDiv.dataset.angle; - if (rotation) { - transform = 'rotate(' + rotation + 'deg) ' + transform; - } - if (transform) { - CustomStyle.setProp('transform' , textDiv, transform); - } - } - } - - this.textLayerDiv.appendChild(textLayerFrag); - this._finishRendering(); - this.updateMatches(); - }, - - /** - * Renders the text layer. - * @param {number} timeout (optional) if specified, the rendering waits - * for specified amount of ms. - */ - render: function TextLayerBuilder_render(timeout) { - if (!this.divContentDone || this.renderingDone) { - return; - } - - if (this.renderTimer) { - clearTimeout(this.renderTimer); - this.renderTimer = null; - } - - if (!timeout) { // Render right away - this.renderLayer(); - } else { // Schedule - var self = this; - this.renderTimer = setTimeout(function() { - self.renderLayer(); - self.renderTimer = null; - }, timeout); - } - }, - - appendText: function TextLayerBuilder_appendText(geom, styles) { - var style = styles[geom.fontName]; - var textDiv = document.createElement('div'); - this.textDivs.push(textDiv); - if (isAllWhitespace(geom.str)) { - textDiv.dataset.isWhitespace = true; - return; - } - var tx = PDFJS.Util.transform(this.viewport.transform, geom.transform); - var angle = Math.atan2(tx[1], tx[0]); - if (style.vertical) { - angle += Math.PI / 2; - } - var fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3])); - var fontAscent = fontHeight; - if (style.ascent) { - fontAscent = style.ascent * fontAscent; - } else if (style.descent) { - fontAscent = (1 + style.descent) * fontAscent; - } - - var left; - var top; - if (angle === 0) { - left = tx[4]; - top = tx[5] - fontAscent; - } else { - left = tx[4] + (fontAscent * Math.sin(angle)); - top = tx[5] - (fontAscent * Math.cos(angle)); - } - textDiv.style.left = left + 'px'; - textDiv.style.top = top + 'px'; - textDiv.style.fontSize = fontHeight + 'px'; - textDiv.style.fontFamily = style.fontFamily; - - textDiv.textContent = geom.str; - // |fontName| is only used by the Font Inspector. This test will succeed - // when e.g. the Font Inspector is off but the Stepper is on, but it's - // not worth the effort to do a more accurate test. - if (PDFJS.pdfBug) { - textDiv.dataset.fontName = geom.fontName; - } - // Storing into dataset will convert number into string. - if (angle !== 0) { - textDiv.dataset.angle = angle * (180 / Math.PI); - } - // We don't bother scaling single-char text divs, because it has very - // little effect on text highlighting. This makes scrolling on docs with - // lots of such divs a lot faster. - if (textDiv.textContent.length > 1) { - if (style.vertical) { - textDiv.dataset.canvasWidth = geom.height * this.viewport.scale; - } else { - textDiv.dataset.canvasWidth = geom.width * this.viewport.scale; - } - } - }, - - setTextContent: function TextLayerBuilder_setTextContent(textContent) { - this.textContent = textContent; - - var textItems = textContent.items; - for (var i = 0, len = textItems.length; i < len; i++) { - this.appendText(textItems[i], textContent.styles); - } - this.divContentDone = true; - }, - - convertMatches: function TextLayerBuilder_convertMatches(matches) { - var i = 0; - var iIndex = 0; - var bidiTexts = this.textContent.items; - var end = bidiTexts.length - 1; - var queryLen = (this.findController === null ? - 0 : this.findController.state.query.length); - var ret = []; - - for (var m = 0, len = matches.length; m < len; m++) { - // Calculate the start position. - var matchIdx = matches[m]; - - // Loop over the divIdxs. - while (i !== end && matchIdx >= (iIndex + bidiTexts[i].str.length)) { - iIndex += bidiTexts[i].str.length; - i++; - } - - if (i === bidiTexts.length) { - console.error('Could not find a matching mapping'); - } - - var match = { - begin: { - divIdx: i, - offset: matchIdx - iIndex - } - }; - - // Calculate the end position. - matchIdx += queryLen; - - // Somewhat the same array as above, but use > instead of >= to get - // the end position right. - while (i !== end && matchIdx > (iIndex + bidiTexts[i].str.length)) { - iIndex += bidiTexts[i].str.length; - i++; - } - - match.end = { - divIdx: i, - offset: matchIdx - iIndex - }; - ret.push(match); - } - - return ret; - }, - - renderMatches: function TextLayerBuilder_renderMatches(matches) { - // Early exit if there is nothing to render. - if (matches.length === 0) { - return; - } - - var bidiTexts = this.textContent.items; - var textDivs = this.textDivs; - var prevEnd = null; - var pageIdx = this.pageIdx; - var isSelectedPage = (this.findController === null ? - false : (pageIdx === this.findController.selected.pageIdx)); - var selectedMatchIdx = (this.findController === null ? - -1 : this.findController.selected.matchIdx); - var highlightAll = (this.findController === null ? - false : this.findController.state.highlightAll); - var infinity = { - divIdx: -1, - offset: undefined - }; - - function beginText(begin, className) { - var divIdx = begin.divIdx; - textDivs[divIdx].textContent = ''; - appendTextToDiv(divIdx, 0, begin.offset, className); - } - - function appendTextToDiv(divIdx, fromOffset, toOffset, className) { - var div = textDivs[divIdx]; - var content = bidiTexts[divIdx].str.substring(fromOffset, toOffset); - var node = document.createTextNode(content); - if (className) { - var span = document.createElement('span'); - span.className = className; - span.appendChild(node); - div.appendChild(span); - return; - } - div.appendChild(node); - } - - var i0 = selectedMatchIdx, i1 = i0 + 1; - if (highlightAll) { - i0 = 0; - i1 = matches.length; - } else if (!isSelectedPage) { - // Not highlighting all and this isn't the selected page, so do nothing. - return; - } - - for (var i = i0; i < i1; i++) { - var match = matches[i]; - var begin = match.begin; - var end = match.end; - var isSelected = (isSelectedPage && i === selectedMatchIdx); - var highlightSuffix = (isSelected ? ' selected' : ''); - - if (this.findController) { - this.findController.updateMatchPosition(pageIdx, i, textDivs, - begin.divIdx, end.divIdx); - } - - // Match inside new div. - if (!prevEnd || begin.divIdx !== prevEnd.divIdx) { - // If there was a previous div, then add the text at the end. - if (prevEnd !== null) { - appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); - } - // Clear the divs and set the content until the starting point. - beginText(begin); - } else { - appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset); - } - - if (begin.divIdx === end.divIdx) { - appendTextToDiv(begin.divIdx, begin.offset, end.offset, - 'highlight' + highlightSuffix); - } else { - appendTextToDiv(begin.divIdx, begin.offset, infinity.offset, - 'highlight begin' + highlightSuffix); - for (var n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) { - textDivs[n0].className = 'highlight middle' + highlightSuffix; - } - beginText(end, 'highlight end' + highlightSuffix); - } - prevEnd = end; - } - - if (prevEnd) { - appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); - } - }, - - updateMatches: function TextLayerBuilder_updateMatches() { - // Only show matches when all rendering is done. - if (!this.renderingDone) { - return; - } - - // Clear all matches. - var matches = this.matches; - var textDivs = this.textDivs; - var bidiTexts = this.textContent.items; - var clearedUntilDivIdx = -1; - - // Clear all current matches. - for (var i = 0, len = matches.length; i < len; i++) { - var match = matches[i]; - var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx); - for (var n = begin, end = match.end.divIdx; n <= end; n++) { - var div = textDivs[n]; - div.textContent = bidiTexts[n].str; - div.className = ''; - } - clearedUntilDivIdx = match.end.divIdx + 1; - } - - if (this.findController === null || !this.findController.active) { - return; - } - - // Convert the matches on the page controller into the match format - // used for the textLayer. - this.matches = this.convertMatches(this.findController === null ? - [] : (this.findController.pageMatches[this.pageIdx] || [])); - this.renderMatches(this.matches); - } - }; - return TextLayerBuilder; -})(); - -/** - * @constructor - * @implements IPDFTextLayerFactory - */ -function DefaultTextLayerFactory() {} -DefaultTextLayerFactory.prototype = { - /** - * @param {HTMLDivElement} textLayerDiv - * @param {number} pageIndex - * @param {PageViewport} viewport - * @returns {TextLayerBuilder} - */ - createTextLayerBuilder: function (textLayerDiv, pageIndex, viewport) { - return new TextLayerBuilder({ - textLayerDiv: textLayerDiv, - pageIndex: pageIndex, - viewport: viewport - }); - } -}; diff --git a/plugins/pdf_viewer/v/ui_utils.js b/plugins/pdf_viewer/v/ui_utils.js deleted file mode 100755 index 7e798e3..0000000 --- a/plugins/pdf_viewer/v/ui_utils.js +++ /dev/null @@ -1,394 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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. - */ - -'use strict'; - -var CSS_UNITS = 96.0 / 72.0; -var DEFAULT_SCALE = 'auto'; -var UNKNOWN_SCALE = 0; -var MAX_AUTO_SCALE = 1.25; -var SCROLLBAR_PADDING = 40; -var VERTICAL_PADDING = 5; - -// optimised CSS custom property getter/setter -var CustomStyle = (function CustomStyleClosure() { - - // As noted on: http://www.zachstronaut.com/posts/2009/02/17/ - // animate-css-transforms-firefox-webkit.html - // in some versions of IE9 it is critical that ms appear in this list - // before Moz - var prefixes = ['ms', 'Moz', 'Webkit', 'O']; - var _cache = {}; - - function CustomStyle() {} - - CustomStyle.getProp = function get(propName, element) { - // check cache only when no element is given - if (arguments.length === 1 && typeof _cache[propName] === 'string') { - return _cache[propName]; - } - - element = element || document.documentElement; - var style = element.style, prefixed, uPropName; - - // test standard property first - if (typeof style[propName] === 'string') { - return (_cache[propName] = propName); - } - - // capitalize - uPropName = propName.charAt(0).toUpperCase() + propName.slice(1); - - // test vendor specific properties - for (var i = 0, l = prefixes.length; i < l; i++) { - prefixed = prefixes[i] + uPropName; - if (typeof style[prefixed] === 'string') { - return (_cache[propName] = prefixed); - } - } - - //if all fails then set to undefined - return (_cache[propName] = 'undefined'); - }; - - CustomStyle.setProp = function set(propName, element, str) { - var prop = this.getProp(propName); - if (prop !== 'undefined') { - element.style[prop] = str; - } - }; - - return CustomStyle; -})(); - -function getFileName(url) { - var anchor = url.indexOf('#'); - var query = url.indexOf('?'); - var end = Math.min( - anchor > 0 ? anchor : url.length, - query > 0 ? query : url.length); - return url.substring(url.lastIndexOf('/', end) + 1, end); -} - -/** - * Returns scale factor for the canvas. It makes sense for the HiDPI displays. - * @return {Object} The object with horizontal (sx) and vertical (sy) - scales. The scaled property is set to false if scaling is - not required, true otherwise. - */ -function getOutputScale(ctx) { - var devicePixelRatio = window.devicePixelRatio || 1; - var backingStoreRatio = ctx.webkitBackingStorePixelRatio || - ctx.mozBackingStorePixelRatio || - ctx.msBackingStorePixelRatio || - ctx.oBackingStorePixelRatio || - ctx.backingStorePixelRatio || 1; - var pixelRatio = devicePixelRatio / backingStoreRatio; - return { - sx: pixelRatio, - sy: pixelRatio, - scaled: pixelRatio !== 1 - }; -} - -/** - * Scrolls specified element into view of its parent. - * element {Object} The element to be visible. - * spot {Object} An object with optional top and left properties, - * specifying the offset from the top left edge. - */ -function scrollIntoView(element, spot) { - // Assuming offsetParent is available (it's not available when viewer is in - // hidden iframe or object). We have to scroll: if the offsetParent is not set - // producing the error. See also animationStartedClosure. - var parent = element.offsetParent; - var offsetY = element.offsetTop + element.clientTop; - var offsetX = element.offsetLeft + element.clientLeft; - if (!parent) { - console.error('offsetParent is not set -- cannot scroll'); - return; - } - while (parent.clientHeight === parent.scrollHeight) { - if (parent.dataset._scaleY) { - offsetY /= parent.dataset._scaleY; - offsetX /= parent.dataset._scaleX; - } - offsetY += parent.offsetTop; - offsetX += parent.offsetLeft; - parent = parent.offsetParent; - if (!parent) { - return; // no need to scroll - } - } - if (spot) { - if (spot.top !== undefined) { - offsetY += spot.top; - } - if (spot.left !== undefined) { - offsetX += spot.left; - parent.scrollLeft = offsetX; - } - } - parent.scrollTop = offsetY; -} - -/** - * Helper function to start monitoring the scroll event and converting them into - * PDF.js friendly one: with scroll debounce and scroll direction. - */ -function watchScroll(viewAreaElement, callback) { - var debounceScroll = function debounceScroll(evt) { - if (rAF) { - return; - } - // schedule an invocation of scroll for next animation frame. - rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { - rAF = null; - - var currentY = viewAreaElement.scrollTop; - var lastY = state.lastY; - if (currentY !== lastY) { - state.down = currentY > lastY; - } - state.lastY = currentY; - callback(state); - }); - }; - - var state = { - down: true, - lastY: viewAreaElement.scrollTop, - _eventHandler: debounceScroll - }; - - var rAF = null; - viewAreaElement.addEventListener('scroll', debounceScroll, true); - return state; -} - -/** - * Use binary search to find the index of the first item in a given array which - * passes a given condition. The items are expected to be sorted in the sense - * that if the condition is true for one item in the array, then it is also true - * for all following items. - * - * @returns {Number} Index of the first array element to pass the test, - * or |items.length| if no such element exists. - */ -function binarySearchFirstItem(items, condition) { - var minIndex = 0; - var maxIndex = items.length - 1; - - if (items.length === 0 || !condition(items[maxIndex])) { - return items.length; - } - if (condition(items[minIndex])) { - return minIndex; - } - - while (minIndex < maxIndex) { - var currentIndex = (minIndex + maxIndex) >> 1; - var currentItem = items[currentIndex]; - if (condition(currentItem)) { - maxIndex = currentIndex; - } else { - minIndex = currentIndex + 1; - } - } - return minIndex; /* === maxIndex */ -} - -/** - * Generic helper to find out what elements are visible within a scroll pane. - */ -function getVisibleElements(scrollEl, views, sortByVisibility) { - var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight; - var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth; - - function isElementBottomBelowViewTop(view) { - var element = view.div; - var elementBottom = - element.offsetTop + element.clientTop + element.clientHeight; - return elementBottom > top; - } - - var visible = [], view, element; - var currentHeight, viewHeight, hiddenHeight, percentHeight; - var currentWidth, viewWidth; - var firstVisibleElementInd = (views.length === 0) ? 0 : - binarySearchFirstItem(views, isElementBottomBelowViewTop); - - for (var i = firstVisibleElementInd, ii = views.length; i < ii; i++) { - view = views[i]; - element = view.div; - currentHeight = element.offsetTop + element.clientTop; - viewHeight = element.clientHeight; - - if (currentHeight > bottom) { - break; - } - - currentWidth = element.offsetLeft + element.clientLeft; - viewWidth = element.clientWidth; - if (currentWidth + viewWidth < left || currentWidth > right) { - continue; - } - hiddenHeight = Math.max(0, top - currentHeight) + - Math.max(0, currentHeight + viewHeight - bottom); - percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0; - - visible.push({ - id: view.id, - x: currentWidth, - y: currentHeight, - view: view, - percent: percentHeight - }); - } - - var first = visible[0]; - var last = visible[visible.length - 1]; - - if (sortByVisibility) { - visible.sort(function(a, b) { - var pc = a.percent - b.percent; - if (Math.abs(pc) > 0.001) { - return -pc; - } - return a.id - b.id; // ensure stability - }); - } - return {first: first, last: last, views: visible}; -} - -/** - * Event handler to suppress context menu. - */ -function noContextMenuHandler(e) { - e.preventDefault(); -} - -/** - * Returns the filename or guessed filename from the url (see issue 3455). - * url {String} The original PDF location. - * @return {String} Guessed PDF file name. - */ -function getPDFFileNameFromURL(url) { - var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/; - // SCHEME HOST 1.PATH 2.QUERY 3.REF - // Pattern to get last matching NAME.pdf - var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i; - var splitURI = reURI.exec(url); - var suggestedFilename = reFilename.exec(splitURI[1]) || - reFilename.exec(splitURI[2]) || - reFilename.exec(splitURI[3]); - if (suggestedFilename) { - suggestedFilename = suggestedFilename[0]; - if (suggestedFilename.indexOf('%') !== -1) { - // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf - try { - suggestedFilename = - reFilename.exec(decodeURIComponent(suggestedFilename))[0]; - } catch(e) { // Possible (extremely rare) errors: - // URIError "Malformed URI", e.g. for "%AA.pdf" - // TypeError "null has no properties", e.g. for "%2F.pdf" - } - } - } - return suggestedFilename || 'document.pdf'; -} - -var ProgressBar = (function ProgressBarClosure() { - - function clamp(v, min, max) { - return Math.min(Math.max(v, min), max); - } - - function ProgressBar(id, opts) { - this.visible = true; - - // Fetch the sub-elements for later. - this.div = document.querySelector(id + ' .progress'); - - // Get the loading bar element, so it can be resized to fit the viewer. - this.bar = this.div.parentNode; - - // Get options, with sensible defaults. - this.height = opts.height || 100; - this.width = opts.width || 100; - this.units = opts.units || '%'; - - // Initialize heights. - this.div.style.height = this.height + this.units; - this.percent = 0; - } - - ProgressBar.prototype = { - - updateBar: function ProgressBar_updateBar() { - if (this._indeterminate) { - this.div.classList.add('indeterminate'); - this.div.style.width = this.width + this.units; - return; - } - - this.div.classList.remove('indeterminate'); - var progressSize = this.width * this._percent / 100; - this.div.style.width = progressSize + this.units; - }, - - get percent() { - return this._percent; - }, - - set percent(val) { - this._indeterminate = isNaN(val); - this._percent = clamp(val, 0, 100); - this.updateBar(); - }, - - setWidth: function ProgressBar_setWidth(viewer) { - if (viewer) { - var container = viewer.parentNode; - var scrollbarWidth = container.offsetWidth - viewer.offsetWidth; - if (scrollbarWidth > 0) { - this.bar.setAttribute('style', 'width: calc(100% - ' + - scrollbarWidth + 'px);'); - } - } - }, - - hide: function ProgressBar_hide() { - if (!this.visible) { - return; - } - this.visible = false; - this.bar.classList.add('hidden'); - document.body.classList.remove('loadingInProgress'); - }, - - show: function ProgressBar_show() { - if (this.visible) { - return; - } - this.visible = true; - document.body.classList.add('loadingInProgress'); - this.bar.classList.remove('hidden'); - } - }; - - return ProgressBar; -})(); diff --git a/plugins/pdf_viewer/v/webodf.js b/plugins/pdf_viewer/v/webodf.js deleted file mode 100755 index dbb0d33..0000000 --- a/plugins/pdf_viewer/v/webodf.js +++ /dev/null @@ -1,936 +0,0 @@ -/* - - This is a generated file. DO NOT EDIT. - - Copyright (C) 2010-2015 KO GmbH - - @licstart - The code in this file is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License (GNU AGPL) - as published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - The code in this file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with WebODF. If not, see . - - As additional permission under GNU AGPL version 3 section 7, you - may distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU AGPL normally - required by section 4, provided you include this license notice and a URL - through which recipients can access the Corresponding Source. - - As a special exception to the AGPL, any HTML file which merely makes function - calls to this code, and for that purpose includes it in unmodified form by reference or in-line shall be - deemed a separate work for copyright law purposes. In addition, the copyright - holders of this code give you permission to combine this code with free - software libraries that are released under the GNU LGPL. You may copy and - distribute such a system following the terms of the GNU AGPL for this code - and the LGPL for the libraries. If you modify this code, you may extend this - exception to your version of the code, but you are not obligated to do so. - If you do not wish to do so, delete this exception statement from your - version. - - This license applies to this entire compilation. - @licend - - @source: http://www.webodf.org/ - @source: https://github.com/kogmbh/WebODF/ -*/ -var webodf_version="0.5.8";function Runtime(){}Runtime.prototype.getVariable=function(g){};Runtime.prototype.toJson=function(g){};Runtime.prototype.fromJson=function(g){};Runtime.prototype.byteArrayFromString=function(g,k){};Runtime.prototype.byteArrayToString=function(g,k){};Runtime.prototype.read=function(g,k,c,b){};Runtime.prototype.readFile=function(g,k,c){};Runtime.prototype.readFileSync=function(g,k){};Runtime.prototype.loadXML=function(g,k){};Runtime.prototype.writeFile=function(g,k,c){}; -Runtime.prototype.deleteFile=function(g,k){};Runtime.prototype.log=function(g,k){};Runtime.prototype.setTimeout=function(g,k){};Runtime.prototype.clearTimeout=function(g){};Runtime.prototype.libraryPaths=function(){};Runtime.prototype.currentDirectory=function(){};Runtime.prototype.setCurrentDirectory=function(g){};Runtime.prototype.type=function(){};Runtime.prototype.getDOMImplementation=function(){};Runtime.prototype.parseXML=function(g){};Runtime.prototype.exit=function(g){}; -Runtime.prototype.getWindow=function(){};Runtime.prototype.requestAnimationFrame=function(g){};Runtime.prototype.cancelAnimationFrame=function(g){};Runtime.prototype.assert=function(g,k){};var IS_COMPILED_CODE=!0; -Runtime.byteArrayToString=function(g,k){function c(b){var c="",r,q=b.length;for(r=0;rl?e.push(l):(r+=1,a=b[r],194<=l&&224>l?e.push((l&31)<<6|a&63):(r+=1,d=b[r],224<=l&&240>l?e.push((l&15)<<12|(a&63)<<6|d&63):(r+=1,m=b[r],240<=l&&245>l&&(l=(l&7)<<18|(a&63)<<12|(d&63)<<6|m&63,l-=65536,e.push((l>>10)+55296,(l&1023)+56320))))),1E3<=e.length&& -(c+=String.fromCharCode.apply(null,e),e.length=0);return c+String.fromCharCode.apply(null,e)}var f;"utf8"===k?f=b(g):("binary"!==k&&this.log("Unsupported encoding: "+k),f=c(g));return f};Runtime.getVariable=function(g){try{return eval(g)}catch(k){}};Runtime.toJson=function(g){return JSON.stringify(g)};Runtime.fromJson=function(g){return JSON.parse(g)};Runtime.getFunctionName=function(g){return void 0===g.name?(g=/function\s+(\w+)/.exec(g))&&g[1]:g.name}; -Runtime.assert=function(g,k){if(!g)throw this.log("alert","ASSERTION FAILED:\n"+k),Error(k);}; -function BrowserRuntime(){function g(b){var e=b.length,l,a,d=0;for(l=0;la&&(d+=1,l+=1);return d}function k(b,e,l){var a=b.length,d,m;e=new Uint8Array(new ArrayBuffer(e));l?(e[0]=239,e[1]=187,e[2]=191,m=3):m=0;for(l=0;ld?(e[m]=d,m+=1):2048>d?(e[m]=192|d>>>6,e[m+1]=128|d&63,m+=2):55040>=d||57344<=d?(e[m]=224|d>>>12&15,e[m+1]=128|d>>>6&63,e[m+2]=128|d&63,m+=3):(l+=1,d=(d-55296<<10|b.charCodeAt(l)-56320)+65536, -e[m]=240|d>>>18&7,e[m+1]=128|d>>>12&63,e[m+2]=128|d>>>6&63,e[m+3]=128|d&63,m+=4);return e}function c(b){var e=b.length,l=new Uint8Array(new ArrayBuffer(e)),a;for(a=0;aa.status||0===a.status?l(null):l("Status "+String(a.status)+": "+a.responseText||a.statusText):l("File "+b+" is empty."))};d=e.buffer&&!a.sendAsBinary?e.buffer:r.byteArrayToString(e,"binary");try{a.sendAsBinary?a.sendAsBinary(d):a.send(d)}catch(m){r.log("HUH? "+ -m+" "+e),l(m.message)}};this.deleteFile=function(b,e){var l=new XMLHttpRequest;l.open("DELETE",b,!0);l.onreadystatechange=function(){4===l.readyState&&(200>l.status&&300<=l.status?e(l.responseText):e(null))};l.send(null)};this.loadXML=function(b,e){var l=new XMLHttpRequest;l.open("GET",b,!0);l.overrideMimeType&&l.overrideMimeType("text/xml");l.onreadystatechange=function(){4===l.readyState&&(0!==l.status||l.responseText?200===l.status||0===l.status?e(null,l.responseXML):e(l.responseText,null):e("File "+ -b+" is empty.",null))};try{l.send(null)}catch(a){e(a.message,null)}};this.log=b;this.enableAlerts=!0;this.assert=Runtime.assert;this.setTimeout=function(b,e){return setTimeout(function(){b()},e)};this.clearTimeout=function(b){clearTimeout(b)};this.libraryPaths=function(){return["lib"]};this.setCurrentDirectory=function(){};this.currentDirectory=function(){return""};this.type=function(){return"BrowserRuntime"};this.getDOMImplementation=function(){return window.document.implementation};this.parseXML= -function(b){return(new DOMParser).parseFromString(b,"text/xml")};this.exit=function(c){b("Calling exit with code "+String(c)+", but exit() is not implemented.")};this.getWindow=function(){return window};this.requestAnimationFrame=function(b){var e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame,l=0;if(e)e.bind(window),l=e(b);else return setTimeout(b,15);return l};this.cancelAnimationFrame=function(b){var e=window.cancelAnimationFrame|| -window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.msCancelAnimationFrame;e?(e.bind(window),e(b)):clearTimeout(b)}} -function NodeJSRuntime(){function g(b){var e=b.length,l,a=new Uint8Array(new ArrayBuffer(e));for(l=0;l").implementation} -function RhinoRuntime(){var g=this,k={},c=k.javax.xml.parsers.DocumentBuilderFactory.newInstance(),b,f,n="";c.setValidating(!1);c.setNamespaceAware(!0);c.setExpandEntityReferences(!1);c.setSchema(null);f=k.org.xml.sax.EntityResolver({resolveEntity:function(b,c){var f=new k.java.io.FileReader(c);return new k.org.xml.sax.InputSource(f)}});b=c.newDocumentBuilder();b.setEntityResolver(f);this.byteArrayFromString=function(b,c){var f,e=b.length,l=new Uint8Array(new ArrayBuffer(e));for(f=0;f>>18],m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d>>>12&63],m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d>>>6&63],m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d& -63];h===b+1?(d=a[h]<<4,m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d>>>6],m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d&63],m+="=="):h===b&&(d=a[h]<<10|a[h+1]<<2,m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d>>>12],m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d>>>6&63],m+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[d&63],m+="=");return m}function c(a){a=a.replace(/[^A-Za-z0-9+\/]+/g, -"");var d=a.length,m=new Uint8Array(new ArrayBuffer(3*d)),b=a.length%4,c=0,l,e;for(l=0;l>16,m[c+1]=e>>8&255,m[c+2]=e&255,c+=3;d=3*d-[0,0,2,1][b];return m.subarray(0,d)}function b(a){var d,m,h=a.length,b=0,c=new Uint8Array(new ArrayBuffer(3*h));for(d=0;dm?c[b++]=m:(2048>m?c[b++]=192|m>>>6:(c[b++]=224|m>>>12&15,c[b++]=128|m>>>6&63),c[b++]=128|m&63);return c.subarray(0, -b)}function f(a){var d,m,h,b,c=a.length,l=new Uint8Array(new ArrayBuffer(c)),e=0;for(d=0;dm?l[e++]=m:(d+=1,h=a[d],224>m?l[e++]=(m&31)<<6|h&63:(d+=1,b=a[d],l[e++]=(m&15)<<12|(h&63)<<6|b&63));return l.subarray(0,e)}function n(a){return k(g(a))}function p(a){return String.fromCharCode.apply(String,c(a))}function r(a){return f(g(a))}function q(a){a=f(a);for(var d="",m=0;md?l+=String.fromCharCode(d):(c+=1,h=a.charCodeAt(c)&255,224>d?l+=String.fromCharCode((d&31)<<6|h&63):(c+=1,b=a.charCodeAt(c)&255,l+=String.fromCharCode((d&15)<<12|(h&63)<<6|b&63)));return l}function l(a,d){function m(){var c=b+1E5;c>a.length&&(c=a.length);h+=e(a,b,c);b=c;c=b===a.length;d(h,c)&&!c&&runtime.setTimeout(m,0)}var h="",b=0;1E5>a.length?d(e(a,0,a.length),!0):("string"!==typeof a&&(a=a.slice()),m())}function a(a){return b(g(a))}function d(a){return String.fromCharCode.apply(String, -b(a))}function m(a){return String.fromCharCode.apply(String,b(g(a)))}var h=function(a){var d={},m,h;m=0;for(h=a.length;m=a.compareBoundaryPoints(Range.START_TO_START,d)&&0<=a.compareBoundaryPoints(Range.END_TO_END,d)}function n(a,d){return 0>=a.compareBoundaryPoints(Range.END_TO_START,d)&&0<=a.compareBoundaryPoints(Range.START_TO_END,d)}function p(a,d){var b=null;a.nodeType===Node.TEXT_NODE&&(0===a.length?(a.parentNode.removeChild(a),d.nodeType===Node.TEXT_NODE&&(b=d)):(d.nodeType===Node.TEXT_NODE&&(a.appendData(d.data),d.parentNode.removeChild(d)),b=a));return b} -function r(a){for(var d=a.parentNode;a.firstChild;)d.insertBefore(a.firstChild,a);d.removeChild(a);return d}function q(a,d){var b=a.parentNode,c=a.firstChild,l=d(a),e;if(l===NodeFilter.FILTER_SKIP)return b;for(;c;)e=c.nextSibling,q(c,d),c=e;b&&l===NodeFilter.FILTER_REJECT&&r(a);return b}function e(a,d){return a===d||Boolean(a.compareDocumentPosition(d)&Node.DOCUMENT_POSITION_CONTAINED_BY)}function l(a,d){return g().unscaledRangeClientRects?a:a/d}function a(d,h,b){Object.keys(h).forEach(function(c){var l= -c.split(":"),e=l[1],f=b(l[0]),l=h[c],n=typeof l;"object"===n?Object.keys(l).length&&(c=f?d.getElementsByTagNameNS(f,e)[0]||d.ownerDocument.createElementNS(f,c):d.getElementsByTagName(e)[0]||d.ownerDocument.createElement(c),d.appendChild(c),a(c,l,b)):f&&(runtime.assert("number"===n||"string"===n,"attempting to map unsupported type '"+n+"' (key: "+c+")"),d.setAttributeNS(f,c,String(l)))})}var d=null;this.splitBoundaries=function(a){var d,c=[],l,e,f;if(a.startContainer.nodeType===Node.TEXT_NODE||a.endContainer.nodeType=== -Node.TEXT_NODE){l=a.endContainer;e=a.endContainer.nodeType!==Node.TEXT_NODE?a.endOffset===a.endContainer.childNodes.length:!1;f=a.endOffset;d=a.endContainer;if(fg))throw runtime.log("alert","watchdog timeout"),"timeout!";if(0k))throw runtime.log("alert","watchdog loop overflow"),"loop overflow";}};core.NodeFilterChain=function(g){var k=NodeFilter.FILTER_REJECT,c=NodeFilter.FILTER_ACCEPT;this.acceptNode=function(b){var f;for(f=0;f "+d.length),runtime.assert(0<=b,"Error in setPosition: "+b+" < 0"),b===d.length&&(l.nextSibling()?a=0:l.parentNode()?a=1:runtime.assert(!1,"Error in setUnfilteredPosition: position not valid."))):ba.value||"%"===a.unit)?null:a}function L(a){return(a=I(a))&&"%"!==a.unit?null:a}function E(a){switch(a.namespaceURI){case odf.Namespaces.drawns:case odf.Namespaces.svgns:case odf.Namespaces.dr3dns:return!1;case odf.Namespaces.textns:switch(a.localName){case "note-body":case "ruby-text":return!1}break;case odf.Namespaces.officens:switch(a.localName){case "annotation":case "binary-data":case "event-listeners":return!1}break;default:switch(a.localName){case "cursor":case "editinfo":return!1}}return!0} -function N(a){return Boolean(n(a)&&(!r(a.textContent)||A(a,0)))}function O(a,d){for(;0=d.value||"%"===d.unit)?null:d;return d||L(a)};this.parseFoLineHeight= -function(a){return K(a)||L(a)};this.isTextContentContainingNode=E;this.getTextNodes=function(a,d){var b;b=aa.getNodesInRange(a,function(a){var d=NodeFilter.FILTER_REJECT;a.nodeType===Node.TEXT_NODE?N(a)&&(d=NodeFilter.FILTER_ACCEPT):E(a)&&(d=NodeFilter.FILTER_SKIP);return d},NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);d||O(a,b);return b};this.getTextElements=D;this.getParagraphElements=function(a){var d;d=aa.getNodesInRange(a,function(a){var d=NodeFilter.FILTER_REJECT;if(f(a))d=NodeFilter.FILTER_ACCEPT; -else if(E(a)||q(a))d=NodeFilter.FILTER_SKIP;return d},NodeFilter.SHOW_ELEMENT);V(a.startContainer,d,f);return d};this.getImageElements=function(a){var d;d=aa.getNodesInRange(a,function(a){var d=NodeFilter.FILTER_SKIP;g(a)&&(d=NodeFilter.FILTER_ACCEPT);return d},NodeFilter.SHOW_ELEMENT);V(a.startContainer,d,g);return d};this.getHyperlinkElements=function(a){var d=[],c=a.cloneRange();a.collapsed&&a.endContainer.nodeType===Node.ELEMENT_NODE&&(a=W(a.endContainer,a.endOffset),a.nodeType===Node.TEXT_NODE&& -c.setEnd(a,1));D(c,!0,!1).forEach(function(a){for(a=a.parentNode;!f(a);){if(b(a)&&-1===d.indexOf(a)){d.push(a);break}a=a.parentNode}});c.detach();return d};this.getNormalizedFontFamilyName=function(a){/^(["'])(?:.|[\n\r])*?\1$/.test(a)||(a=a.replace(/^[ \t\r\n\f]*((?:.|[\n\r])*?)[ \t\r\n\f]*$/,"$1"),/[ \t\r\n\f]/.test(a)&&(a="'"+a.replace(/[ \t\r\n\f]+/g," ")+"'"));return a}};odf.OdfUtils=new odf.OdfUtilsImpl; -gui.OdfTextBodyNodeFilter=function(){var g=odf.OdfUtils,k=Node.TEXT_NODE,c=NodeFilter.FILTER_REJECT,b=NodeFilter.FILTER_ACCEPT,f=odf.Namespaces.textns;this.acceptNode=function(n){if(n.nodeType===k){if(!g.isGroupingElement(n.parentNode))return c}else if(n.namespaceURI===f&&"tracked-changes"===n.localName)return c;return b}};xmldom.LSSerializerFilter=function(){};xmldom.LSSerializerFilter.prototype.acceptNode=function(g){}; -odf.OdfNodeFilter=function(){this.acceptNode=function(g){return"http://www.w3.org/1999/xhtml"===g.namespaceURI?NodeFilter.FILTER_SKIP:g.namespaceURI&&g.namespaceURI.match(/^urn:webodf:/)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}};xmldom.XPathIterator=function(){};xmldom.XPathIterator.prototype.next=function(){};xmldom.XPathIterator.prototype.reset=function(){}; -function createXPathSingleton(){function g(b,a,d){return-1!==b&&(b=e&&d.push(k(b.substring(a,c)))):"["===b[c]&&(0>=e&&(a=c+1),e+=1),c+=1;return c};q=function(c,a,d){var m,h,e,n;for(m=0;m/g,">").replace(/'/g,"'").replace(/"/g,""")}function c(f,n){var g="",r=b.filter?b.filter.acceptNode(n):NodeFilter.FILTER_ACCEPT,q;if(r===NodeFilter.FILTER_ACCEPT&&n.nodeType===Node.ELEMENT_NODE){f.push();q=f.getQName(n);var e,l=n.attributes,a,d,m,h="",y;e="<"+q;a=l.length;for(d=0;d")}if(r===NodeFilter.FILTER_ACCEPT||r===NodeFilter.FILTER_SKIP){for(r=n.firstChild;r;)g+=c(f,r),r=r.nextSibling;n.nodeValue&&(g+=k(n.nodeValue))}q&&(g+="",f.pop());return g}var b=this;this.filter=null;this.writeToString=function(b,n){if(!b)return"";var k=new g(n);return c(k,b)}}; -(function(){function g(b){var a,d=r.length;for(a=0;ad)break;h=h.nextSibling}b.insertBefore(a,h)}}}var f=new odf.StyleInfo,n=core.DomUtils,p=odf.Namespaces.stylens,r="meta settings scripts font-face-decls styles automatic-styles master-styles body".split(" "), -q=Date.now()+"_webodf_",e=new core.Base64;odf.ODFElement=function(){};odf.ODFDocumentElement=function(){};odf.ODFDocumentElement.prototype=new odf.ODFElement;odf.ODFDocumentElement.prototype.constructor=odf.ODFDocumentElement;odf.ODFDocumentElement.prototype.fontFaceDecls=null;odf.ODFDocumentElement.prototype.manifest=null;odf.ODFDocumentElement.prototype.settings=null;odf.ODFDocumentElement.namespaceURI="urn:oasis:names:tc:opendocument:xmlns:office:1.0";odf.ODFDocumentElement.localName="document"; -odf.AnnotationElement=function(){};odf.OdfPart=function(b,a,d,c){var h=this;this.size=0;this.type=null;this.name=b;this.container=d;this.url=null;this.mimetype=a;this.onstatereadychange=this.document=null;this.EMPTY=0;this.LOADING=1;this.DONE=2;this.state=this.EMPTY;this.data="";this.load=function(){null!==c&&(this.mimetype=a,c.loadAsDataURL(b,a,function(a,d){a&&runtime.log(a);h.url=d;if(h.onchange)h.onchange(h);if(h.onstatereadychange)h.onstatereadychange(h)}))}};odf.OdfPart.prototype.load=function(){}; -odf.OdfPart.prototype.getUrl=function(){return this.data?"data:;base64,"+e.toBase64(this.data):null};odf.OdfContainer=function a(d,m){function h(a){for(var d=a.firstChild,b;d;)b=d.nextSibling,d.nodeType===Node.ELEMENT_NODE?h(d):d.nodeType===Node.PROCESSING_INSTRUCTION_NODE&&a.removeChild(d),d=b}function g(a){var d={},b,c,h=a.ownerDocument.createNodeIterator(a,NodeFilter.SHOW_ELEMENT,null,!1);for(a=h.nextNode();a;)"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&("annotation"=== -a.localName?(b=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","name"))&&(d.hasOwnProperty(b)?runtime.log("Warning: annotation name used more than once with : '"+b+"'"):d[b]=a):"annotation-end"===a.localName&&((b=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","name"))?d.hasOwnProperty(b)?(c=d[b],c.annotationEndElement?runtime.log("Warning: annotation name used more than once with : '"+b+"'"):c.annotationEndElement= -a):runtime.log("Warning: annotation end without an annotation start, name: '"+b+"'"):runtime.log("Warning: annotation end without a name found"))),a=h.nextNode()}function r(a,d){for(var b=a&&a.firstChild;b;)b.nodeType===Node.ELEMENT_NODE&&b.setAttributeNS("urn:webodf:names:scope","scope",d),b=b.nextSibling}function z(a,d){for(var b=B.rootElement.meta,b=b&&b.firstChild;b&&(b.namespaceURI!==a||b.localName!==d);)b=b.nextSibling;for(b=b&&b.firstChild;b&&b.nodeType!==Node.TEXT_NODE;)b=b.nextSibling;return b? -b.data:null}function w(a){var d={},b;for(a=a.firstChild;a;)a.nodeType===Node.ELEMENT_NODE&&a.namespaceURI===p&&"font-face"===a.localName&&(b=a.getAttributeNS(p,"name"),d[b]=a),a=a.nextSibling;return d}function v(a,d){var b=null,c,h,e;if(a)for(b=a.cloneNode(!0),c=b.firstElementChild;c;)h=c.nextElementSibling,(e=c.getAttributeNS("urn:webodf:names:scope","scope"))&&e!==d&&b.removeChild(c),c=h;return b}function u(a,d){var b,c,h,e=null,m={};if(a)for(d.forEach(function(a){f.collectUsedFontFaces(m,a)}), -e=a.cloneNode(!0),b=e.firstElementChild;b;)c=b.nextElementSibling,h=b.getAttributeNS(p,"name"),m[h]||e.removeChild(b),b=c;return e}function t(a){var d=B.rootElement.ownerDocument,b;if(a){h(a.documentElement);try{b=d.importNode(a.documentElement,!0)}catch(c){}}return b}function A(a){B.state=a;if(B.onchange)B.onchange(B);if(B.onstatereadychange)B.onstatereadychange(B)}function I(a){Q=null;B.rootElement=a;a.fontFaceDecls=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"); -a.styles=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles");a.automaticStyles=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");a.masterStyles=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles");a.body=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");a.meta=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta");a.settings=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"settings");a.scripts=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","scripts");g(a)}function K(d){var c=t(d),h=B.rootElement,e;c&&"document-styles"===c.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===c.namespaceURI?(h.fontFaceDecls=n.getDirectChild(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls"),b(h,h.fontFaceDecls),e=n.getDirectChild(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","styles"),h.styles=e||d.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0", -"styles"),b(h,h.styles),e=n.getDirectChild(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),h.automaticStyles=e||d.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles"),r(h.automaticStyles,"document-styles"),b(h,h.automaticStyles),c=n.getDirectChild(c,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),h.masterStyles=c||d.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","master-styles"),b(h,h.masterStyles), -f.prefixStyleNames(h.automaticStyles,q,h.masterStyles)):A(a.INVALID)}function L(d){d=t(d);var c,h,e,m;if(d&&"document-content"===d.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===d.namespaceURI){c=B.rootElement;e=n.getDirectChild(d,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","font-face-decls");if(c.fontFaceDecls&&e){m=c.fontFaceDecls;var g,k,O,q,D={};h=w(m);q=w(e);for(e=e.firstElementChild;e;){g=e.nextElementSibling;if(e.namespaceURI===p&&"font-face"===e.localName)if(k=e.getAttributeNS(p, -"name"),h.hasOwnProperty(k)){if(!e.isEqualNode(h[k])){O=k;for(var y=h,E=q,u=0,W=void 0,W=O=O.replace(/\d+$/,"");y.hasOwnProperty(W)||E.hasOwnProperty(W);)u+=1,W=O+u;O=W;e.setAttributeNS(p,"style:name",O);m.appendChild(e);h[O]=e;delete q[k];D[k]=O}}else m.appendChild(e),h[k]=e,delete q[k];e=g}m=D}else e&&(c.fontFaceDecls=e,b(c,e));h=n.getDirectChild(d,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","automatic-styles");r(h,"document-content");m&&f.changeFontFaceNames(h,m);if(c.automaticStyles&&h)for(m= -h.firstChild;m;)c.automaticStyles.appendChild(m),m=h.firstChild;else h&&(c.automaticStyles=h,b(c,h));d=n.getDirectChild(d,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","body");if(null===d)throw" tag is mising.";c.body=d;b(c,c.body)}else A(a.INVALID)}function E(a){a=t(a);var d;a&&"document-meta"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(d=B.rootElement,d.meta=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta"), -b(d,d.meta))}function N(a){a=t(a);var d;a&&"document-settings"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===a.namespaceURI&&(d=B.rootElement,d.settings=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","settings"),b(d,d.settings))}function O(a){a=t(a);var d;if(a&&"manifest"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"===a.namespaceURI)for(d=B.rootElement,d.manifest=a,a=d.manifest.firstElementChild;a;)"file-entry"===a.localName&&"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"=== -a.namespaceURI&&(M[a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","full-path")]=a.getAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","media-type")),a=a.nextElementSibling}function D(a,d,b){a=n.getElementsByTagName(a,d);var c;for(c=0;c'}function P(){var a=new xmldom.LSSerializer,d=R("document-meta");a.filter=new odf.OdfNodeFilter;d+=a.writeToString(B.rootElement.meta,odf.Namespaces.namespaceMap);return d+""}function aa(a,d){var b=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:file-entry");b.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0","manifest:full-path",a);b.setAttributeNS("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", -"manifest:media-type",d);return b}function S(){var a=runtime.parseXML(''),d=a.documentElement,b=new xmldom.LSSerializer,c;for(c in M)M.hasOwnProperty(c)&&d.appendChild(aa(c,M[c]));b.filter=new odf.OdfNodeFilter;return'\n'+b.writeToString(a,odf.Namespaces.namespaceMap)}function fa(){var a,d,b,c=odf.Namespaces.namespaceMap, -h=new xmldom.LSSerializer,e=R("document-styles");d=v(B.rootElement.automaticStyles,"document-styles");b=B.rootElement.masterStyles.cloneNode(!0);a=u(B.rootElement.fontFaceDecls,[b,B.rootElement.styles,d]);f.removePrefixFromStyleNames(d,q,b);h.filter=new k(b,d);e+=h.writeToString(a,c);e+=h.writeToString(B.rootElement.styles,c);e+=h.writeToString(d,c);e+=h.writeToString(b,c);return e+""}function ha(){var a,d,b=odf.Namespaces.namespaceMap,h=new xmldom.LSSerializer,e=R("document-content"); -d=v(B.rootElement.automaticStyles,"document-content");a=u(B.rootElement.fontFaceDecls,[d]);h.filter=new c(B.rootElement.body,d);e+=h.writeToString(a,b);e+=h.writeToString(d,b);e+=h.writeToString(B.rootElement.body,b);return e+""}function C(d,b){runtime.loadXML(d,function(d,c){if(d)b(d);else if(c){V(c);W(c.documentElement);var h=t(c);h&&"document"===h.localName&&"urn:oasis:names:tc:opendocument:xmlns:office:1.0"===h.namespaceURI?(I(h),A(a.DONE)):A(a.INVALID)}else b("No DOM was loaded.")})} -function Z(a,d){var c;c=B.rootElement;var h=c.meta;h||(c.meta=h=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0","meta"),b(c,h));c=h;a&&n.mapKeyValObjOntoNode(c,a,odf.Namespaces.lookupNamespaceURI);d&&n.removeKeyElementsFromNode(c,d,odf.Namespaces.lookupNamespaceURI)}function ba(d,b){function c(a,d){var b;d||(d=a);b=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",d);f[a]=b;f.appendChild(b)}var h=new core.Zip("",null),e="application/vnd.oasis.opendocument."+ -d+(!0===b?"-template":""),m=runtime.byteArrayFromString(e,"utf8"),f=B.rootElement,g=document.createElementNS("urn:oasis:names:tc:opendocument:xmlns:office:1.0",d);h.save("mimetype",m,!1,new Date);c("meta");c("settings");c("scripts");c("fontFaceDecls","font-face-decls");c("styles");c("automaticStyles","automatic-styles");c("masterStyles","master-styles");c("body");f.body.appendChild(g);M["/"]=e;M["settings.xml"]="text/xml";M["meta.xml"]="text/xml";M["styles.xml"]="text/xml";M["content.xml"]="text/xml"; -A(a.DONE);return h}function U(){var a,d=new Date,b="";B.rootElement.settings&&B.rootElement.settings.firstElementChild&&(a=new xmldom.LSSerializer,b=R("document-settings"),a.filter=new odf.OdfNodeFilter,b+=a.writeToString(B.rootElement.settings,odf.Namespaces.namespaceMap),b+="");(a=b)?(a=runtime.byteArrayFromString(a,"utf8"),Y.save("settings.xml",a,!0,d)):Y.remove("settings.xml");b=runtime.getWindow();a="WebODF/"+webodf.Version;b&&(a=a+" "+b.navigator.userAgent);Z({"meta:generator":a}, -null);a=runtime.byteArrayFromString(P(),"utf8");Y.save("meta.xml",a,!0,d);a=runtime.byteArrayFromString(fa(),"utf8");Y.save("styles.xml",a,!0,d);a=runtime.byteArrayFromString(ha(),"utf8");Y.save("content.xml",a,!0,d);a=runtime.byteArrayFromString(S(),"utf8");Y.save("META-INF/manifest.xml",a,!0,d)}function ga(a,d){U();Y.writeAs(a,function(a){d(a)})}var B=this,Y,M={},Q,F="";this.onstatereadychange=m;this.state=this.onchange=null;this.getMetadata=z;this.setRootElement=I;this.getContentElement=function(){var a; -Q||(a=B.rootElement.body,Q=n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","text")||n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","presentation")||n.getDirectChild(a,"urn:oasis:names:tc:opendocument:xmlns:office:1.0","spreadsheet"));if(!Q)throw"Could not find content element in .";return Q};this.getDocumentType=function(){var a=B.getContentElement();return a&&a.localName};this.isTemplate=function(){return"-template"===M["/"].substr(-9)}; -this.setIsTemplate=function(a){var d=M["/"],b="-template"===d.substr(-9);a!==b&&(d=a?d+"-template":d.substr(0,d.length-9),M["/"]=d,a=runtime.byteArrayFromString(d,"utf8"),Y.save("mimetype",a,!1,new Date))};this.getPart=function(a){return new odf.OdfPart(a,M[a],B,Y)};this.getPartData=function(a,d){Y.load(a,d)};this.setMetadata=Z;this.incrementEditingCycles=function(){var a=z(odf.Namespaces.metans,"editing-cycles"),a=a?parseInt(a,10):0;isNaN(a)&&(a=0);Z({"meta:editing-cycles":a+1},null);return a+1}; -this.createByteArray=function(a,d){U();Y.createByteArray(a,d)};this.saveAs=ga;this.save=function(a){ga(F,a)};this.getUrl=function(){return F};this.setBlob=function(a,d,b){b=e.convertBase64ToByteArray(b);Y.save(a,b,!1,new Date);M.hasOwnProperty(a)&&runtime.log(a+" has been overwritten.");M[a]=d};this.removeBlob=function(a){var d=Y.remove(a);runtime.assert(d,"file is not found: "+a);delete M[a]};this.state=a.LOADING;this.rootElement=function(a){var d=document.createElementNS(a.namespaceURI,a.localName), -b;a=new a.Type;for(b in a)a.hasOwnProperty(b)&&(d[b]=a[b]);return d}({Type:odf.ODFDocumentElement,namespaceURI:odf.ODFDocumentElement.namespaceURI,localName:odf.ODFDocumentElement.localName});d===odf.OdfContainer.DocumentType.TEXT?Y=ba("text"):d===odf.OdfContainer.DocumentType.TEXT_TEMPLATE?Y=ba("text",!0):d===odf.OdfContainer.DocumentType.PRESENTATION?Y=ba("presentation"):d===odf.OdfContainer.DocumentType.PRESENTATION_TEMPLATE?Y=ba("presentation",!0):d===odf.OdfContainer.DocumentType.SPREADSHEET? -Y=ba("spreadsheet"):d===odf.OdfContainer.DocumentType.SPREADSHEET_TEMPLATE?Y=ba("spreadsheet",!0):(F=d,Y=new core.Zip(F,function(d,b){Y=b;d?C(F,function(b){d&&(Y.error=d+"\n"+b,A(a.INVALID))}):J([{path:"styles.xml",handler:K},{path:"content.xml",handler:L},{path:"meta.xml",handler:E},{path:"settings.xml",handler:N},{path:"META-INF/manifest.xml",handler:O}])}))};odf.OdfContainer.EMPTY=0;odf.OdfContainer.LOADING=1;odf.OdfContainer.DONE=2;odf.OdfContainer.INVALID=3;odf.OdfContainer.SAVING=4;odf.OdfContainer.MODIFIED= -5;odf.OdfContainer.getContainer=function(a){return new odf.OdfContainer(a,null)}})();odf.OdfContainer.DocumentType={TEXT:1,TEXT_TEMPLATE:2,PRESENTATION:3,PRESENTATION_TEMPLATE:4,SPREADSHEET:5,SPREADSHEET_TEMPLATE:6};gui.AnnotatableCanvas=function(){};gui.AnnotatableCanvas.prototype.refreshSize=function(){};gui.AnnotatableCanvas.prototype.getZoomLevel=function(){};gui.AnnotatableCanvas.prototype.getSizer=function(){}; -gui.AnnotationViewManager=function(g,k,c,b){function f(d){var b=d.annotationEndElement,c=l.createRange(),e=d.getAttributeNS(odf.Namespaces.officens,"name");b&&(c.setStart(d,d.childNodes.length),c.setEnd(b,0),d=a.getTextNodes(c,!1),d.forEach(function(a){var d;a:{for(d=a.parentNode;d.namespaceURI!==odf.Namespaces.officens||"body"!==d.localName;){if("http://www.w3.org/1999/xhtml"===d.namespaceURI&&"webodf-annotationHighlight"===d.className&&d.getAttribute("annotation")===e){d=!0;break a}d=d.parentNode}d= -!1}d||(d=l.createElement("span"),d.className="webodf-annotationHighlight",d.setAttribute("annotation",e),a.parentNode.replaceChild(d,a),d.appendChild(a))}));c.detach()}function n(a){var b=g.getSizer();a?(c.style.display="inline-block",b.style.paddingRight=d.getComputedStyle(c).width):(c.style.display="none",b.style.paddingRight=0);g.refreshSize()}function p(){e.sort(function(a,d){return 0!==(a.compareDocumentPosition(d)&Node.DOCUMENT_POSITION_FOLLOWING)?-1:1})}function r(){var a;for(a=0;a=(n.getBoundingClientRect().top-r.bottom)/d?b.style.top=Math.abs(n.getBoundingClientRect().top-r.bottom)/d+20+"px":b.style.top="0px"): -b.style.top="0px";l.style.left=f.getBoundingClientRect().width/d+"px";var f=l.style,n=l.getBoundingClientRect().left/d,k=l.getBoundingClientRect().top/d,r=b.getBoundingClientRect().left/d,p=b.getBoundingClientRect().top/d,q=0,I=0,q=r-n,q=q*q,I=p-k,I=I*I,n=Math.sqrt(q+I);f.width=n+"px";k=Math.asin((b.getBoundingClientRect().top-l.getBoundingClientRect().top)/(d*parseFloat(l.style.width)));l.style.transform="rotate("+k+"rad)";l.style.MozTransform="rotate("+k+"rad)";l.style.WebkitTransform="rotate("+ -k+"rad)";l.style.msTransform="rotate("+k+"rad)"}}function q(a){var d=e.indexOf(a),b=a.parentNode.parentNode;"div"===b.localName&&(b.parentNode.insertBefore(a,b),b.parentNode.removeChild(b));a=a.getAttributeNS(odf.Namespaces.officens,"name");a=l.querySelectorAll('span.webodf-annotationHighlight[annotation="'+a+'"]');for(var c,b=0;bp||k.bottom>p)g.scrollTop=k.bottom-k.top<=p-f?g.scrollTop+(k.bottom-p):g.scrollTop+(k.top-f);k.leftn&&(g.scrollLeft=k.right-k.left<=n-b?g.scrollLeft+(k.right-n):g.scrollLeft-(b-k.left))}}}; -(function(){function g(c,n,k,r,q){var e,l=0,a;for(a in c)if(c.hasOwnProperty(a)){if(l===k){e=a;break}l+=1}e?n.getPartData(c[e].href,function(a,m){if(a)runtime.log(a);else if(m){var h="@font-face { font-family: "+(c[e].family||e)+"; src: url(data:application/x-font-ttf;charset=binary;base64,"+b.convertUTF8ArrayToBase64(m)+') format("truetype"); }';try{r.insertRule(h,r.cssRules.length)}catch(l){runtime.log("Problem inserting rule in CSS: "+runtime.toJson(l)+"\nRule: "+h)}}else runtime.log("missing font data for "+ -c[e].href);g(c,n,k+1,r,q)}):q&&q()}var k=xmldom.XPath,c=odf.OdfUtils,b=new core.Base64;odf.FontLoader=function(){this.loadFonts=function(b,n){for(var p=b.rootElement.fontFaceDecls;n.cssRules.length;)n.deleteRule(n.cssRules.length-1);if(p){var r={},q,e,l,a;if(p)for(p=k.getODFElementsWithXPath(p,"style:font-face[svg:font-face-src]",odf.Namespaces.lookupNamespaceURI),q=0;q text|list-item:first-child > :not(text|list):first-child:before',u+="{",u+="counter-increment: "+p+" 0;",u+="}",g(b,u));for(;l.counterIdStack.length>=k;)l.counterIdStack.pop();l.counterIdStack.push(p);t=l.contentRules[k.toString()]||"";for(u=1;u<=k;u+=1)t=t.replace(u+"webodf-listLevel",l.counterIdStack[u-1]);u='text|list[webodfhelper|counter-id="'+r+'"] > text|list-item > :not(text|list):first-child:before'; -u+="{";u+=t;u+="counter-increment: "+p+";";u+="}";g(b,u)}for(h=h.firstElementChild;h;)c(d,h,f,l),h=h.nextElementSibling}else l.continuedCounterIdStack=[]}var f=0,a="",d={};this.createCounterRules=function(a,b,n){var g=b.getAttributeNS(p,"id"),r=[];n&&(n=n.getAttributeNS("urn:webodf:names:helper","counter-id"),r=d[n].slice(0));a=new k(a,r);g?g="Y"+g:(f+=1,g="X"+f);c(g,b,0,a);d[g+"-level1-1"]=a.counterIdStack};this.initialiseCreatedCounters=function(){var d;d="office|document{"+("counter-reset: "+a+ -";");d+="}";g(b,d)}}var b=odf.Namespaces.fons,f=odf.Namespaces.stylens,n=odf.Namespaces.textns,p=odf.Namespaces.xmlns,r={1:"decimal",a:"lower-latin",A:"upper-latin",i:"lower-roman",I:"upper-roman"};odf.ListStyleToCss=function(){function k(a){var b=m.parseLength(a);return b?d.convert(b.value,b.unit,"px"):(runtime.log("Could not parse value '"+a+"'."),0)}function e(a){return a.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function l(a,d){var b;a&&(b=a.getAttributeNS(n,"style-name"));return b===d}function a(a, -d,b){d=d.getElementsByTagNameNS(n,"list");a=new c(a);var m,g,k,q,t,A,I={},K;for(K=0;K text|list-item > text|list",--x;x=E&&E.getAttributeNS(b,"text-align")||"left";switch(x){case "end":x="right";break;case "start":x="left"}"label-alignment"===N?(D=O&&O.getAttributeNS(b,"margin-left")||"0px",J=O&&O.getAttributeNS(b,"text-indent")||"0px",R=O&&O.getAttributeNS(n,"label-followed-by"),O=k(D)):(D=E&&E.getAttributeNS(n,"space-before")||"0px",V=E&&E.getAttributeNS(n,"min-label-width")||"0px", -W=E&&E.getAttributeNS(n,"min-label-distance")||"0px",O=k(D)+k(V));E=p+" > text|list-item";E+="{";E+="margin-left: "+O+"px;";E+="}";g(e,E);E=p+" > text|list-item > text|list";E+="{";E+="margin-left: "+-O+"px;";E+="}";g(e,E);E=p+" > text|list-item > :not(text|list):first-child:before";E+="{";E+="text-align: "+x+";";E+="display: inline-block;";"label-alignment"===N?(E+="margin-left: "+J+";","listtab"===R&&(E+="padding-right: 0.2cm;")):(E+="min-width: "+V+";",E+="margin-left: "+(0===parseFloat(V)?"": -"-")+V+";",E+="padding-right: "+W+";");E+="}";g(e,E)}c=c.nextElementSibling}});a(d,e,m)}}})();odf.LazyStyleProperties=function(g,k){var c={};this.value=function(b){var f;c.hasOwnProperty(b)?f=c[b]:(f=k[b](),void 0===f&&g&&(f=g.value(b)),c[b]=f);return f};this.reset=function(b){g=b;c={}}}; -odf.StyleParseUtils=function(){function g(c){var b,f;c=(c=/(-?[0-9]*[0-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px))/.exec(c))?{value:parseFloat(c[1]),unit:c[3]}:null;f=c&&c.unit;"px"===f?b=c.value:"cm"===f?b=c.value/2.54*96:"mm"===f?b=c.value/25.4*96:"in"===f?b=96*c.value:"pt"===f?b=c.value/.75:"pc"===f&&(b=16*c.value);return b}var k=odf.Namespaces.stylens;this.parseLength=g;this.parsePositiveLengthOrPercent=function(c,b,f){var n;c&&(n=parseFloat(c.substr(0, -c.indexOf("%"))),isNaN(n)&&(n=void 0));var k;void 0!==n?(f&&(k=f.value(b)),n=void 0===k?void 0:k/100*n):n=g(c);return n};this.getPropertiesElement=function(c,b,f){for(b=f?f.nextElementSibling:b.firstElementChild;null!==b&&(b.localName!==c||b.namespaceURI!==k);)b=b.nextElementSibling;return b};this.parseAttributeList=function(c){c&&(c=c.replace(/^\s*(.*?)\s*$/g,"$1"));return c&&0n.value&&(m="0.75pt"+h);h=m}else if(V.hasOwnProperty(e[1])){var m= -a,f=e[0],n=e[1],g=J.parseLength(h),r=void 0,p=void 0,q=void 0,O=void 0,q=void 0;if(g&&"%"===g.unit){r=g.value/100;p=k(m.parentNode);for(O="0";p;){if(q=y.getDirectChild(p,l,"paragraph-properties"))if(q=J.parseLength(q.getAttributeNS(f,n))){if("%"!==q.unit){O=q.value*r+q.unit;break}r*=q.value/100}p=k(p)}h=O}}e[2]&&(b+=e[2]+":"+h+";")}return b}function b(a,d,b,c){return d+d+b+b+c+c}function f(a,d){var b=[a],c=d.derivedStyles;Object.keys(c).forEach(function(a){a=f(a,c[a]);b=b.concat(a)});return b}function n(a, -d,b,c){function e(d,b){var c=[],h;d.forEach(function(a){m.forEach(function(d){c.push('draw|page[webodfhelper|page-style-name="'+d+'"] draw|frame[presentation|class="'+a+'"]')})});0 -z&&(a=z);for(d=Math.floor(a/c)*c;!b&&0<=d;)b=m[d],d-=c;for(b=b||x;b.nextBookmark&&b.nextBookmark.steps<=a;)e.check(),b=b.nextBookmark;runtime.assert(-1===a||b.steps<=a,"Bookmark @"+p(b)+" at step "+b.steps+" exceeds requested step of "+a);return b}function a(a){a.previousBookmark&&(a.previousBookmark.nextBookmark=a.nextBookmark);a.nextBookmark&&(a.nextBookmark.previousBookmark=a.previousBookmark)}function d(a){for(var d,b=null;!b&&a&&a!==k;)(d=q(a))&&(b=h[d])&&b.node!==a&&(runtime.log("Cloned node detected. Creating new bookmark"), -b=null,a.removeAttributeNS("urn:webodf:names:steps","nodeId")),a=a.parentNode;return b}var m={},h={},y=core.DomUtils,x,z,w=Node.DOCUMENT_POSITION_FOLLOWING,v=Node.DOCUMENT_POSITION_PRECEDING;this.updateBookmark=function(d,b){var g,n=Math.ceil(d/c)*c,p,v,E;if(void 0!==z&&zp.steps)m[n]=v;r()};this.setToClosestStep=function(a,d){var b;r();b=l(a);b.setIteratorPosition(d); -return b.steps};this.setToClosestDomPoint=function(a,b,c){var e,h;r();if(a===k&&0===b)e=x;else if(a===k&&b===k.childNodes.length)for(h in e=x,m)m.hasOwnProperty(h)&&(a=m[h],a.steps>e.steps&&(e=a));else if(e=d(a.childNodes.item(b)||a),!e)for(c.setUnfilteredPosition(a,b);!e&&c.previousNode();)e=d(c.getCurrentNode());e=e||x;void 0!==z&&e.steps>z&&(e=l(z));e.setIteratorPosition(c);return e.steps};this.damageCacheAfterStep=function(a){0>a&&(a=-1);void 0===z?z=a:aa)throw new RangeError("Requested steps is negative ("+a+")");for(b=p.setToClosestStep(a,k);bq.comparePoints(g,0,a,b),a=g,b=b?0:g.childNodes.length);k.setUnfilteredPosition(a,b);n(k,h)||k.setUnfilteredPosition(a,b);h=k.container();b=k.unfilteredDomOffset();a=p.setToClosestDomPoint(h,b,k);if(0>q.comparePoints(k.container(),k.unfilteredDomOffset(),h,b))return 0=e.textNode.length?null:e.textNode.splitText(e.offset));for(d=e.textNode;d!==a;){d=d.parentNode;m=d.cloneNode(!1);h&&m.appendChild(h);if(y)for(;y&&y.nextSibling;)m.appendChild(y.nextSibling);else for(;d.firstChild;)m.appendChild(d.firstChild);d.parentNode.insertBefore(m,d.nextSibling);y=d;h=m}p.isListItem(h)&&(h=h.childNodes.item(0));n?h.setAttributeNS(r,"text:style-name",n):h.removeAttributeNS(r,"style-name");0===e.textNode.length&& -e.textNode.parentNode.removeChild(e.textNode);c.emit(ops.OdtDocument.signalStepsInserted,{position:b});x&&f&&(c.moveCursor(g,b+1,0),c.emit(ops.Document.signalCursorMoved,x));c.fixCursorPositions();c.getOdfCanvas().refreshSize();c.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:l,memberId:g,timeStamp:k});c.emit(ops.OdtDocument.signalParagraphChanged,{paragraphElement:h,memberId:g,timeStamp:k});c.getOdfCanvas().rerenderAnnotations();return!0};this.spec=function(){return{optype:"SplitParagraph", -memberid:g,timestamp:k,position:b,sourceParagraphPosition:c,paragraphStyleName:n,moveCursor:f}}}; -ops.OpUpdateMember=function(){function g(c){var f="//dc:creator[@editinfo:memberid='"+k+"']";c=xmldom.XPath.getODFElementsWithXPath(c.getRootNode(),f,function(b){return"editinfo"===b?"urn:webodf:names:editinfo":odf.Namespaces.lookupNamespaceURI(b)});for(f=0;f=e.width&&(e=null),g.detach();else if(k.isCharacterElement(f.container)||k.isCharacterFrame(f.container))e=b.getBoundingClientRect(f.container); -return e}var k=odf.OdfUtils,c=new odf.StepUtils,b=core.DomUtils,f=core.StepDirection.NEXT,n=gui.StepInfo.VisualDirection.LEFT_TO_RIGHT,p=gui.StepInfo.VisualDirection.RIGHT_TO_LEFT;this.getContentRect=g;this.moveToFilteredStep=function(b,c,e){function l(a,b){b.process(w,h,k)&&(a=!0,!x&&b.token&&(x=b.token));return a}var a=c===f,d,m,h,k,x,z=b.snapshot();d=!1;var w;do d=g(b),w={token:b.snapshot(),container:b.container,offset:b.offset,direction:c,visualDirection:c===f?n:p},m=b.nextStep()?g(b):null,b.restore(w.token), -a?(h=d,k=m):(h=m,k=d),d=e.reduce(l,!1);while(!d&&b.advanceStep(c));d||e.forEach(function(a){!x&&a.token&&(x=a.token)});b.restore(x||z);return Boolean(x)}}; -gui.Caret=function(g,k,c,b){function f(){a.style.opacity="0"===a.style.opacity?"1":"0";t.trigger()}function n(){y.selectNodeContents(h);return y.getBoundingClientRect()}function p(a){return E[a]!==L[a]}function r(){Object.keys(L).forEach(function(a){E[a]=L[a]})}function q(){if(!1===L.isShown||g.getSelectionType()!==ops.OdtCursor.RangeSelection||!b&&!g.getSelectedRange().collapsed)L.visibility="hidden",a.style.visibility="hidden",t.cancel();else if(L.visibility="visible",a.style.visibility="visible", -!1===L.isFocused)a.style.opacity="1",t.cancel();else{if(A||p("visibility"))a.style.opacity="1",t.cancel();t.trigger()}if(K||I){var c;c=g.getNode();var e,h,f=z.getBoundingClientRect(x.getSizer()),q=!1,y=0;c.removeAttributeNS("urn:webodf:names:cursor","caret-sizer-active");if(0c.height&&(c={top:c.top-(8-c.height)/2,height:8,right:c.right});l.style.height=c.height+"px";l.style.top=c.top+"px"; -l.style.left=c.right-c.width+"px";l.style.width=c.width?c.width+"px":"";m&&(c=runtime.getWindow().getComputedStyle(g.getNode(),null),c.font?m.style.font=c.font:(m.style.fontStyle=c.fontStyle,m.style.fontVariant=c.fontVariant,m.style.fontWeight=c.fontWeight,m.style.fontSize=c.fontSize,m.style.lineHeight=c.lineHeight,m.style.fontFamily=c.fontFamily))}L.isShown&&I&&k.scrollIntoView(a.getBoundingClientRect());p("isFocused")&&d.markAsFocussed(L.isFocused);r();K=I=A=!1}function e(a){l.parentNode.removeChild(l); -h.parentNode.removeChild(h);a()}var l,a,d,m,h,y,x=g.getDocument().getCanvas(),z=core.DomUtils,w=new gui.GuiStepUtils,v,u,t,A=!1,I=!1,K=!1,L={isFocused:!1,isShown:!0,visibility:"hidden"},E={isFocused:!L.isFocused,isShown:!L.isShown,visibility:"hidden"};this.handleUpdate=function(){K=!0;u.trigger()};this.refreshCursorBlinking=function(){A=!0;u.trigger()};this.setFocus=function(){L.isFocused=!0;u.trigger()};this.removeFocus=function(){L.isFocused=!1;u.trigger()};this.show=function(){L.isShown=!0;u.trigger()}; -this.hide=function(){L.isShown=!1;u.trigger()};this.setAvatarImageUrl=function(a){d.setImageUrl(a)};this.setColor=function(b){a.style.borderColor=b;d.setColor(b)};this.getCursor=function(){return g};this.getFocusElement=function(){return a};this.toggleHandleVisibility=function(){d.isVisible()?d.hide():d.show()};this.showHandle=function(){d.show()};this.hideHandle=function(){d.hide()};this.setOverlayElement=function(a){m=a;l.appendChild(a);K=!0;u.trigger()};this.ensureVisible=function(){I=!0;u.trigger()}; -this.getBoundingClientRect=function(){return z.getBoundingClientRect(l)};this.destroy=function(a){core.Async.destroyAll([u.destroy,t.destroy,d.destroy,e],a)};(function(){var b=g.getDocument(),e=[b.createRootFilter(g.getMemberId()),b.getPositionFilter()],m=b.getDOMDocument();y=m.createRange();h=m.createElement("span");h.className="webodf-caretSizer";h.textContent="|";g.getNode().appendChild(h);l=m.createElement("div");l.setAttributeNS("urn:webodf:names:editinfo","editinfo:memberid",g.getMemberId()); -l.className="webodf-caretOverlay";a=m.createElement("div");a.className="caret";l.appendChild(a);d=new gui.Avatar(l,c);x.getSizer().appendChild(l);v=b.createStepIterator(g.getNode(),0,e,b.getRootNode());u=core.Task.createRedrawTask(q);t=core.Task.createTimeoutTask(f,500);u.triggerImmediate()})()}; -odf.TextSerializer=function(){function g(b){var f="",n=k.filter?k.filter.acceptNode(b):NodeFilter.FILTER_ACCEPT,p=b.nodeType,r;if((n===NodeFilter.FILTER_ACCEPT||n===NodeFilter.FILTER_SKIP)&&c.isTextContentContainingNode(b))for(r=b.firstChild;r;)f+=g(r),r=r.nextSibling;n===NodeFilter.FILTER_ACCEPT&&(p===Node.ELEMENT_NODE&&c.isParagraph(b)?f+="\n":p===Node.TEXT_NODE&&b.textContent&&(f+=b.textContent));return f}var k=this,c=odf.OdfUtils;this.filter=null;this.writeToString=function(b){if(!b)return""; -b=g(b);"\n"===b[b.length-1]&&(b=b.substr(0,b.length-1));return b}};gui.MimeDataExporter=function(){var g;this.exportRangeToDataTransfer=function(k,c){var b;b=c.startContainer.ownerDocument.createElement("span");b.appendChild(c.cloneContents());b=g.writeToString(b);try{k.setData("text/plain",b)}catch(f){k.setData("Text",b)}};g=new odf.TextSerializer;g.filter=new odf.OdfNodeFilter}; -gui.Clipboard=function(g){this.setDataFromRange=function(k,c){var b,f=k.clipboardData;b=runtime.getWindow();!f&&b&&(f=b.clipboardData);f?(b=!0,g.exportRangeToDataTransfer(f,c),k.preventDefault()):b=!1;return b}}; -gui.SessionContext=function(g,k){var c=g.getOdtDocument(),b=odf.OdfUtils;this.isLocalCursorWithinOwnAnnotation=function(){var f=c.getCursor(k),g;if(!f)return!1;g=f&&f.getNode();f=c.getMember(k).getProperties().fullName;return(g=b.getParentAnnotation(g,c.getRootNode()))&&b.getAnnotationCreator(g)===f?!0:!1}}; -gui.StyleSummary=function(g){function k(b,c){var k=b+"|"+c,q;f.hasOwnProperty(k)||(q=[],g.forEach(function(e){e=(e=e.styleProperties[b])&&e[c];-1===q.indexOf(e)&&q.push(e)}),f[k]=q);return f[k]}function c(b,c,f){return function(){var g=k(b,c);return f.length>=g.length&&g.every(function(b){return-1!==f.indexOf(b)})}}function b(b,c){var f=k(b,c);return 1===f.length?f[0]:void 0}var f={};this.getPropertyValues=k;this.getCommonValue=b;this.isBold=c("style:text-properties","fo:font-weight",["bold"]);this.isItalic= -c("style:text-properties","fo:font-style",["italic"]);this.hasUnderline=c("style:text-properties","style:text-underline-style",["solid"]);this.hasStrikeThrough=c("style:text-properties","style:text-line-through-style",["solid"]);this.fontSize=function(){var c=b("style:text-properties","fo:font-size");return c&&parseFloat(c)};this.fontName=function(){return b("style:text-properties","style:font-name")};this.isAlignedLeft=c("style:paragraph-properties","fo:text-align",["left","start"]);this.isAlignedCenter= -c("style:paragraph-properties","fo:text-align",["center"]);this.isAlignedRight=c("style:paragraph-properties","fo:text-align",["right","end"]);this.isAlignedJustified=c("style:paragraph-properties","fo:text-align",["justify"]);this.text={isBold:this.isBold,isItalic:this.isItalic,hasUnderline:this.hasUnderline,hasStrikeThrough:this.hasStrikeThrough,fontSize:this.fontSize,fontName:this.fontName};this.paragraph={isAlignedLeft:this.isAlignedLeft,isAlignedCenter:this.isAlignedCenter,isAlignedRight:this.isAlignedRight, -isAlignedJustified:this.isAlignedJustified}}; -gui.DirectFormattingController=function(g,k,c,b,f,n,p){function r(){return U.value().styleSummary}function q(){return U.value().enabledFeatures}function e(a){var b;a.collapsed?(b=a.startContainer,b.hasChildNodes()&&a.startOffseta.clientWidth||a.scrollHeight>a.clientHeight)&&b.push(new l(a)),a=a.parentNode;b.push(new e(v));return b}function w(){var a; -h()||(a=z(K),x(),K.focus(),a.forEach(function(a){a.restore()}))}var v=runtime.getWindow(),u={beforecut:!0,beforepaste:!0,longpress:!0,drag:!0,dragstop:!0},t={mousedown:!0,mouseup:!0,focus:!0},A={},I={},K,L=g.getCanvas().getElement(),E=this,N={};this.addFilter=function(b,d){a(b,!0).filters.push(d)};this.removeFilter=function(b,d){var c=a(b,!0),e=c.filters.indexOf(d);-1!==e&&c.filters.splice(e,1)};this.subscribe=d;this.unsubscribe=m;this.hasFocus=h;this.focus=w;this.getEventTrap=function(){return K}; -this.setEditing=function(a){var b=h();b&&K.blur();a?K.removeAttribute("readOnly"):K.setAttribute("readOnly","true");b&&w()};this.destroy=function(a){m("touchstart",q);Object.keys(N).forEach(function(a){b(parseInt(a,10))});N.length=0;Object.keys(A).forEach(function(a){A[a].destroy()});A={};m("mousedown",y);m("mouseup",x);m("contextmenu",x);Object.keys(I).forEach(function(a){I[a].destroy()});I={};K.parentNode.removeChild(K);a()};(function(){var a=g.getOdfCanvas().getSizer(),b=a.ownerDocument;runtime.assert(Boolean(v), -"EventManager requires a window object to operate correctly");K=b.createElement("textarea");K.id="eventTrap";K.setAttribute("tabindex","-1");K.setAttribute("readOnly","true");K.setAttribute("rows","1");a.appendChild(K);d("mousedown",y);d("mouseup",x);d("contextmenu",x);A.longpress=new c("longpress",["touchstart","touchmove","touchend"],n);A.drag=new c("drag",["touchstart","touchmove","touchend"],p);A.dragstop=new c("dragstop",["drag","touchend"],r);d("touchstart",q)})()}; -gui.IOSSafariSupport=function(g){function k(){c.innerHeight!==c.outerHeight&&(b.style.display="none",runtime.requestAnimationFrame(function(){b.style.display="block"}))}var c=runtime.getWindow(),b=g.getEventTrap();this.destroy=function(c){g.unsubscribe("focus",k);b.removeAttribute("autocapitalize");b.style.WebkitTransform="";c()};g.subscribe("focus",k);b.setAttribute("autocapitalize","off");b.style.WebkitTransform="translateX(-10000px)"}; -gui.HyperlinkController=function(g,k,c,b){function f(){var b=!0;!0===k.getState(gui.CommonConstraints.EDIT.REVIEW_MODE)&&(b=c.isLocalCursorWithinOwnAnnotation());b!==e&&(e=b,q.emit(gui.HyperlinkController.enabledChanged,e))}function n(c){c.getMemberId()===b&&f()}var p=odf.OdfUtils,r=g.getOdtDocument(),q=new core.EventNotifier([gui.HyperlinkController.enabledChanged]),e=!1;this.isEnabled=function(){return e};this.subscribe=function(b,a){q.subscribe(b,a)};this.unsubscribe=function(b,a){q.unsubscribe(b, -a)};this.addHyperlink=function(c,a){if(e){var d=r.getCursorSelection(b),f=new ops.OpApplyHyperlink,h=[];if(0===d.length||a)a=a||c,f=new ops.OpInsertText,f.init({memberid:b,position:d.position,text:a}),d.length=a.length,h.push(f);f=new ops.OpApplyHyperlink;f.init({memberid:b,position:d.position,length:d.length,hyperlink:c});h.push(f);g.enqueue(h)}};this.removeHyperlinks=function(){if(e){var c=r.createPositionIterator(r.getRootNode()),a=r.getCursor(b).getSelectedRange(),d=p.getHyperlinkElements(a), -f=a.collapsed&&1===d.length,h=r.getDOMDocument().createRange(),k=[],n,q;0!==d.length&&(d.forEach(function(a){h.selectNodeContents(a);n=r.convertDomToCursorRange({anchorNode:h.startContainer,anchorOffset:h.startOffset,focusNode:h.endContainer,focusOffset:h.endOffset});q=new ops.OpRemoveHyperlink;q.init({memberid:b,position:n.position,length:n.length});k.push(q)}),f||(f=d[0],-1===a.comparePoint(f,0)&&(h.setStart(f,0),h.setEnd(a.startContainer,a.startOffset),n=r.convertDomToCursorRange({anchorNode:h.startContainer, -anchorOffset:h.startOffset,focusNode:h.endContainer,focusOffset:h.endOffset}),0k.width&&(v=k.width/n.width);n.height>k.height&&(u=k.height/n.height);k=Math.min(v,u);n= -{width:n.width*k,height:n.height*k}}k=p.convert(n.width,"px","cm")+"cm";p=p.convert(n.height,"px","cm")+"cm";u=e.getOdfCanvas().odfContainer().rootElement.styles;n=d.toLowerCase();var v=r.hasOwnProperty(n)?r[n]:null,t;n=[];runtime.assert(null!==v,"Image type is not supported: "+d);v="Pictures/"+f.generateImageName()+v;t=new ops.OpSetBlob;t.init({memberid:b,filename:v,mimetype:d,content:c});n.push(t);a.getStyleElement("Graphics","graphic",[u])||(d=new ops.OpAddStyle,d.init({memberid:b,styleName:"Graphics", -styleFamily:"graphic",isAutomaticStyle:!1,setProperties:{"style:graphic-properties":{"text:anchor-type":"paragraph","svg:x":"0cm","svg:y":"0cm","style:wrap":"dynamic","style:number-wrapped-paragraphs":"no-limit","style:wrap-contour":"false","style:vertical-pos":"top","style:vertical-rel":"paragraph","style:horizontal-pos":"center","style:horizontal-rel":"paragraph"}}}),n.push(d));d=f.generateStyleName();c=new ops.OpAddStyle;c.init({memberid:b,styleName:d,styleFamily:"graphic",isAutomaticStyle:!0, -setProperties:{"style:parent-style-name":"Graphics","style:graphic-properties":{"style:vertical-pos":"top","style:vertical-rel":"baseline","style:horizontal-pos":"center","style:horizontal-rel":"paragraph","fo:background-color":"transparent","style:background-transparency":"100%","style:shadow":"none","style:mirror":"none","fo:clip":"rect(0cm, 0cm, 0cm, 0cm)","draw:luminance":"0%","draw:contrast":"0%","draw:red":"0%","draw:green":"0%","draw:blue":"0%","draw:gamma":"100%","draw:color-inversion":"false", -"draw:image-opacity":"100%","draw:color-mode":"standard"}}});n.push(c);t=new ops.OpInsertImage;t.init({memberid:b,position:e.getCursorPosition(b),filename:v,frameWidth:k,frameHeight:p,frameStyleName:d,frameName:f.generateFrameName()});n.push(t);g.enqueue(n)}};this.destroy=function(a){e.unsubscribe(ops.Document.signalCursorMoved,p);k.unsubscribe(gui.CommonConstraints.EDIT.REVIEW_MODE,n);a()};e.subscribe(ops.Document.signalCursorMoved,p);k.subscribe(gui.CommonConstraints.EDIT.REVIEW_MODE,n);n()}; -gui.ImageController.enabledChanged="enabled/changed"; -gui.ImageSelector=function(g){function k(){var c=g.getSizer(),k=f.createElement("div");k.id="imageSelector";k.style.borderWidth="1px";c.appendChild(k);b.forEach(function(b){var c=f.createElement("div");c.className=b;k.appendChild(c)});return k}var c=odf.Namespaces.svgns,b="topLeft topRight bottomRight bottomLeft topMiddle rightMiddle bottomMiddle leftMiddle".split(" "),f=g.getElement().ownerDocument,n=!1;this.select=function(b){var r,q,e=f.getElementById("imageSelector");e||(e=k());n=!0;r=e.parentNode; -q=b.getBoundingClientRect();var l=r.getBoundingClientRect(),a=g.getZoomLevel();r=(q.left-l.left)/a-1;q=(q.top-l.top)/a-1;e.style.display="block";e.style.left=r+"px";e.style.top=q+"px";e.style.width=b.getAttributeNS(c,"width");e.style.height=b.getAttributeNS(c,"height")};this.clearSelection=function(){var b;n&&(b=f.getElementById("imageSelector"))&&(b.style.display="none");n=!1};this.isSelectorElement=function(b){var c=f.getElementById("imageSelector");return c?b===c||b.parentNode===c:!1}}; -(function(){function g(g){function c(b){p=b.which&&String.fromCharCode(b.which)===n;n=void 0;return!1===p}function b(){p=!1}function f(b){n=b.data;p=!1}var n,p=!1;this.destroy=function(n){g.unsubscribe("textInput",b);g.unsubscribe("compositionend",f);g.removeFilter("keypress",c);n()};g.subscribe("textInput",b);g.subscribe("compositionend",f);g.addFilter("keypress",c)}gui.InputMethodEditor=function(k,c){function b(b){a&&(b?a.getNode().setAttributeNS("urn:webodf:names:cursor","composing","true"):(a.getNode().removeAttributeNS("urn:webodf:names:cursor", -"composing"),h.textContent=""))}function f(){x&&(x=!1,b(!1),w.emit(gui.InputMethodEditor.signalCompositionEnd,{data:z}),z="")}function n(){I||(I=!0,f(),a&&a.getSelectedRange().collapsed?d.value="":d.value=u.writeToString(a.getSelectedRange().cloneContents()),d.setSelectionRange(0,d.value.length),I=!1)}function p(){c.hasFocus()&&y.trigger()}function r(){v=void 0;y.cancel();b(!0);x||w.emit(gui.InputMethodEditor.signalCompositionStart,{data:""})}function q(a){a=v=a.data;x=!0;z+=a;y.trigger()}function e(a){a.data!== -v&&(a=a.data,x=!0,z+=a,y.trigger());v=void 0}function l(){h.textContent=d.value}var a=null,d=c.getEventTrap(),m=d.ownerDocument,h,y,x=!1,z="",w=new core.EventNotifier([gui.InputMethodEditor.signalCompositionStart,gui.InputMethodEditor.signalCompositionEnd]),v,u,t=[],A,I=!1;this.subscribe=w.subscribe;this.unsubscribe=w.unsubscribe;this.registerCursor=function(b){b.getMemberId()===k&&(a=b,a.getNode().appendChild(h),b.subscribe(ops.OdtCursor.signalCursorUpdated,p),c.subscribe("input",l),c.subscribe("compositionupdate", -l))};this.removeCursor=function(b){a&&b===k&&(a.getNode().removeChild(h),a.unsubscribe(ops.OdtCursor.signalCursorUpdated,p),c.unsubscribe("input",l),c.unsubscribe("compositionupdate",l),a=null)};this.destroy=function(a){c.unsubscribe("compositionstart",r);c.unsubscribe("compositionend",q);c.unsubscribe("textInput",e);c.unsubscribe("keypress",f);c.unsubscribe("focus",n);core.Async.destroyAll(A,a)};(function(){u=new odf.TextSerializer;u.filter=new odf.OdfNodeFilter;c.subscribe("compositionstart",r); -c.subscribe("compositionend",q);c.subscribe("textInput",e);c.subscribe("keypress",f);c.subscribe("focus",n);t.push(new g(c));A=t.map(function(a){return a.destroy});h=m.createElement("span");h.setAttribute("id","composer");y=core.Task.createTimeoutTask(n,1);A.push(y.destroy)})()};gui.InputMethodEditor.signalCompositionStart="input/compositionstart";gui.InputMethodEditor.signalCompositionEnd="input/compositionend"})(); -gui.MetadataController=function(g,k){function c(b){n.emit(gui.MetadataController.signalMetadataChanged,b)}function b(b){var c=-1===p.indexOf(b);c||runtime.log("Setting "+b+" is restricted.");return c}var f=g.getOdtDocument(),n=new core.EventNotifier([gui.MetadataController.signalMetadataChanged]),p=["dc:creator","dc:date","meta:editing-cycles","meta:editing-duration","meta:document-statistic"];this.setMetadata=function(c,f){var e={},l="",a;c&&Object.keys(c).filter(b).forEach(function(a){e[a]=c[a]}); -f&&(l=f.filter(b).join(","));if(0f:!1}function c(b){null!==b&&!1===k(b)&&(f=Math.abs(b-g))}var b=this,f,n=gui.StepInfo.VisualDirection.LEFT_TO_RIGHT;this.token=void 0;this.process=function(f,g,q){var e,l;f.visualDirection===n?(e=g&&g.right,l=q&&q.left):(e=g&&g.left,l=q&&q.right);if(k(e)||k(l))return!0;if(g||q)c(e),c(l),b.token=f.token;return!1}}; -gui.LineBoundaryScanner=function(){var g=this,k=null;this.token=void 0;this.process=function(c,b,f){var n;if(n=f)if(k){var p=k;n=Math.min(p.bottom-p.top,f.bottom-f.top);var r=Math.max(p.top,f.top),p=Math.min(p.bottom,f.bottom)-r;n=.4>=(0b?a.previousSibling:a.nextSibling,d(f)===NodeFilter.FILTER_ACCEPT&&(c=f),a=a.parentNode;return c}function b(a,b){var d;return null===a?m.NO_NEIGHBOUR:p.isCharacterElement(a)?m.SPACE_CHAR:a.nodeType===f||p.isTextSpan(a)||p.isHyperlink(a)?(d=a.textContent.charAt(b()),q.test(d)?m.SPACE_CHAR:r.test(d)?m.PUNCTUATION_CHAR:m.WORD_CHAR):m.OTHER}var f=Node.TEXT_NODE,n=Node.ELEMENT_NODE, -p=odf.OdfUtils,r=/[!-#%-*,-\/:-;?-@\[-\]_{}\u00a1\u00ab\u00b7\u00bb\u00bf;\u00b7\u055a-\u055f\u0589-\u058a\u05be\u05c0\u05c3\u05c6\u05f3-\u05f4\u0609-\u060a\u060c-\u060d\u061b\u061e-\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0964-\u0965\u0970\u0df4\u0e4f\u0e5a-\u0e5b\u0f04-\u0f12\u0f3a-\u0f3d\u0f85\u0fd0-\u0fd4\u104a-\u104f\u10fb\u1361-\u1368\u166d-\u166e\u169b-\u169c\u16eb-\u16ed\u1735-\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u180a\u1944-\u1945\u19de-\u19df\u1a1e-\u1a1f\u1b5a-\u1b60\u1c3b-\u1c3f\u1c7e-\u1c7f\u2000-\u206e\u207d-\u207e\u208d-\u208e\u3008-\u3009\u2768-\u2775\u27c5-\u27c6\u27e6-\u27ef\u2983-\u2998\u29d8-\u29db\u29fc-\u29fd\u2cf9-\u2cfc\u2cfe-\u2cff\u2e00-\u2e7e\u3000-\u303f\u30a0\u30fb\ua60d-\ua60f\ua673\ua67e\ua874-\ua877\ua8ce-\ua8cf\ua92e-\ua92f\ua95f\uaa5c-\uaa5f\ufd3e-\ufd3f\ufe10-\ufe19\ufe30-\ufe52\ufe54-\ufe61\ufe63\ufe68\ufe6a-\ufe6b\uff01-\uff03\uff05-\uff0a\uff0c-\uff0f\uff1a-\uff1b\uff1f-\uff20\uff3b-\uff3d\uff3f\uff5b\uff5d\uff5f-\uff65]|\ud800[\udd00-\udd01\udf9f\udfd0]|\ud802[\udd1f\udd3f\ude50-\ude58]|\ud809[\udc00-\udc7e]/, -q=/\s/,e=core.PositionFilter.FilterResult.FILTER_ACCEPT,l=core.PositionFilter.FilterResult.FILTER_REJECT,a=odf.WordBoundaryFilter.IncludeWhitespace.TRAILING,d=odf.WordBoundaryFilter.IncludeWhitespace.LEADING,m={NO_NEIGHBOUR:0,SPACE_CHAR:1,PUNCTUATION_CHAR:2,WORD_CHAR:3,OTHER:4};this.acceptPosition=function(f){var g=f.container(),p=f.leftNode(),q=f.rightNode(),r=f.unfilteredDomOffset,v=function(){return f.unfilteredDomOffset()-1};g.nodeType===n&&(null===q&&(q=c(g,1,f.getNodeFilter())),null===p&&(p= -c(g,-1,f.getNodeFilter())));g!==q&&(r=function(){return 0});g!==p&&null!==p&&(v=function(){return p.textContent.length-1});g=b(p,v);q=b(q,r);return g===m.WORD_CHAR&&q===m.WORD_CHAR||g===m.PUNCTUATION_CHAR&&q===m.PUNCTUATION_CHAR||k===a&&g!==m.NO_NEIGHBOUR&&q===m.SPACE_CHAR||k===d&&g===m.SPACE_CHAR&&q!==m.NO_NEIGHBOUR?l:e}};odf.WordBoundaryFilter.IncludeWhitespace={None:0,TRAILING:1,LEADING:2}; -gui.SelectionController=function(g,k){function c(a){var b=a.spec();if(a.isEdit||b.memberid===k)I=void 0,K.cancel()}function b(){var a=x.getCursor(k).getNode();return x.createStepIterator(a,0,[v,t],x.getRootElement(a))}function f(a,b,d){d=new odf.WordBoundaryFilter(x,d);var c=x.getRootElement(a)||x.getRootNode(),e=x.createRootFilter(c);return x.createStepIterator(a,b,[v,e,d],c)}function n(a,b){return b?{anchorNode:a.startContainer,anchorOffset:a.startOffset,focusNode:a.endContainer,focusOffset:a.endOffset}: -{anchorNode:a.endContainer,anchorOffset:a.endOffset,focusNode:a.startContainer,focusOffset:a.startOffset}}function p(a,b,d){var c=new ops.OpMoveCursor;c.init({memberid:k,position:a,length:b||0,selectionType:d});return c}function r(a,b,d){var c;c=x.getCursor(k);c=n(c.getSelectedRange(),c.hasForwardSelection());c.focusNode=a;c.focusOffset=b;d||(c.anchorNode=c.focusNode,c.anchorOffset=c.focusOffset);a=x.convertDomToCursorRange(c);g.enqueue([p(a.position,a.length)])}function q(a){var b;b=f(a.startContainer, -a.startOffset,L);b.roundToPreviousStep()&&a.setStart(b.container(),b.offset());b=f(a.endContainer,a.endOffset,E);b.roundToNextStep()&&a.setEnd(b.container(),b.offset())}function e(a){var b=w.getParagraphElements(a),d=b[0],b=b[b.length-1];d&&a.setStart(d,0);b&&(w.isParagraph(a.endContainer)&&0===a.endOffset?a.setEndBefore(b):a.setEnd(b,b.childNodes.length))}function l(a,b,d,c){var e,f;c?(e=d.startContainer,f=d.startOffset):(e=d.endContainer,f=d.endOffset);z.containsNode(a,e)||(f=0>z.comparePoints(a, -0,e,f)?0:a.childNodes.length,e=a);a=x.createStepIterator(e,f,b,w.getParagraphElement(e)||a);a.roundToClosestStep()||runtime.assert(!1,"No step found in requested range");c?d.setStart(a.container(),a.offset()):d.setEnd(a.container(),a.offset())}function a(a,d){var c=b();c.advanceStep(a)&&r(c.container(),c.offset(),d)}function d(a,d){var c,e=I,f=[new gui.LineBoundaryScanner,new gui.ParagraphBoundaryScanner];void 0===e&&A&&(e=A());isNaN(e)||(c=b(),u.moveToFilteredStep(c,a,f)&&c.advanceStep(a)&&(f=[new gui.ClosestXOffsetScanner(e), -new gui.LineBoundaryScanner,new gui.ParagraphBoundaryScanner],u.moveToFilteredStep(c,a,f)&&(r(c.container(),c.offset(),d),I=e,K.restart())))}function m(a,d){var c=b(),e=[new gui.LineBoundaryScanner,new gui.ParagraphBoundaryScanner];u.moveToFilteredStep(c,a,e)&&r(c.container(),c.offset(),d)}function h(a,b){var d=x.getCursor(k),d=n(d.getSelectedRange(),d.hasForwardSelection()),d=f(d.focusNode,d.focusOffset,L);d.advanceStep(a)&&r(d.container(),d.offset(),b)}function y(a,b,d){var c=!1,e=x.getCursor(k), -e=n(e.getSelectedRange(),e.hasForwardSelection()),c=x.getRootElement(e.focusNode);runtime.assert(Boolean(c),"SelectionController: Cursor outside root");e=x.createStepIterator(e.focusNode,e.focusOffset,[v,t],c);e.roundToClosestStep();e.advanceStep(a)&&(d=d(e.container()))&&(a===N?(e.setPosition(d,0),c=e.roundToNextStep()):(e.setPosition(d,d.childNodes.length),c=e.roundToPreviousStep()),c&&r(e.container(),e.offset(),b))}var x=g.getOdtDocument(),z=core.DomUtils,w=odf.OdfUtils,v=x.getPositionFilter(), -u=new gui.GuiStepUtils,t=x.createRootFilter(k),A=null,I,K,L=odf.WordBoundaryFilter.IncludeWhitespace.TRAILING,E=odf.WordBoundaryFilter.IncludeWhitespace.LEADING,N=core.StepDirection.PREVIOUS,O=core.StepDirection.NEXT;this.selectionToRange=function(a){var b=0<=z.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset),d=a.focusNode.ownerDocument.createRange();b?(d.setStart(a.anchorNode,a.anchorOffset),d.setEnd(a.focusNode,a.focusOffset)):(d.setStart(a.focusNode,a.focusOffset),d.setEnd(a.anchorNode, -a.anchorOffset));return{range:d,hasForwardSelection:b}};this.rangeToSelection=n;this.selectImage=function(a){var b=x.getRootElement(a),d=x.createRootFilter(b),b=x.createStepIterator(a,0,[d,x.getPositionFilter()],b),c;b.roundToPreviousStep()||runtime.assert(!1,"No walkable position before frame");d=b.container();c=b.offset();b.setPosition(a,a.childNodes.length);b.roundToNextStep()||runtime.assert(!1,"No walkable position after frame");a=x.convertDomToCursorRange({anchorNode:d,anchorOffset:c,focusNode:b.container(), -focusOffset:b.offset()});a=p(a.position,a.length,ops.OdtCursor.RegionSelection);g.enqueue([a])};this.expandToWordBoundaries=q;this.expandToParagraphBoundaries=e;this.selectRange=function(a,b,d){var c=x.getOdfCanvas().getElement(),f,h=[v];f=z.containsNode(c,a.startContainer);c=z.containsNode(c,a.endContainer);if(f||c)if(f&&c&&(2===d?q(a):3<=d&&e(a)),(d=b?x.getRootElement(a.startContainer):x.getRootElement(a.endContainer))||(d=x.getRootNode()),h.push(x.createRootFilter(d)),l(d,h,a,!0),l(d,h,a,!1),a= -n(a,b),b=x.convertDomToCursorRange(a),a=x.getCursorSelection(k),b.position!==a.position||b.length!==a.length)a=p(b.position,b.length,ops.OdtCursor.RangeSelection),g.enqueue([a])};this.moveCursorToLeft=function(){a(N,!1);return!0};this.moveCursorToRight=function(){a(O,!1);return!0};this.extendSelectionToLeft=function(){a(N,!0);return!0};this.extendSelectionToRight=function(){a(O,!0);return!0};this.setCaretXPositionLocator=function(a){A=a};this.moveCursorUp=function(){d(N,!1);return!0};this.moveCursorDown= -function(){d(O,!1);return!0};this.extendSelectionUp=function(){d(N,!0);return!0};this.extendSelectionDown=function(){d(O,!0);return!0};this.moveCursorBeforeWord=function(){h(N,!1);return!0};this.moveCursorPastWord=function(){h(O,!1);return!0};this.extendSelectionBeforeWord=function(){h(N,!0);return!0};this.extendSelectionPastWord=function(){h(O,!0);return!0};this.moveCursorToLineStart=function(){m(N,!1);return!0};this.moveCursorToLineEnd=function(){m(O,!1);return!0};this.extendSelectionToLineStart= -function(){m(N,!0);return!0};this.extendSelectionToLineEnd=function(){m(O,!0);return!0};this.extendSelectionToParagraphStart=function(){y(N,!0,w.getParagraphElement);return!0};this.extendSelectionToParagraphEnd=function(){y(O,!0,w.getParagraphElement);return!0};this.moveCursorToParagraphStart=function(){y(N,!1,w.getParagraphElement);return!0};this.moveCursorToParagraphEnd=function(){y(O,!1,w.getParagraphElement);return!0};this.moveCursorToDocumentStart=function(){y(N,!1,x.getRootElement);return!0}; -this.moveCursorToDocumentEnd=function(){y(O,!1,x.getRootElement);return!0};this.extendSelectionToDocumentStart=function(){y(N,!0,x.getRootElement);return!0};this.extendSelectionToDocumentEnd=function(){y(O,!0,x.getRootElement);return!0};this.extendSelectionToEntireDocument=function(){var a=x.getCursor(k),a=x.getRootElement(a.getNode()),b,d,c;runtime.assert(Boolean(a),"SelectionController: Cursor outside root");c=x.createStepIterator(a,0,[v,t],a);c.roundToClosestStep();b=c.container();d=c.offset(); -c.setPosition(a,a.childNodes.length);c.roundToClosestStep();a=x.convertDomToCursorRange({anchorNode:b,anchorOffset:d,focusNode:c.container(),focusOffset:c.offset()});g.enqueue([p(a.position,a.length)]);return!0};this.destroy=function(a){x.unsubscribe(ops.OdtDocument.signalOperationStart,c);core.Async.destroyAll([K.destroy],a)};(function(){K=core.Task.createTimeoutTask(function(){I=void 0},2E3);x.subscribe(ops.OdtDocument.signalOperationStart,c)})()}; -gui.TextController=function(g,k,c,b,f,n){function p(){y=!0===k.getState(gui.CommonConstraints.EDIT.REVIEW_MODE)?c.isLocalCursorWithinOwnAnnotation():!0}function r(a){a.getMemberId()===b&&p()}function q(a,b,c){var e=[d.getPositionFilter()];c&&e.push(d.createRootFilter(a.startContainer));c=d.createStepIterator(a.startContainer,a.startOffset,e,b);c.roundToClosestStep()||runtime.assert(!1,"No walkable step found in paragraph element at range start");b=d.convertDomPointToCursorStep(c.container(),c.offset()); -a.collapsed?a=b:(c.setPosition(a.endContainer,a.endOffset),c.roundToClosestStep()||runtime.assert(!1,"No walkable step found in paragraph element at range end"),a=d.convertDomPointToCursorStep(c.container(),c.offset()));return{position:b,length:a-b}}function e(a){var d,c,e,f=m.getParagraphElements(a),g=a.cloneRange(),l=[];d=f[0];1a.length&&(a.position+=a.length,a.length=-a.length);return a}function a(a){if(!y)return!1;var c,f=d.getCursor(b).getSelectedRange().cloneRange(), -h=l(d.getCursorSelection(b)),m;if(0===h.length){h=void 0;c=d.getCursor(b).getNode();m=d.getRootElement(c);var k=[d.getPositionFilter(),d.createRootFilter(m)];m=d.createStepIterator(c,0,k,m);m.roundToClosestStep()&&(a?m.nextStep():m.previousStep())&&(h=l(d.convertDomToCursorRange({anchorNode:c,anchorOffset:0,focusNode:m.container(),focusOffset:m.offset()})),a?(f.setStart(c,0),f.setEnd(m.container(),m.offset())):(f.setStart(m.container(),m.offset()),f.setEnd(c,0)))}h&&g.enqueue(e(f));return void 0!== -h}var d=g.getOdtDocument(),m=odf.OdfUtils,h=core.DomUtils,y=!1,x=odf.Namespaces.textns,z=core.StepDirection.NEXT;this.isEnabled=function(){return y};this.enqueueParagraphSplittingOps=function(){if(!y)return!1;var a=d.getCursor(b),c=a.getSelectedRange(),f=l(d.getCursorSelection(b)),h=[],a=m.getParagraphElement(a.getNode()),k=a.getAttributeNS(x,"style-name")||"";0c.left&&(c=v(e)))b.focusNode=c.container,b.focusOffset=c.offset, -d&&(b.anchorNode=b.focusNode,b.anchorOffset=b.focusOffset)}else S.isImage(b.focusNode.firstChild)&&1===b.focusOffset&&S.isCharacterFrame(b.focusNode)&&(c=v(b.focusNode))&&(b.anchorNode=b.focusNode=c.container,b.anchorOffset=b.focusOffset=c.offset);b.anchorNode&&b.focusNode&&(b=T.selectionToRange(b),T.selectRange(b.range,b.hasForwardSelection,0===a.button?a.detail:0));F.focus()}function t(a){var b;if(b=n(a.clientX,a.clientY))a=b.container,b=b.offset,a={anchorNode:a,anchorOffset:b,focusNode:a,focusOffset:b}, -a=T.selectionToRange(a),T.selectRange(a.range,a.hasForwardSelection,2),F.focus()}function A(a){var d=a.target||a.srcElement||null,c,e,f;ma.processRequests();U&&(S.isImage(d)&&S.isCharacterFrame(d.parentNode)&&W.getSelection().isCollapsed?(T.selectImage(d.parentNode),F.focus()):la.isSelectorElement(d)?F.focus():B?(d=b.getSelectedRange(),e=d.collapsed,S.isImage(d.endContainer)&&0===d.endOffset&&S.isCharacterFrame(d.endContainer.parentNode)&&(f=d.endContainer.parentNode,f=v(f))&&(d.setEnd(f.container, -f.offset),e&&d.collapse(!1)),T.selectRange(d,b.hasForwardSelection(),0===a.button?a.detail:0),F.focus()):ua?u(a):(c=aa.cloneEvent(a),M=runtime.setTimeout(function(){u(c)},0)),oa=0,B=U=!1)}function I(a){var b=J.getCursor(c).getSelectedRange();b.collapsed||fa.exportRangeToDataTransfer(a.dataTransfer,b)}function K(){U&&F.focus();oa=0;B=U=!1}function L(a){A(a)}function E(a){var b=a.target||a.srcElement||null,d=null;"annotationRemoveButton"===b.className?(runtime.assert(ja,"Remove buttons are displayed on annotations while annotation editing is disabled in the controller."), -d=b.parentNode.getElementsByTagNameNS(odf.Namespaces.officens,"annotation").item(0),ca.removeAnnotation(d),F.focus()):"webodf-draggable"!==b.getAttribute("class")&&A(a)}function N(a){(a=a.data)&&(-1===a.indexOf("\n")?da.insertText(a):ea.paste(a))}function O(a){return function(){a();return!0}}function D(a){return function(b){return J.getCursor(c).getSelectionType()===ops.OdtCursor.RangeSelection?a(b):!0}}function V(b){F.unsubscribe("keydown",C.handleEvent);F.unsubscribe("keypress",Z.handleEvent);F.unsubscribe("keyup", -ba.handleEvent);F.unsubscribe("copy",q);F.unsubscribe("mousedown",w);F.unsubscribe("mousemove",ma.trigger);F.unsubscribe("mouseup",E);F.unsubscribe("contextmenu",L);F.unsubscribe("dragstart",I);F.unsubscribe("dragend",K);F.unsubscribe("click",pa.handleClick);F.unsubscribe("longpress",t);F.unsubscribe("drag",y);F.unsubscribe("dragstop",x);J.unsubscribe(ops.OdtDocument.signalOperationEnd,na.trigger);J.unsubscribe(ops.Document.signalCursorAdded,ka.registerCursor);J.unsubscribe(ops.Document.signalCursorRemoved, -ka.removeCursor);J.unsubscribe(ops.OdtDocument.signalOperationEnd,a);b()}var W=runtime.getWindow(),J=k.getOdtDocument(),R=new gui.SessionConstraints,P=new gui.SessionContext(k,c),aa=core.DomUtils,S=odf.OdfUtils,fa=new gui.MimeDataExporter,ha=new gui.Clipboard(fa),C=new gui.KeyboardHandler,Z=new gui.KeyboardHandler,ba=new gui.KeyboardHandler,U=!1,ga=new odf.ObjectNameGenerator(J.getOdfCanvas().odfContainer(),c),B=!1,Y=null,M,Q=null,F=new gui.EventManager(J),ja=f.annotationsEnabled,ca=new gui.AnnotationController(k, -R,c),X=new gui.DirectFormattingController(k,R,P,c,ga,f.directTextStylingEnabled,f.directParagraphStylingEnabled),da=new gui.TextController(k,R,P,c,X.createCursorStyleOp,X.createParagraphStyleOps),qa=new gui.ImageController(k,R,P,c,ga),la=new gui.ImageSelector(J.getOdfCanvas()),ia=J.createPositionIterator(J.getRootNode()),ma,na,ea=new gui.PasteController(k,R,P,c),ka=new gui.InputMethodEditor(c,F),oa=0,pa=new gui.HyperlinkClickHandler(J.getOdfCanvas().getElement,C,ba),ta=new gui.HyperlinkController(k, -R,P,c),T=new gui.SelectionController(k,c),va=new gui.MetadataController(k,c),G=gui.KeyboardHandler.Modifier,H=gui.KeyboardHandler.KeyCode,ra=-1!==W.navigator.appVersion.toLowerCase().indexOf("mac"),ua=-1!==["iPad","iPod","iPhone"].indexOf(W.navigator.platform),sa;runtime.assert(null!==W,"Expected to be run in an environment which has a global window, like a browser.");this.undo=m;this.redo=h;this.insertLocalCursor=function(){runtime.assert(void 0===k.getOdtDocument().getCursor(c),"Inserting local cursor a second time."); -var a=new ops.OpAddCursor;a.init({memberid:c});k.enqueue([a]);F.focus()};this.removeLocalCursor=function(){runtime.assert(void 0!==k.getOdtDocument().getCursor(c),"Removing local cursor without inserting before.");var a=new ops.OpRemoveCursor;a.init({memberid:c});k.enqueue([a])};this.startEditing=function(){ka.subscribe(gui.InputMethodEditor.signalCompositionStart,da.removeCurrentSelection);ka.subscribe(gui.InputMethodEditor.signalCompositionEnd,N);F.subscribe("beforecut",r);F.subscribe("cut",p); -F.subscribe("beforepaste",l);F.subscribe("paste",e);Q&&Q.initialize();F.setEditing(!0);pa.setModifier(ra?G.Meta:G.Ctrl);C.bind(H.Backspace,G.None,O(da.removeTextByBackspaceKey),!0);C.bind(H.Delete,G.None,da.removeTextByDeleteKey);C.bind(H.Tab,G.None,D(function(){da.insertText("\t");return!0}));ra?(C.bind(H.Clear,G.None,da.removeCurrentSelection),C.bind(H.B,G.Meta,D(X.toggleBold)),C.bind(H.I,G.Meta,D(X.toggleItalic)),C.bind(H.U,G.Meta,D(X.toggleUnderline)),C.bind(H.L,G.MetaShift,D(X.alignParagraphLeft)), -C.bind(H.E,G.MetaShift,D(X.alignParagraphCenter)),C.bind(H.R,G.MetaShift,D(X.alignParagraphRight)),C.bind(H.J,G.MetaShift,D(X.alignParagraphJustified)),ja&&C.bind(H.C,G.MetaShift,ca.addAnnotation),C.bind(H.Z,G.Meta,m),C.bind(H.Z,G.MetaShift,h)):(C.bind(H.B,G.Ctrl,D(X.toggleBold)),C.bind(H.I,G.Ctrl,D(X.toggleItalic)),C.bind(H.U,G.Ctrl,D(X.toggleUnderline)),C.bind(H.L,G.CtrlShift,D(X.alignParagraphLeft)),C.bind(H.E,G.CtrlShift,D(X.alignParagraphCenter)),C.bind(H.R,G.CtrlShift,D(X.alignParagraphRight)), -C.bind(H.J,G.CtrlShift,D(X.alignParagraphJustified)),ja&&C.bind(H.C,G.CtrlAlt,ca.addAnnotation),C.bind(H.Z,G.Ctrl,m),C.bind(H.Z,G.CtrlShift,h));Z.setDefault(D(function(a){var b;b=null===a.which||void 0===a.which?String.fromCharCode(a.keyCode):0!==a.which&&0!==a.charCode?String.fromCharCode(a.which):null;return!b||a.altKey||a.ctrlKey||a.metaKey?!1:(da.insertText(b),!0)}));Z.bind(H.Enter,G.None,D(da.enqueueParagraphSplittingOps))};this.endEditing=function(){ka.unsubscribe(gui.InputMethodEditor.signalCompositionStart, -da.removeCurrentSelection);ka.unsubscribe(gui.InputMethodEditor.signalCompositionEnd,N);F.unsubscribe("cut",p);F.unsubscribe("beforecut",r);F.unsubscribe("paste",e);F.unsubscribe("beforepaste",l);F.setEditing(!1);pa.setModifier(G.None);C.bind(H.Backspace,G.None,function(){return!0},!0);C.unbind(H.Delete,G.None);C.unbind(H.Tab,G.None);ra?(C.unbind(H.Clear,G.None),C.unbind(H.B,G.Meta),C.unbind(H.I,G.Meta),C.unbind(H.U,G.Meta),C.unbind(H.L,G.MetaShift),C.unbind(H.E,G.MetaShift),C.unbind(H.R,G.MetaShift), -C.unbind(H.J,G.MetaShift),ja&&C.unbind(H.C,G.MetaShift),C.unbind(H.Z,G.Meta),C.unbind(H.Z,G.MetaShift)):(C.unbind(H.B,G.Ctrl),C.unbind(H.I,G.Ctrl),C.unbind(H.U,G.Ctrl),C.unbind(H.L,G.CtrlShift),C.unbind(H.E,G.CtrlShift),C.unbind(H.R,G.CtrlShift),C.unbind(H.J,G.CtrlShift),ja&&C.unbind(H.C,G.CtrlAlt),C.unbind(H.Z,G.Ctrl),C.unbind(H.Z,G.CtrlShift));Z.setDefault(null);Z.unbind(H.Enter,G.None)};this.getInputMemberId=function(){return c};this.getSession=function(){return k};this.getSessionConstraints=function(){return R}; -this.setUndoManager=function(a){Q&&Q.unsubscribe(gui.UndoManager.signalUndoStackChanged,d);if(Q=a)Q.setDocument(J),Q.setPlaybackFunction(k.enqueue),Q.subscribe(gui.UndoManager.signalUndoStackChanged,d)};this.getUndoManager=function(){return Q};this.getMetadataController=function(){return va};this.getAnnotationController=function(){return ca};this.getDirectFormattingController=function(){return X};this.getHyperlinkClickHandler=function(){return pa};this.getHyperlinkController=function(){return ta}; -this.getImageController=function(){return qa};this.getSelectionController=function(){return T};this.getTextController=function(){return da};this.getEventManager=function(){return F};this.getKeyboardHandlers=function(){return{keydown:C,keypress:Z}};this.destroy=function(a){var b=[ma.destroy,na.destroy,X.destroy,ka.destroy,F.destroy,pa.destroy,ta.destroy,va.destroy,T.destroy,da.destroy,V];sa&&b.unshift(sa.destroy);runtime.clearTimeout(M);core.Async.destroyAll(b,a)};ma=core.Task.createRedrawTask(z); -na=core.Task.createRedrawTask(function(){var a=J.getCursor(c);if(a&&a.getSelectionType()===ops.OdtCursor.RegionSelection&&(a=S.getImageElements(a.getSelectedRange())[0])){la.select(a.parentNode);return}la.clearSelection()});C.bind(H.Left,G.None,D(T.moveCursorToLeft));C.bind(H.Right,G.None,D(T.moveCursorToRight));C.bind(H.Up,G.None,D(T.moveCursorUp));C.bind(H.Down,G.None,D(T.moveCursorDown));C.bind(H.Left,G.Shift,D(T.extendSelectionToLeft));C.bind(H.Right,G.Shift,D(T.extendSelectionToRight));C.bind(H.Up, -G.Shift,D(T.extendSelectionUp));C.bind(H.Down,G.Shift,D(T.extendSelectionDown));C.bind(H.Home,G.None,D(T.moveCursorToLineStart));C.bind(H.End,G.None,D(T.moveCursorToLineEnd));C.bind(H.Home,G.Ctrl,D(T.moveCursorToDocumentStart));C.bind(H.End,G.Ctrl,D(T.moveCursorToDocumentEnd));C.bind(H.Home,G.Shift,D(T.extendSelectionToLineStart));C.bind(H.End,G.Shift,D(T.extendSelectionToLineEnd));C.bind(H.Up,G.CtrlShift,D(T.extendSelectionToParagraphStart));C.bind(H.Down,G.CtrlShift,D(T.extendSelectionToParagraphEnd)); -C.bind(H.Home,G.CtrlShift,D(T.extendSelectionToDocumentStart));C.bind(H.End,G.CtrlShift,D(T.extendSelectionToDocumentEnd));ra?(C.bind(H.Left,G.Alt,D(T.moveCursorBeforeWord)),C.bind(H.Right,G.Alt,D(T.moveCursorPastWord)),C.bind(H.Left,G.Meta,D(T.moveCursorToLineStart)),C.bind(H.Right,G.Meta,D(T.moveCursorToLineEnd)),C.bind(H.Home,G.Meta,D(T.moveCursorToDocumentStart)),C.bind(H.End,G.Meta,D(T.moveCursorToDocumentEnd)),C.bind(H.Left,G.AltShift,D(T.extendSelectionBeforeWord)),C.bind(H.Right,G.AltShift, -D(T.extendSelectionPastWord)),C.bind(H.Left,G.MetaShift,D(T.extendSelectionToLineStart)),C.bind(H.Right,G.MetaShift,D(T.extendSelectionToLineEnd)),C.bind(H.Up,G.AltShift,D(T.extendSelectionToParagraphStart)),C.bind(H.Down,G.AltShift,D(T.extendSelectionToParagraphEnd)),C.bind(H.Up,G.MetaShift,D(T.extendSelectionToDocumentStart)),C.bind(H.Down,G.MetaShift,D(T.extendSelectionToDocumentEnd)),C.bind(H.A,G.Meta,D(T.extendSelectionToEntireDocument))):(C.bind(H.Left,G.Ctrl,D(T.moveCursorBeforeWord)),C.bind(H.Right, -G.Ctrl,D(T.moveCursorPastWord)),C.bind(H.Left,G.CtrlShift,D(T.extendSelectionBeforeWord)),C.bind(H.Right,G.CtrlShift,D(T.extendSelectionPastWord)),C.bind(H.A,G.Ctrl,D(T.extendSelectionToEntireDocument)));ua&&(sa=new gui.IOSSafariSupport(F));F.subscribe("keydown",C.handleEvent);F.subscribe("keypress",Z.handleEvent);F.subscribe("keyup",ba.handleEvent);F.subscribe("copy",q);F.subscribe("mousedown",w);F.subscribe("mousemove",ma.trigger);F.subscribe("mouseup",E);F.subscribe("contextmenu",L);F.subscribe("dragstart", -I);F.subscribe("dragend",K);F.subscribe("click",pa.handleClick);F.subscribe("longpress",t);F.subscribe("drag",y);F.subscribe("dragstop",x);J.subscribe(ops.OdtDocument.signalOperationEnd,na.trigger);J.subscribe(ops.Document.signalCursorAdded,ka.registerCursor);J.subscribe(ops.Document.signalCursorRemoved,ka.removeCursor);J.subscribe(ops.OdtDocument.signalOperationEnd,a)}})(); -gui.CaretManager=function(g,k){function c(b){return n.hasOwnProperty(b)?n[b]:null}function b(){return Object.keys(n).map(function(b){return n[b]})}function f(b){var c=n[b];c&&(delete n[b],b===g.getInputMemberId()?(r.unsubscribe(ops.OdtDocument.signalProcessingBatchEnd,c.ensureVisible),r.unsubscribe(ops.Document.signalCursorMoved,c.refreshCursorBlinking),q.unsubscribe("compositionupdate",c.handleUpdate),q.unsubscribe("compositionend",c.handleUpdate),q.unsubscribe("focus",c.setFocus),q.unsubscribe("blur", -c.removeFocus),p.removeEventListener("focus",c.show,!1),p.removeEventListener("blur",c.hide,!1)):r.unsubscribe(ops.OdtDocument.signalProcessingBatchEnd,c.handleUpdate),c.destroy(function(){}))}var n={},p=runtime.getWindow(),r=g.getSession().getOdtDocument(),q=g.getEventManager();this.registerCursor=function(b,c,a){var d=b.getMemberId();b=new gui.Caret(b,k,c,a);n[d]=b;d===g.getInputMemberId()?(runtime.log("Starting to track input on new cursor of "+d),r.subscribe(ops.OdtDocument.signalProcessingBatchEnd, -b.ensureVisible),r.subscribe(ops.Document.signalCursorMoved,b.refreshCursorBlinking),q.subscribe("compositionupdate",b.handleUpdate),q.subscribe("compositionend",b.handleUpdate),q.subscribe("focus",b.setFocus),q.subscribe("blur",b.removeFocus),p.addEventListener("focus",b.show,!1),p.addEventListener("blur",b.hide,!1),b.setOverlayElement(q.getEventTrap())):r.subscribe(ops.OdtDocument.signalProcessingBatchEnd,b.handleUpdate);return b};this.getCaret=c;this.getCarets=b;this.destroy=function(c){var l= -b().map(function(a){return a.destroy});g.getSelectionController().setCaretXPositionLocator(null);r.unsubscribe(ops.Document.signalCursorRemoved,f);n={};core.Async.destroyAll(l,c)};g.getSelectionController().setCaretXPositionLocator(function(){var b=c(g.getInputMemberId()),f;b&&(f=b.getBoundingClientRect());return f?f.right:void 0});r.subscribe(ops.Document.signalCursorRemoved,f)}; -gui.EditInfoHandle=function(g){var k=[],c,b=g.ownerDocument,f=b.documentElement.namespaceURI;this.setEdits=function(g){k=g;var p,r,q,e;core.DomUtils.removeAllChildNodes(c);for(g=0;gd?(r=c(1,0),q=c(.5,1E4-d),e=c(.2,2E4-d)):1E4<=d&&2E4>d?(r=c(.5,0),e=c(.2,2E4-d)):r=c(.2,0)};this.getEdits=function(){return g.getEdits()};this.clearEdits=function(){g.clearEdits(); -n.setEdits([]);p.hasAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")&&p.removeAttributeNS("urn:webodf:names:editinfo","editinfo:memberid")};this.getEditInfo=function(){return g};this.show=function(){p.style.display="block"};this.hide=function(){b.hideHandle();p.style.display="none"};this.showHandle=function(){n.show()};this.hideHandle=function(){n.hide()};this.destroy=function(b){runtime.clearTimeout(r);runtime.clearTimeout(q);runtime.clearTimeout(e);f.removeChild(p);n.destroy(function(a){a? -b(a):g.destroy(b)})};(function(){var c=g.getOdtDocument().getDOMDocument();p=c.createElementNS(c.documentElement.namespaceURI,"div");p.setAttribute("class","editInfoMarker");p.onmouseover=function(){b.showHandle()};p.onmouseout=function(){b.hideHandle()};f=g.getNode();f.appendChild(p);n=new gui.EditInfoHandle(f);k||b.hide()})()}; -gui.HyperlinkTooltipView=function(g,k){var c=core.DomUtils,b=odf.OdfUtils,f=runtime.getWindow(),n,p,r;runtime.assert(null!==f,"Expected to be run in an environment which has a global window, like a browser.");this.showTooltip=function(q){var e=q.target||q.srcElement,l=g.getSizer(),a=g.getZoomLevel(),d;a:{for(;e;){if(b.isHyperlink(e))break a;if(b.isParagraph(e)||b.isInlineRoot(e))break;e=e.parentNode}e=null}if(e){c.containsNode(l,r)||l.appendChild(r);d=p;var m;switch(k()){case gui.KeyboardHandler.Modifier.Ctrl:m= -runtime.tr("Ctrl-click to follow link");break;case gui.KeyboardHandler.Modifier.Meta:m=runtime.tr("\u2318-click to follow link");break;default:m=""}d.textContent=m;n.textContent=b.getHyperlinkTarget(e);r.style.display="block";d=f.innerWidth-r.offsetWidth-15;e=q.clientX>d?d:q.clientX+15;d=f.innerHeight-r.offsetHeight-10;q=q.clientY>d?d:q.clientY+10;l=l.getBoundingClientRect();e=(e-l.left)/a;q=(q-l.top)/a;r.style.left=e+"px";r.style.top=q+"px"}};this.hideTooltip=function(){r.style.display="none"};this.destroy= -function(b){r.parentNode&&r.parentNode.removeChild(r);b()};(function(){var b=g.getElement().ownerDocument;n=b.createElement("span");p=b.createElement("span");n.className="webodf-hyperlinkTooltipLink";p.className="webodf-hyperlinkTooltipText";r=b.createElement("div");r.className="webodf-hyperlinkTooltip";r.appendChild(n);r.appendChild(p);g.getElement().appendChild(r)})()}; -gui.OdfFieldView=function(g){function k(){var b=odf.OdfSchema.getFields().map(function(b){return b.replace(":","|")}),c=b.join(",\n")+"\n{ background-color: #D0D0D0; }\n",b=b.map(function(b){return b+":empty::after"}).join(",\n")+"\n{ content:' '; white-space: pre; }\n";return c+"\n"+b}var c,b=g.getElement().ownerDocument;this.showFieldHighlight=function(){c.appendChild(b.createTextNode(k()))};this.hideFieldHighlight=function(){for(var b=c.sheet,g=b.cssRules;g.length;)b.deleteRule(g.length-1)};this.destroy= -function(b){c.parentNode&&c.parentNode.removeChild(c);b()};c=function(){var c=b.getElementsByTagName("head").item(0),g=b.createElement("style"),k="";g.type="text/css";g.media="screen, print, handheld, projection";odf.Namespaces.forEachPrefix(function(b,c){k+="@namespace "+b+" url("+c+");\n"});g.appendChild(b.createTextNode(k));c.appendChild(g);return g}()}; -gui.ShadowCursor=function(g){var k=g.getDOMDocument().createRange(),c=!0;this.removeFromDocument=function(){};this.getMemberId=function(){return gui.ShadowCursor.ShadowCursorMemberId};this.getSelectedRange=function(){return k};this.setSelectedRange=function(b,f){k=b;c=!1!==f};this.hasForwardSelection=function(){return c};this.getDocument=function(){return g};this.getSelectionType=function(){return ops.OdtCursor.RangeSelection};k.setStart(g.getRootNode(),0)};gui.ShadowCursor.ShadowCursorMemberId=""; -gui.SelectionView=function(g){};gui.SelectionView.prototype.rerender=function(){};gui.SelectionView.prototype.show=function(){};gui.SelectionView.prototype.hide=function(){};gui.SelectionView.prototype.destroy=function(g){}; -gui.SelectionViewManager=function(g){function k(){return Object.keys(c).map(function(b){return c[b]})}var c={};this.getSelectionView=function(b){return c.hasOwnProperty(b)?c[b]:null};this.getSelectionViews=k;this.removeSelectionView=function(b){c.hasOwnProperty(b)&&(c[b].destroy(function(){}),delete c[b])};this.hideSelectionView=function(b){c.hasOwnProperty(b)&&c[b].hide()};this.showSelectionView=function(b){c.hasOwnProperty(b)&&c[b].show()};this.rerenderSelectionViews=function(){Object.keys(c).forEach(function(b){c[b].rerender()})}; -this.registerCursor=function(b,f){var k=b.getMemberId(),p=new g(b);f?p.show():p.hide();return c[k]=p};this.destroy=function(b){function c(k,r){r?b(r):k .webodf-draggable"),a=gui.ShadowCursor.ShadowCursorMemberId,e(".webodf-selectionOverlay","{ fill: "+d+"; stroke: "+d+";}",""),e(".webodf-touchEnabled .webodf-selectionOverlay","{ display: block; }"," > .webodf-draggable"))}function l(a){var b,d;for(d in t)t.hasOwnProperty(d)&&(b=t[d],a?b.show():b.hide())}function a(a){n.getCarets().forEach(function(b){a?b.showHandle():b.hideHandle()})}function d(a){var b=a.getMemberId();a=a.getProperties();e(b,a.fullName,a.color)}function m(a){var d= -a.getMemberId(),c=b.getOdtDocument().getMember(d).getProperties();n.registerCursor(a,E,N);p.registerCursor(a,!0);if(a=n.getCaret(d))a.setAvatarImageUrl(c.imageUrl),a.setColor(c.color);runtime.log("+++ View here +++ eagerly created an Caret for '"+d+"'! +++")}function h(a){a=a.getMemberId();var b=p.getSelectionView(c),d=p.getSelectionView(gui.ShadowCursor.ShadowCursorMemberId),e=n.getCaret(c);a===c?(d.hide(),b&&b.show(),e&&e.show()):a===gui.ShadowCursor.ShadowCursorMemberId&&(d.show(),b&&b.hide(), -e&&e.hide())}function y(a){p.removeSelectionView(a)}function x(a){var d=a.paragraphElement,c=a.memberId;a=a.timeStamp;var e,f="",h=d.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo").item(0);h?(f=h.getAttributeNS("urn:webodf:names:editinfo","id"),e=t[f]):(f=Math.random().toString(),e=new ops.EditInfo(d,b.getOdtDocument()),e=new gui.EditInfoMarker(e,L),h=d.getElementsByTagNameNS("urn:webodf:names:editinfo","editinfo").item(0),h.setAttributeNS("urn:webodf:names:editinfo","id",f),t[f]=e); -e.addEdit(c,new Date(a));K.trigger()}function z(){var a;u.hasChildNodes()&&core.DomUtils.removeAllChildNodes(u);!0===f.getState(gui.CommonConstraints.EDIT.ANNOTATIONS.ONLY_DELETE_OWN)&&(a=b.getOdtDocument().getMember(c))&&(a=a.getProperties().fullName,u.appendChild(document.createTextNode(".annotationWrapper:not([creator = '"+a+"']) .annotationRemoveButton { display: none; }")))}function w(a){var b=Object.keys(t).map(function(a){return t[a]});A.unsubscribe(ops.Document.signalMemberAdded,d);A.unsubscribe(ops.Document.signalMemberUpdated, -d);A.unsubscribe(ops.Document.signalCursorAdded,m);A.unsubscribe(ops.Document.signalCursorRemoved,y);A.unsubscribe(ops.OdtDocument.signalParagraphChanged,x);A.unsubscribe(ops.Document.signalCursorMoved,h);A.unsubscribe(ops.OdtDocument.signalParagraphChanged,p.rerenderSelectionViews);A.unsubscribe(ops.OdtDocument.signalTableAdded,p.rerenderSelectionViews);A.unsubscribe(ops.OdtDocument.signalParagraphStyleModified,p.rerenderSelectionViews);f.unsubscribe(gui.CommonConstraints.EDIT.ANNOTATIONS.ONLY_DELETE_OWN, -z);A.unsubscribe(ops.Document.signalMemberAdded,z);A.unsubscribe(ops.Document.signalMemberUpdated,z);v.parentNode.removeChild(v);u.parentNode.removeChild(u);(function W(d,c){c?a(c):da.length;b&&g(a);return b}function c(a,b){function c(f){a[f]===b&&e.push(f)}var e=[];a&&["style:parent-style-name","style:next-style-name"].forEach(c);return e}function b(a,b){function c(e){a[e]===b&&delete a[e]}a&&["style:parent-style-name","style:next-style-name"].forEach(c)}function f(a){var b={};Object.keys(a).forEach(function(c){b[c]="object"===typeof a[c]?f(a[c]):a[c]});return b}function n(a, -b,c,e){var f,g=!1,k=!1,l,n=[];e&&e.attributes&&(n=e.attributes.split(","));a&&(c||0=a.length?0:a.length-f.length)):void 0!==a.length&&(f=a.position+a.length,e<=f?a.length-=b.length:c=b.position+b.length)){e=c?a:b;g=c?b:a;if(a.position!==b.position||a.length!==b.length)r=f(e),u=f(g);b=q(g.setProperties,null,e.setProperties, -null,"style:text-properties");if(b.majorChanged||b.minorChanged)k=[],a=[],l=e.position+e.length,n=g.position+g.length,g.positionl?b.minorChanged&&(r=u,r.position=l,r.length=n-l,a.push(r),g.length=l-g.position):l>n&&b.majorChanged&&(r.position=n, -r.length=l-n,k.push(r),e.length=n-e.position),e.setProperties&&p(e.setProperties)&&k.push(e),g.setProperties&&p(g.setProperties)&&a.push(g),c?(l=k,k=a):l=a}return{opSpecsA:l,opSpecsB:k}},InsertText:function(a,b){b.position<=a.position?a.position+=b.text.length:b.position<=a.position+a.length&&(a.length+=b.text.length);return{opSpecsA:[a],opSpecsB:[b]}},MergeParagraph:function(a,b){var c=a.position,e=a.position+a.length;c>=b.sourceStartPosition&&--c;e>=b.sourceStartPosition&&--e;a.position=c;a.length= -e-c;return{opSpecsA:[a],opSpecsB:[b]}},MoveCursor:e,RemoveAnnotation:function(a,b){var c=a.position,e=a.position+a.length,f=b.position+b.length,g=[a],k=[b];b.position<=c&&e<=f?g=[]:(fb.position?a.position+=b.text.length:c?b.position+=a.text.length:a.position+= -b.text.length;return{opSpecsA:[a],opSpecsB:[b]}},MergeParagraph:function(a,b){a.position>=b.sourceStartPosition?--a.position:(a.positiona.position&&(b.position+=a.text.length);return{opSpecsA:[a],opSpecsB:[b]}},SplitParagraph:function(a,b){a.position=a.sourceStartPosition&&--f;c>=a.sourceStartPosition&&--c;0<=b.length?(b.position=f,b.length=c-f):(b.position=c,b.length=f-c);return{opSpecsA:[a],opSpecsB:[b]}},RemoveAnnotation:function(a,b){var c=b.position+b.length,e=[a],f=[b];b.position<=a.destinationStartPosition&&a.sourceStartPosition<=c?(e=[],--b.length):a.sourceStartPosition=a.sourceStartPosition?--b.position:(b.positiona.sourceStartPosition)--b.position;else if(b.position===a.destinationStartPosition||b.position===a.sourceStartPosition)b.position=a.destinationStartPosition,a.paragraphStyleName=b.styleName;return{opSpecsA:c,opSpecsB:e}},SplitParagraph:function(a,b){var c,e=[a],f=[b];b.position=a.destinationStartPosition&&b.position=a.sourceStartPosition&&(--b.position,--b.sourceParagraphPosition);return{opSpecsA:e,opSpecsB:f}},UpdateMember:e,UpdateMetadata:e, -UpdateParagraphStyle:e},MoveCursor:{MoveCursor:e,RemoveAnnotation:function(a,b){var c=k(a),e=a.position+a.length,f=b.position+b.length;b.position<=a.position&&e<=f?(a.position=b.position-1,a.length=0):(fb.position?a.position+= -1:a.position===b.sourceParagraphPosition&&(b.paragraphStyleName=a.styleName,g=f(a),g.position=b.position+1,c.push(g));return{opSpecsA:c,opSpecsB:e}},UpdateMember:e,UpdateMetadata:e,UpdateParagraphStyle:e},SplitParagraph:{SplitParagraph:function(a,b,c){var e,f;a.position - -(c) 2009-2014 Stuart Knightley -Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. - -JSZip uses the library pako released under the MIT license : -https://github.com/nodeca/pako/blob/master/LICENSE - @licend -*/ -!function(e){var globalScope=typeof window!=="undefined"?window:typeof global!=="undefined"?global:{},externs=globalScope.externs||(globalScope.externs={});externs.JSZip=e()}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'");}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f, -f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>> -6;enc4=chr3&63;if(isNaN(chr2))enc3=enc4=64;else if(isNaN(chr3))enc4=64;output=output+_keyStr.charAt(enc1)+_keyStr.charAt(enc2)+_keyStr.charAt(enc3)+_keyStr.charAt(enc4)}return output};exports.decode=function(input,utf8){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64)output=output+String.fromCharCode(chr2);if(enc4!=64)output=output+String.fromCharCode(chr3)}return output}},{}],2:[function(_dereq_,module,exports){function CompressedObject(){this.compressedSize=0;this.uncompressedSize=0;this.crc32=0;this.compressionMethod=null;this.compressedContent=null}CompressedObject.prototype={getContent:function(){return null},getCompressedContent:function(){return null}}; -module.exports=CompressedObject},{}],3:[function(_dereq_,module,exports){exports.STORE={magic:"\x00\x00",compress:function(content){return content},uncompress:function(content){return content},compressInputType:null,uncompressInputType:null};exports.DEFLATE=_dereq_("./flate")},{"./flate":8}],4:[function(_dereq_,module,exports){var utils=_dereq_("./utils");var table=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021, -3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527, -1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856, -1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626, -1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692, -2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614, -3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];module.exports=function crc32(input,crc){if(typeof input==="undefined"||!input.length)return 0;var isArray=utils.getTypeOf(input)!=="string";if(typeof crc=="undefined")crc=0;var x=0;var y=0;var b=0;crc=crc^-1;for(var i=0,iTop=input.length;i>>8^x}return crc^-1}},{"./utils":21}],5:[function(_dereq_,module,exports){var utils=_dereq_("./utils"); -function DataReader(data){this.data=null;this.length=0;this.index=0}DataReader.prototype={checkOffset:function(offset){this.checkIndex(this.index+offset)},checkIndex:function(newIndex){if(this.length=this.index;i--)result=(result<<8)+this.byteAt(i);this.index+=size;return result},readString:function(size){return utils.transformTo("string",this.readData(size))},readData:function(size){},lastIndexOfSignature:function(sig){},readDate:function(){var dostime=this.readInt(4);return new Date((dostime>>25&127)+1980,(dostime>>21&15)-1,dostime>>16&31,dostime>>11&31,dostime>>5&63,(dostime&31)<<1)}};module.exports=DataReader},{"./utils":21}],6:[function(_dereq_, -module,exports){exports.base64=false;exports.binary=false;exports.dir=false;exports.createFolders=false;exports.date=null;exports.compression=null;exports.comment=null},{}],7:[function(_dereq_,module,exports){var utils=_dereq_("./utils");exports.string2binary=function(str){return utils.string2binary(str)};exports.string2Uint8Array=function(str){return utils.transformTo("uint8array",str)};exports.uint8Array2String=function(array){return utils.transformTo("string",array)};exports.string2Blob=function(str){var buffer= -utils.transformTo("arraybuffer",str);return utils.arrayBuffer2Blob(buffer)};exports.arrayBuffer2Blob=function(buffer){return utils.arrayBuffer2Blob(buffer)};exports.transformTo=function(outputType,input){return utils.transformTo(outputType,input)};exports.getTypeOf=function(input){return utils.getTypeOf(input)};exports.checkSupport=function(type){return utils.checkSupport(type)};exports.MAX_VALUE_16BITS=utils.MAX_VALUE_16BITS;exports.MAX_VALUE_32BITS=utils.MAX_VALUE_32BITS;exports.pretty=function(str){return utils.pretty(str)}; -exports.findCompression=function(compressionMethod){return utils.findCompression(compressionMethod)};exports.isRegExp=function(object){return utils.isRegExp(object)}},{"./utils":21}],8:[function(_dereq_,module,exports){var USE_TYPEDARRAY=typeof Uint8Array!=="undefined"&&typeof Uint16Array!=="undefined"&&typeof Uint32Array!=="undefined";var pako=_dereq_("pako");exports.uncompressInputType=USE_TYPEDARRAY?"uint8array":"array";exports.compressInputType=USE_TYPEDARRAY?"uint8array":"array";exports.magic= -"\b\x00";exports.compress=function(input){return pako.deflateRaw(input)};exports.uncompress=function(input){return pako.inflateRaw(input)}},{"pako":24}],9:[function(_dereq_,module,exports){var base64=_dereq_("./base64");function JSZip(data,options){if(!(this instanceof JSZip))return new JSZip(data,options);this.files={};this.comment=null;this.root="";if(data)this.load(data,options);this.clone=function(){var newObj=new JSZip;for(var i in this)if(typeof this[i]!=="function")newObj[i]=this[i];return newObj}} -JSZip.prototype=_dereq_("./object");JSZip.prototype.load=_dereq_("./load");JSZip.support=_dereq_("./support");JSZip.defaults=_dereq_("./defaults");JSZip.utils=_dereq_("./deprecatedPublicUtils");JSZip.base64={encode:function(input){return base64.encode(input)},decode:function(input){return base64.decode(input)}};JSZip.compressions=_dereq_("./compressions");module.exports=JSZip},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(_dereq_, -module,exports){var base64=_dereq_("./base64");var ZipEntries=_dereq_("./zipEntries");module.exports=function(data,options){var files,zipEntries,i,input;options=options||{};if(options.base64)data=base64.decode(data);zipEntries=new ZipEntries(data,options);files=zipEntries.files;for(i=0;i>>8}return hex};var extend=function(){var result={},i,attr;for(i=0;i0?path.substring(0,lastSlash):""};var folderAdd=function(name,createFolders){if(name.slice(-1)!="/")name+="/";createFolders=typeof createFolders!=="undefined"?createFolders:false;if(!this.files[name])fileAdd.call(this,name,null,{dir:true,createFolders:createFolders});return this.files[name]};var generateCompressedObjectFrom=function(file,compression){var result=new CompressedObject,content;if(file._data instanceof -CompressedObject){result.uncompressedSize=file._data.uncompressedSize;result.crc32=file._data.crc32;if(result.uncompressedSize===0||file.dir){compression=compressions["STORE"];result.compressedContent="";result.crc32=0}else if(file._data.compressionMethod===compression.magic)result.compressedContent=file._data.getCompressedContent();else{content=file._data.getContent();result.compressedContent=compression.compress(utils.transformTo(compression.compressInputType,content))}}else{content=getBinaryData(file); -if(!content||content.length===0||file.dir){compression=compressions["STORE"];content=""}result.uncompressedSize=content.length;result.crc32=crc32(content);result.compressedContent=compression.compress(utils.transformTo(compression.compressInputType,content))}result.compressedSize=result.compressedContent.length;result.compressionMethod=compression.magic;return result};var generateZipParts=function(name,file,compressedObject,offset){var data=compressedObject.compressedContent,utfEncodedFileName=utils.transformTo("string", -utf8.utf8encode(file.name)),comment=file.comment||"",utfEncodedComment=utils.transformTo("string",utf8.utf8encode(comment)),useUTF8ForFileName=utfEncodedFileName.length!==file.name.length,useUTF8ForComment=utfEncodedComment.length!==comment.length,o=file.options,dosTime,dosDate,extraFields="",unicodePathExtraField="",unicodeCommentExtraField="",dir,date;if(file._initialMetadata.dir!==file.dir)dir=file.dir;else dir=o.dir;if(file._initialMetadata.date!==file.date)date=file.date;else date=o.date;dosTime= -date.getHours();dosTime=dosTime<<6;dosTime=dosTime|date.getMinutes();dosTime=dosTime<<5;dosTime=dosTime|date.getSeconds()/2;dosDate=date.getFullYear()-1980;dosDate=dosDate<<4;dosDate=dosDate|date.getMonth()+1;dosDate=dosDate<<5;dosDate=dosDate|date.getDate();if(useUTF8ForFileName){unicodePathExtraField=decToHex(1,1)+decToHex(crc32(utfEncodedFileName),4)+utfEncodedFileName;extraFields+="up"+decToHex(unicodePathExtraField.length,2)+unicodePathExtraField}if(useUTF8ForComment){unicodeCommentExtraField= -decToHex(1,1)+decToHex(this.crc32(utfEncodedComment),4)+utfEncodedComment;extraFields+="uc"+decToHex(unicodeCommentExtraField.length,2)+unicodeCommentExtraField}var header="";header+="\n\x00";header+=useUTF8ForFileName||useUTF8ForComment?"\x00\b":"\x00\x00";header+=compressedObject.compressionMethod;header+=decToHex(dosTime,2);header+=decToHex(dosDate,2);header+=decToHex(compressedObject.crc32,4);header+=decToHex(compressedObject.compressedSize,4);header+=decToHex(compressedObject.uncompressedSize, -4);header+=decToHex(utfEncodedFileName.length,2);header+=decToHex(extraFields.length,2);var fileRecord=signature.LOCAL_FILE_HEADER+header+utfEncodedFileName+extraFields;var dirRecord=signature.CENTRAL_FILE_HEADER+"\u0014\x00"+header+decToHex(utfEncodedComment.length,2)+"\x00\x00"+"\x00\x00"+(dir===true?"\u0010\x00\x00\x00":"\x00\x00\x00\x00")+decToHex(offset,4)+utfEncodedFileName+extraFields+utfEncodedComment;return{fileRecord:fileRecord,dirRecord:dirRecord,compressedObject:compressedObject}};var out= -{load:function(stream,options){throw new Error("Load method is not defined. Is the file jszip-load.js included ?");},filter:function(search){var result=[],filename,relativePath,file,fileClone;for(filename in this.files){if(!this.files.hasOwnProperty(filename))continue;file=this.files[filename];fileClone=new ZipObject(file.name,file._data,extend(file.options));relativePath=filename.slice(this.root.length,filename.length);if(filename.slice(0,this.root.length)===this.root&&search(relativePath,fileClone))result.push(fileClone)}return result}, -file:function(name,data,o){if(arguments.length===1)if(utils.isRegExp(name)){var regexp=name;return this.filter(function(relativePath,file){return!file.dir&®exp.test(relativePath)})}else return this.filter(function(relativePath,file){return!file.dir&&relativePath===name})[0]||null;else{name=this.root+name;fileAdd.call(this,name,data,o)}return this},folder:function(arg){if(!arg)return this;if(utils.isRegExp(arg))return this.filter(function(relativePath,file){return file.dir&&arg.test(relativePath)}); -var name=this.root+arg;var newFolder=folderAdd.call(this,name);var ret=this.clone();ret.root=newFolder.name;return ret},remove:function(name){name=this.root+name;var file=this.files[name];if(!file){if(name.slice(-1)!="/")name+="/";file=this.files[name]}if(file&&!file.dir)delete this.files[name];else{var kids=this.filter(function(relativePath,file){return file.name.slice(0,name.length)===name});for(var i=0;i=0;--i)if(this.data[i]===sig0&&this.data[i+1]===sig1&&this.data[i+2]===sig2&&this.data[i+3]===sig3)return i;return-1};Uint8ArrayReader.prototype.readData=function(size){this.checkOffset(size);if(size===0)return new Uint8Array(0);var result=this.data.subarray(this.index, -this.index+size);this.index+=size;return result};module.exports=Uint8ArrayReader},{"./dataReader":5}],19:[function(_dereq_,module,exports){var utils=_dereq_("./utils");var Uint8ArrayWriter=function(length){this.data=new Uint8Array(length);this.index=0};Uint8ArrayWriter.prototype={append:function(input){if(input.length!==0){input=utils.transformTo("uint8array",input);this.data.set(input,this.index);this.index+=input.length}},finalize:function(){return this.data}};module.exports=Uint8ArrayWriter},{"./utils":21}], -20:[function(_dereq_,module,exports){var utils=_dereq_("./utils");var support=_dereq_("./support");var nodeBuffer=_dereq_("./nodeBuffer");var _utf8len=new Array(256);for(var i=0;i<256;i++)_utf8len[i]=i>=252?6:i>=248?5:i>=240?4:i>=224?3:i>=192?2:1;_utf8len[254]=_utf8len[254]=1;var string2buf=function(str){var buf,c,c2,m_pos,i,str_len=str.length,buf_len=0;for(m_pos=0;m_pos>>6;buf[i++]=128|c&63}else if(c<65536){buf[i++]=224|c>>>12;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}else{buf[i++]= -240|c>>>18;buf[i++]=128|c>>>12&63;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}}return buf};var utf8border=function(buf,max){var pos;max=max||buf.length;if(max>buf.length)max=buf.length;pos=max-1;while(pos>=0&&(buf[pos]&192)===128)pos--;if(pos<0)return max;if(pos===0)return max;return pos+_utf8len[buf[pos]]>max?pos:max};var buf2string=function(buf){var str,i,out,c,c_len;var len=buf.length;var utf16buf=new Array(len*2);for(out=0,i=0;i4){utf16buf[out++]=65533;i+=c_len-1;continue}c&=c_len===2?31:c_len===3?15:7;while(c_len>1&&i1){utf16buf[out++]=65533;continue}if(c<65536)utf16buf[out++]=c;else{c-=65536;utf16buf[out++]=55296|c>>10&1023;utf16buf[out++]=56320|c&1023}}if(utf16buf.length!==out)if(utf16buf.subarray)utf16buf=utf16buf.subarray(0,out);else utf16buf.length=out;return utils.applyFromCharCode(utf16buf)};exports.utf8encode=function utf8encode(str){if(support.nodebuffer)return nodeBuffer(str, -"utf-8");return string2buf(str)};exports.utf8decode=function utf8decode(buf){if(support.nodebuffer)return utils.transformTo("nodebuffer",buf).toString("utf-8");buf=utils.transformTo(support.uint8array?"uint8array":"array",buf);var result=[],k=0,len=buf.length,chunk=65536;while(k1)try{if(type==="array"||type==="nodebuffer")result.push(String.fromCharCode.apply(null,array.slice(k,Math.min(k+chunk,len))));else result.push(String.fromCharCode.apply(null, -array.subarray(k,Math.min(k+chunk,len))));k+=chunk}catch(e){chunk=Math.floor(chunk/2)}return result.join("")}exports.applyFromCharCode=arrayLikeToString;function arrayLikeToArrayLike(arrayFrom,arrayTo){for(var i=0;i1)throw new Error("Multi-volumes zip are not supported");},readLocalFiles:function(){var i,file;for(i=0;i0)opt.windowBits=-opt.windowBits;else if(opt.gzip&&opt.windowBits>0&&opt.windowBits<16)opt.windowBits+=16;this.err=0;this.msg="";this.ended=false;this.chunks=[];this.strm=new zstream;this.strm.avail_out=0;var status=zlib_deflate.deflateInit2(this.strm,opt.level,opt.method,opt.windowBits,opt.memLevel,opt.strategy);if(status!==Z_OK)throw new Error(msg[status]); -if(opt.header)zlib_deflate.deflateSetHeader(this.strm,opt.header)};Deflate.prototype.push=function(data,mode){var strm=this.strm;var chunkSize=this.options.chunkSize;var status,_mode;if(this.ended)return false;_mode=mode===~~mode?mode:mode===true?Z_FINISH:Z_NO_FLUSH;if(typeof data==="string")strm.input=strings.string2buf(data);else strm.input=data;strm.next_in=0;strm.avail_in=strm.input.length;do{if(strm.avail_out===0){strm.output=new utils.Buf8(chunkSize);strm.next_out=0;strm.avail_out=chunkSize}status= -zlib_deflate.deflate(strm,_mode);if(status!==Z_STREAM_END&&status!==Z_OK){this.onEnd(status);this.ended=true;return false}if(strm.avail_out===0||strm.avail_in===0&&_mode===Z_FINISH)if(this.options.to==="string")this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output,strm.next_out)));else this.onData(utils.shrinkBuf(strm.output,strm.next_out))}while((strm.avail_in>0||strm.avail_out===0)&&status!==Z_STREAM_END);if(_mode===Z_FINISH){status=zlib_deflate.deflateEnd(this.strm);this.onEnd(status); -this.ended=true;return status===Z_OK}return true};Deflate.prototype.onData=function(chunk){this.chunks.push(chunk)};Deflate.prototype.onEnd=function(status){if(status===Z_OK)if(this.options.to==="string")this.result=this.chunks.join("");else this.result=utils.flattenChunks(this.chunks);this.chunks=[];this.err=status;this.msg=this.strm.msg};function deflate(input,options){var deflator=new Deflate(options);deflator.push(input,true);if(deflator.err)throw deflator.msg;return deflator.result}function deflateRaw(input, -options){options=options||{};options.raw=true;return deflate(input,options)}function gzip(input,options){options=options||{};options.gzip=true;return deflate(input,options)}exports.Deflate=Deflate;exports.deflate=deflate;exports.deflateRaw=deflateRaw;exports.gzip=gzip},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(_dereq_,module,exports){var zlib_inflate=_dereq_("./zlib/inflate.js");var utils=_dereq_("./utils/common");var strings= -_dereq_("./utils/strings");var c=_dereq_("./zlib/constants");var msg=_dereq_("./zlib/messages");var zstream=_dereq_("./zlib/zstream");var gzheader=_dereq_("./zlib/gzheader");var Inflate=function(options){this.options=utils.assign({chunkSize:16384,windowBits:0,to:""},options||{});var opt=this.options;if(opt.raw&&opt.windowBits>=0&&opt.windowBits<16){opt.windowBits=-opt.windowBits;if(opt.windowBits===0)opt.windowBits=-15}if(opt.windowBits>=0&&opt.windowBits<16&&!(options&&options.windowBits))opt.windowBits+= -32;if(opt.windowBits>15&&opt.windowBits<48)if((opt.windowBits&15)===0)opt.windowBits|=15;this.err=0;this.msg="";this.ended=false;this.chunks=[];this.strm=new zstream;this.strm.avail_out=0;var status=zlib_inflate.inflateInit2(this.strm,opt.windowBits);if(status!==c.Z_OK)throw new Error(msg[status]);this.header=new gzheader;zlib_inflate.inflateGetHeader(this.strm,this.header)};Inflate.prototype.push=function(data,mode){var strm=this.strm;var chunkSize=this.options.chunkSize;var status,_mode;var next_out_utf8, -tail,utf8str;if(this.ended)return false;_mode=mode===~~mode?mode:mode===true?c.Z_FINISH:c.Z_NO_FLUSH;if(typeof data==="string")strm.input=strings.binstring2buf(data);else strm.input=data;strm.next_in=0;strm.avail_in=strm.input.length;do{if(strm.avail_out===0){strm.output=new utils.Buf8(chunkSize);strm.next_out=0;strm.avail_out=chunkSize}status=zlib_inflate.inflate(strm,c.Z_NO_FLUSH);if(status!==c.Z_STREAM_END&&status!==c.Z_OK){this.onEnd(status);this.ended=true;return false}if(strm.next_out)if(strm.avail_out=== -0||status===c.Z_STREAM_END||strm.avail_in===0&&_mode===c.Z_FINISH)if(this.options.to==="string"){next_out_utf8=strings.utf8border(strm.output,strm.next_out);tail=strm.next_out-next_out_utf8;utf8str=strings.buf2string(strm.output,next_out_utf8);strm.next_out=tail;strm.avail_out=chunkSize-tail;if(tail)utils.arraySet(strm.output,strm.output,next_out_utf8,tail,0);this.onData(utf8str)}else this.onData(utils.shrinkBuf(strm.output,strm.next_out))}while(strm.avail_in>0&&status!==c.Z_STREAM_END);if(status=== -c.Z_STREAM_END)_mode=c.Z_FINISH;if(_mode===c.Z_FINISH){status=zlib_inflate.inflateEnd(this.strm);this.onEnd(status);this.ended=true;return status===c.Z_OK}return true};Inflate.prototype.onData=function(chunk){this.chunks.push(chunk)};Inflate.prototype.onEnd=function(status){if(status===c.Z_OK)if(this.options.to==="string")this.result=this.chunks.join("");else this.result=utils.flattenChunks(this.chunks);this.chunks=[];this.err=status;this.msg=this.strm.msg};function inflate(input,options){var inflator= -new Inflate(options);inflator.push(input,true);if(inflator.err)throw inflator.msg;return inflator.result}function inflateRaw(input,options){options=options||{};options.raw=true;return inflate(input,options)}exports.Inflate=Inflate;exports.inflate=inflate;exports.inflateRaw=inflateRaw;exports.ungzip=inflate},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(_dereq_,module,exports){var TYPED_OK= -typeof Uint8Array!=="undefined"&&typeof Uint16Array!=="undefined"&&typeof Int32Array!=="undefined";exports.assign=function(obj){var sources=Array.prototype.slice.call(arguments,1);while(sources.length){var source=sources.shift();if(!source)continue;if(typeof source!=="object")throw new TypeError(source+"must be non-object");for(var p in source)if(source.hasOwnProperty(p))obj[p]=source[p]}return obj};exports.shrinkBuf=function(buf,size){if(buf.length===size)return buf;if(buf.subarray)return buf.subarray(0, -size);buf.length=size;return buf};var fnTyped={arraySet:function(dest,src,src_offs,len,dest_offs){if(src.subarray&&dest.subarray){dest.set(src.subarray(src_offs,src_offs+len),dest_offs);return}for(var i=0;i=252?6:i>=248?5:i>=240?4:i>=224?3:i>=192?2:1;_utf8len[254]=_utf8len[254]=1;exports.string2buf=function(str){var buf,c,c2,m_pos,i,str_len=str.length,buf_len=0;for(m_pos=0;m_pos>>6;buf[i++]=128|c&63}else if(c<65536){buf[i++]=224|c>>>12;buf[i++]= -128|c>>>6&63;buf[i++]=128|c&63}else{buf[i++]=240|c>>>18;buf[i++]=128|c>>>12&63;buf[i++]=128|c>>>6&63;buf[i++]=128|c&63}}return buf};function buf2binstring(buf,len){if(len<65537)if(buf.subarray&&STR_APPLY_UIA_OK||!buf.subarray&&STR_APPLY_OK)return String.fromCharCode.apply(null,utils.shrinkBuf(buf,len));var result="";for(var i=0;i4){utf16buf[out++]=65533;i+=c_len-1;continue}c&=c_len===2?31:c_len===3?15:7;while(c_len>1&&i1){utf16buf[out++]=65533;continue}if(c<65536)utf16buf[out++]= -c;else{c-=65536;utf16buf[out++]=55296|c>>10&1023;utf16buf[out++]=56320|c&1023}}return buf2binstring(utf16buf,out)};exports.utf8border=function(buf,max){var pos;max=max||buf.length;if(max>buf.length)max=buf.length;pos=max-1;while(pos>=0&&(buf[pos]&192)===128)pos--;if(pos<0)return max;if(pos===0)return max;return pos+_utf8len[buf[pos]]>max?pos:max}},{"./common":27}],29:[function(_dereq_,module,exports){function adler32(adler,buf,len,pos){var s1=adler&65535|0,s2=adler>>>16&65535|0,n=0;while(len!==0){n= -len>2E3?2E3:len;len-=n;do{s1=s1+buf[pos++]|0;s2=s2+s1|0}while(--n);s1%=65521;s2%=65521}return s1|s2<<16|0}module.exports=adler32},{}],30:[function(_dereq_,module,exports){module.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4, -Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(_dereq_,module,exports){function makeTable(){var c,table=[];for(var n=0;n<256;n++){c=n;for(var k=0;k<8;k++)c=c&1?3988292384^c>>>1:c>>>1;table[n]=c}return table}var crcTable=makeTable();function crc32(crc,buf,len,pos){var t=crcTable,end=pos+len;crc=crc^-1;for(var i=pos;i>>8^t[(crc^buf[i])&255];return crc^-1}module.exports=crc32},{}],32:[function(_dereq_,module,exports){var utils=_dereq_("../utils/common"); -var trees=_dereq_("./trees");var adler32=_dereq_("./adler32");var crc32=_dereq_("./crc32");var msg=_dereq_("./messages");var Z_NO_FLUSH=0;var Z_PARTIAL_FLUSH=1;var Z_FULL_FLUSH=3;var Z_FINISH=4;var Z_BLOCK=5;var Z_OK=0;var Z_STREAM_END=1;var Z_STREAM_ERROR=-2;var Z_DATA_ERROR=-3;var Z_BUF_ERROR=-5;var Z_DEFAULT_COMPRESSION=-1;var Z_FILTERED=1;var Z_HUFFMAN_ONLY=2;var Z_RLE=3;var Z_FIXED=4;var Z_DEFAULT_STRATEGY=0;var Z_UNKNOWN=2;var Z_DEFLATED=8;var MAX_MEM_LEVEL=9;var MAX_WBITS=15;var DEF_MEM_LEVEL= -8;var LENGTH_CODES=29;var LITERALS=256;var L_CODES=LITERALS+1+LENGTH_CODES;var D_CODES=30;var BL_CODES=19;var HEAP_SIZE=2*L_CODES+1;var MAX_BITS=15;var MIN_MATCH=3;var MAX_MATCH=258;var MIN_LOOKAHEAD=MAX_MATCH+MIN_MATCH+1;var PRESET_DICT=32;var INIT_STATE=42;var EXTRA_STATE=69;var NAME_STATE=73;var COMMENT_STATE=91;var HCRC_STATE=103;var BUSY_STATE=113;var FINISH_STATE=666;var BS_NEED_MORE=1;var BS_BLOCK_DONE=2;var BS_FINISH_STARTED=3;var BS_FINISH_DONE=4;var OS_CODE=3;function err(strm,errorCode){strm.msg= -msg[errorCode];return errorCode}function rank(f){return(f<<1)-(f>4?9:0)}function zero(buf){var len=buf.length;while(--len>=0)buf[len]=0}function flush_pending(strm){var s=strm.state;var len=s.pending;if(len>strm.avail_out)len=strm.avail_out;if(len===0)return;utils.arraySet(strm.output,s.pending_buf,s.pending_out,len,strm.next_out);strm.next_out+=len;s.pending_out+=len;strm.total_out+=len;strm.avail_out-=len;s.pending-=len;if(s.pending===0)s.pending_out=0}function flush_block_only(s,last){trees._tr_flush_block(s, -s.block_start>=0?s.block_start:-1,s.strstart-s.block_start,last);s.block_start=s.strstart;flush_pending(s.strm)}function put_byte(s,b){s.pending_buf[s.pending++]=b}function putShortMSB(s,b){s.pending_buf[s.pending++]=b>>>8&255;s.pending_buf[s.pending++]=b&255}function read_buf(strm,buf,start,size){var len=strm.avail_in;if(len>size)len=size;if(len===0)return 0;strm.avail_in-=len;utils.arraySet(buf,strm.input,strm.next_in,len,start);if(strm.state.wrap===1)strm.adler=adler32(strm.adler,buf,len,start); -else if(strm.state.wrap===2)strm.adler=crc32(strm.adler,buf,len,start);strm.next_in+=len;strm.total_in+=len;return len}function longest_match(s,cur_match){var chain_length=s.max_chain_length;var scan=s.strstart;var match;var len;var best_len=s.prev_length;var nice_match=s.nice_match;var limit=s.strstart>s.w_size-MIN_LOOKAHEAD?s.strstart-(s.w_size-MIN_LOOKAHEAD):0;var _win=s.window;var wmask=s.w_mask;var prev=s.prev;var strend=s.strstart+MAX_MATCH;var scan_end1=_win[scan+best_len-1];var scan_end=_win[scan+ -best_len];if(s.prev_length>=s.good_match)chain_length>>=2;if(nice_match>s.lookahead)nice_match=s.lookahead;do{match=cur_match;if(_win[match+best_len]!==scan_end||_win[match+best_len-1]!==scan_end1||_win[match]!==_win[scan]||_win[++match]!==_win[scan+1])continue;scan+=2;match++;do;while(_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&_win[++scan]===_win[++match]&&_win[++scan]=== -_win[++match]&&scanbest_len){s.match_start=cur_match;best_len=len;if(len>=nice_match)break;scan_end1=_win[scan+best_len-1];scan_end=_win[scan+best_len]}}while((cur_match=prev[cur_match&wmask])>limit&&--chain_length!==0);if(best_len<=s.lookahead)return best_len;return s.lookahead}function fill_window(s){var _w_size=s.w_size;var p,n,m,more,str;do{more=s.window_size-s.lookahead-s.strstart;if(s.strstart>=_w_size+(_w_size-MIN_LOOKAHEAD)){utils.arraySet(s.window, -s.window,_w_size,_w_size,0);s.match_start-=_w_size;s.strstart-=_w_size;s.block_start-=_w_size;n=s.hash_size;p=n;do{m=s.head[--p];s.head[p]=m>=_w_size?m-_w_size:0}while(--n);n=_w_size;p=n;do{m=s.prev[--p];s.prev[p]=m>=_w_size?m-_w_size:0}while(--n);more+=_w_size}if(s.strm.avail_in===0)break;n=read_buf(s.strm,s.window,s.strstart+s.lookahead,more);s.lookahead+=n;if(s.lookahead+s.insert>=MIN_MATCH){str=s.strstart-s.insert;s.ins_h=s.window[str];s.ins_h=(s.ins_h<s.pending_buf_size-5)max_block_size=s.pending_buf_size-5;for(;;){if(s.lookahead<=1){fill_window(s);if(s.lookahead===0&&flush===Z_NO_FLUSH)return BS_NEED_MORE;if(s.lookahead=== -0)break}s.strstart+=s.lookahead;s.lookahead=0;var max_start=s.block_start+max_block_size;if(s.strstart===0||s.strstart>=max_start){s.lookahead=s.strstart-max_start;s.strstart=max_start;flush_block_only(s,false);if(s.strm.avail_out===0)return BS_NEED_MORE}if(s.strstart-s.block_start>=s.w_size-MIN_LOOKAHEAD){flush_block_only(s,false);if(s.strm.avail_out===0)return BS_NEED_MORE}}s.insert=0;if(flush===Z_FINISH){flush_block_only(s,true);if(s.strm.avail_out===0)return BS_FINISH_STARTED;return BS_FINISH_DONE}if(s.strstart> -s.block_start){flush_block_only(s,false);if(s.strm.avail_out===0)return BS_NEED_MORE}return BS_NEED_MORE}function deflate_fast(s,flush){var hash_head;var bflush;for(;;){if(s.lookahead=MIN_MATCH){s.ins_h=(s.ins_h<=MIN_MATCH){bflush=trees._tr_tally(s,s.strstart-s.match_start,s.match_length-MIN_MATCH);s.lookahead-=s.match_length;if(s.match_length<=s.max_lazy_match&&s.lookahead>=MIN_MATCH){s.match_length--;do{s.strstart++;s.ins_h=(s.ins_h<=MIN_MATCH){s.ins_h=(s.ins_h<4096))s.match_length=MIN_MATCH-1}if(s.prev_length>=MIN_MATCH&&s.match_length<=s.prev_length){max_insert=s.strstart+s.lookahead-MIN_MATCH;bflush=trees._tr_tally(s,s.strstart-1-s.prev_match,s.prev_length- -MIN_MATCH);s.lookahead-=s.prev_length-1;s.prev_length-=2;do if(++s.strstart<=max_insert){s.ins_h=(s.ins_h<=MIN_MATCH&&s.strstart>0){scan=s.strstart-1;prev=_win[scan];if(prev===_win[++scan]&&prev===_win[++scan]&&prev===_win[++scan]){strend=s.strstart+MAX_MATCH;do;while(prev===_win[++scan]&&prev===_win[++scan]&&prev===_win[++scan]&&prev===_win[++scan]&& -prev===_win[++scan]&&prev===_win[++scan]&&prev===_win[++scan]&&prev===_win[++scan]&&scans.lookahead)s.match_length=s.lookahead}}if(s.match_length>=MIN_MATCH){bflush=trees._tr_tally(s,1,s.match_length-MIN_MATCH);s.lookahead-=s.match_length;s.strstart+=s.match_length;s.match_length=0}else{bflush=trees._tr_tally(s,0,s.window[s.strstart]);s.lookahead--;s.strstart++}if(bflush){flush_block_only(s,false);if(s.strm.avail_out===0)return BS_NEED_MORE}}s.insert= -0;if(flush===Z_FINISH){flush_block_only(s,true);if(s.strm.avail_out===0)return BS_FINISH_STARTED;return BS_FINISH_DONE}if(s.last_lit){flush_block_only(s,false);if(s.strm.avail_out===0)return BS_NEED_MORE}return BS_BLOCK_DONE}function deflate_huff(s,flush){var bflush;for(;;){if(s.lookahead===0){fill_window(s);if(s.lookahead===0){if(flush===Z_NO_FLUSH)return BS_NEED_MORE;break}}s.match_length=0;bflush=trees._tr_tally(s,0,s.window[s.strstart]);s.lookahead--;s.strstart++;if(bflush){flush_block_only(s, -false);if(s.strm.avail_out===0)return BS_NEED_MORE}}s.insert=0;if(flush===Z_FINISH){flush_block_only(s,true);if(s.strm.avail_out===0)return BS_FINISH_STARTED;return BS_FINISH_DONE}if(s.last_lit){flush_block_only(s,false);if(s.strm.avail_out===0)return BS_NEED_MORE}return BS_BLOCK_DONE}var Config=function(good_length,max_lazy,nice_length,max_chain,func){this.good_length=good_length;this.max_lazy=max_lazy;this.nice_length=nice_length;this.max_chain=max_chain;this.func=func};var configuration_table; -configuration_table=[new Config(0,0,0,0,deflate_stored),new Config(4,4,8,4,deflate_fast),new Config(4,5,16,8,deflate_fast),new Config(4,6,32,32,deflate_fast),new Config(4,4,16,16,deflate_slow),new Config(8,16,32,32,deflate_slow),new Config(8,16,128,128,deflate_slow),new Config(8,32,128,256,deflate_slow),new Config(32,128,258,1024,deflate_slow),new Config(32,258,258,4096,deflate_slow)];function lm_init(s){s.window_size=2*s.w_size;zero(s.head);s.max_lazy_match=configuration_table[s.level].max_lazy; -s.good_match=configuration_table[s.level].good_length;s.nice_match=configuration_table[s.level].nice_length;s.max_chain_length=configuration_table[s.level].max_chain;s.strstart=0;s.block_start=0;s.lookahead=0;s.insert=0;s.match_length=s.prev_length=MIN_MATCH-1;s.match_available=0;s.ins_h=0}function DeflateState(){this.strm=null;this.status=0;this.pending_buf=null;this.pending_buf_size=0;this.pending_out=0;this.pending=0;this.wrap=0;this.gzhead=null;this.gzindex=0;this.method=Z_DEFLATED;this.last_flush= --1;this.w_size=0;this.w_bits=0;this.w_mask=0;this.window=null;this.window_size=0;this.prev=null;this.head=null;this.ins_h=0;this.hash_size=0;this.hash_bits=0;this.hash_mask=0;this.hash_shift=0;this.block_start=0;this.match_length=0;this.prev_match=0;this.match_available=0;this.strstart=0;this.match_start=0;this.lookahead=0;this.prev_length=0;this.max_chain_length=0;this.max_lazy_match=0;this.level=0;this.strategy=0;this.good_match=0;this.nice_match=0;this.dyn_ltree=new utils.Buf16(HEAP_SIZE*2);this.dyn_dtree= -new utils.Buf16((2*D_CODES+1)*2);this.bl_tree=new utils.Buf16((2*BL_CODES+1)*2);zero(this.dyn_ltree);zero(this.dyn_dtree);zero(this.bl_tree);this.l_desc=null;this.d_desc=null;this.bl_desc=null;this.bl_count=new utils.Buf16(MAX_BITS+1);this.heap=new utils.Buf16(2*L_CODES+1);zero(this.heap);this.heap_len=0;this.heap_max=0;this.depth=new utils.Buf16(2*L_CODES+1);zero(this.depth);this.l_buf=0;this.lit_bufsize=0;this.last_lit=0;this.d_buf=0;this.opt_len=0;this.static_len=0;this.matches=0;this.insert=0; -this.bi_buf=0;this.bi_valid=0}function deflateResetKeep(strm){var s;if(!strm||!strm.state)return err(strm,Z_STREAM_ERROR);strm.total_in=strm.total_out=0;strm.data_type=Z_UNKNOWN;s=strm.state;s.pending=0;s.pending_out=0;if(s.wrap<0)s.wrap=-s.wrap;s.status=s.wrap?INIT_STATE:BUSY_STATE;strm.adler=s.wrap===2?0:1;s.last_flush=Z_NO_FLUSH;trees._tr_init(s);return Z_OK}function deflateReset(strm){var ret=deflateResetKeep(strm);if(ret===Z_OK)lm_init(strm.state);return ret}function deflateSetHeader(strm,head){if(!strm|| -!strm.state)return Z_STREAM_ERROR;if(strm.state.wrap!==2)return Z_STREAM_ERROR;strm.state.gzhead=head;return Z_OK}function deflateInit2(strm,level,method,windowBits,memLevel,strategy){if(!strm)return Z_STREAM_ERROR;var wrap=1;if(level===Z_DEFAULT_COMPRESSION)level=6;if(windowBits<0){wrap=0;windowBits=-windowBits}else if(windowBits>15){wrap=2;windowBits-=16}if(memLevel<1||memLevel>MAX_MEM_LEVEL||method!==Z_DEFLATED||windowBits<8||windowBits>15||level<0||level>9||strategy<0||strategy>Z_FIXED)return err(strm, -Z_STREAM_ERROR);if(windowBits===8)windowBits=9;var s=new DeflateState;strm.state=s;s.strm=strm;s.wrap=wrap;s.gzhead=null;s.w_bits=windowBits;s.w_size=1<>1;s.l_buf=(1+2)*s.lit_bufsize;s.level=level;s.strategy=strategy;s.method=method;return deflateReset(strm)}function deflateInit(strm,level){return deflateInit2(strm,level,Z_DEFLATED,MAX_WBITS,DEF_MEM_LEVEL,Z_DEFAULT_STRATEGY)}function deflate(strm,flush){var old_flush,s;var beg,val;if(!strm||!strm.state||flush>Z_BLOCK||flush<0)return strm?err(strm,Z_STREAM_ERROR):Z_STREAM_ERROR;s=strm.state;if(!strm.output||!strm.input&&strm.avail_in!==0||s.status===FINISH_STATE&&flush!==Z_FINISH)return err(strm, -strm.avail_out===0?Z_BUF_ERROR:Z_STREAM_ERROR);s.strm=strm;old_flush=s.last_flush;s.last_flush=flush;if(s.status===INIT_STATE)if(s.wrap===2){strm.adler=0;put_byte(s,31);put_byte(s,139);put_byte(s,8);if(!s.gzhead){put_byte(s,0);put_byte(s,0);put_byte(s,0);put_byte(s,0);put_byte(s,0);put_byte(s,s.level===9?2:s.strategy>=Z_HUFFMAN_ONLY||s.level<2?4:0);put_byte(s,OS_CODE);s.status=BUSY_STATE}else{put_byte(s,(s.gzhead.text?1:0)+(s.gzhead.hcrc?2:0)+(!s.gzhead.extra?0:4)+(!s.gzhead.name?0:8)+(!s.gzhead.comment? -0:16));put_byte(s,s.gzhead.time&255);put_byte(s,s.gzhead.time>>8&255);put_byte(s,s.gzhead.time>>16&255);put_byte(s,s.gzhead.time>>24&255);put_byte(s,s.level===9?2:s.strategy>=Z_HUFFMAN_ONLY||s.level<2?4:0);put_byte(s,s.gzhead.os&255);if(s.gzhead.extra&&s.gzhead.extra.length){put_byte(s,s.gzhead.extra.length&255);put_byte(s,s.gzhead.extra.length>>8&255)}if(s.gzhead.hcrc)strm.adler=crc32(strm.adler,s.pending_buf,s.pending,0);s.gzindex=0;s.status=EXTRA_STATE}}else{var header=Z_DEFLATED+(s.w_bits-8<< -4)<<8;var level_flags=-1;if(s.strategy>=Z_HUFFMAN_ONLY||s.level<2)level_flags=0;else if(s.level<6)level_flags=1;else if(s.level===6)level_flags=2;else level_flags=3;header|=level_flags<<6;if(s.strstart!==0)header|=PRESET_DICT;header+=31-header%31;s.status=BUSY_STATE;putShortMSB(s,header);if(s.strstart!==0){putShortMSB(s,strm.adler>>>16);putShortMSB(s,strm.adler&65535)}strm.adler=1}if(s.status===EXTRA_STATE)if(s.gzhead.extra){beg=s.pending;while(s.gzindex<(s.gzhead.extra.length&65535)){if(s.pending=== -s.pending_buf_size){if(s.gzhead.hcrc&&s.pending>beg)strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);flush_pending(strm);beg=s.pending;if(s.pending===s.pending_buf_size)break}put_byte(s,s.gzhead.extra[s.gzindex]&255);s.gzindex++}if(s.gzhead.hcrc&&s.pending>beg)strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);if(s.gzindex===s.gzhead.extra.length){s.gzindex=0;s.status=NAME_STATE}}else s.status=NAME_STATE;if(s.status===NAME_STATE)if(s.gzhead.name){beg=s.pending;do{if(s.pending=== -s.pending_buf_size){if(s.gzhead.hcrc&&s.pending>beg)strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);flush_pending(strm);beg=s.pending;if(s.pending===s.pending_buf_size){val=1;break}}if(s.gzindexbeg)strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);if(val===0){s.gzindex=0;s.status=COMMENT_STATE}}else s.status=COMMENT_STATE;if(s.status===COMMENT_STATE)if(s.gzhead.comment){beg= -s.pending;do{if(s.pending===s.pending_buf_size){if(s.gzhead.hcrc&&s.pending>beg)strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);flush_pending(strm);beg=s.pending;if(s.pending===s.pending_buf_size){val=1;break}}if(s.gzindexbeg)strm.adler=crc32(strm.adler,s.pending_buf,s.pending-beg,beg);if(val===0)s.status=HCRC_STATE}else s.status=HCRC_STATE;if(s.status=== -HCRC_STATE)if(s.gzhead.hcrc){if(s.pending+2>s.pending_buf_size)flush_pending(strm);if(s.pending+2<=s.pending_buf_size){put_byte(s,strm.adler&255);put_byte(s,strm.adler>>8&255);strm.adler=0;s.status=BUSY_STATE}}else s.status=BUSY_STATE;if(s.pending!==0){flush_pending(strm);if(strm.avail_out===0){s.last_flush=-1;return Z_OK}}else if(strm.avail_in===0&&rank(flush)<=rank(old_flush)&&flush!==Z_FINISH)return err(strm,Z_BUF_ERROR);if(s.status===FINISH_STATE&&strm.avail_in!==0)return err(strm,Z_BUF_ERROR); -if(strm.avail_in!==0||s.lookahead!==0||flush!==Z_NO_FLUSH&&s.status!==FINISH_STATE){var bstate=s.strategy===Z_HUFFMAN_ONLY?deflate_huff(s,flush):s.strategy===Z_RLE?deflate_rle(s,flush):configuration_table[s.level].func(s,flush);if(bstate===BS_FINISH_STARTED||bstate===BS_FINISH_DONE)s.status=FINISH_STATE;if(bstate===BS_NEED_MORE||bstate===BS_FINISH_STARTED){if(strm.avail_out===0)s.last_flush=-1;return Z_OK}if(bstate===BS_BLOCK_DONE){if(flush===Z_PARTIAL_FLUSH)trees._tr_align(s);else if(flush!==Z_BLOCK){trees._tr_stored_block(s, -0,0,false);if(flush===Z_FULL_FLUSH){zero(s.head);if(s.lookahead===0){s.strstart=0;s.block_start=0;s.insert=0}}}flush_pending(strm);if(strm.avail_out===0){s.last_flush=-1;return Z_OK}}}if(flush!==Z_FINISH)return Z_OK;if(s.wrap<=0)return Z_STREAM_END;if(s.wrap===2){put_byte(s,strm.adler&255);put_byte(s,strm.adler>>8&255);put_byte(s,strm.adler>>16&255);put_byte(s,strm.adler>>24&255);put_byte(s,strm.total_in&255);put_byte(s,strm.total_in>>8&255);put_byte(s,strm.total_in>>16&255);put_byte(s,strm.total_in>> -24&255)}else{putShortMSB(s,strm.adler>>>16);putShortMSB(s,strm.adler&65535)}flush_pending(strm);if(s.wrap>0)s.wrap=-s.wrap;return s.pending!==0?Z_OK:Z_STREAM_END}function deflateEnd(strm){var status;if(!strm||!strm.state)return Z_STREAM_ERROR;status=strm.state.status;if(status!==INIT_STATE&&status!==EXTRA_STATE&&status!==NAME_STATE&&status!==COMMENT_STATE&&status!==HCRC_STATE&&status!==BUSY_STATE&&status!==FINISH_STATE)return err(strm,Z_STREAM_ERROR);strm.state=null;return status===BUSY_STATE?err(strm, -Z_DATA_ERROR):Z_OK}exports.deflateInit=deflateInit;exports.deflateInit2=deflateInit2;exports.deflateReset=deflateReset;exports.deflateResetKeep=deflateResetKeep;exports.deflateSetHeader=deflateSetHeader;exports.deflate=deflate;exports.deflateEnd=deflateEnd;exports.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(_dereq_,module,exports){function GZheader(){this.text=0;this.time=0;this.xflags=0;this.os=0; -this.extra=null;this.extra_len=0;this.name="";this.comment="";this.hcrc=0;this.done=false}module.exports=GZheader},{}],34:[function(_dereq_,module,exports){var BAD=30;var TYPE=12;module.exports=function inflate_fast(strm,start){var state;var _in;var last;var _out;var beg;var end;var dmax;var wsize;var whave;var wnext;var window;var hold;var bits;var lcode;var dcode;var lmask;var dmask;var here;var op;var len;var dist;var from;var from_source;var input,output;state=strm.state;_in=strm.next_in;input= -strm.input;last=_in+(strm.avail_in-5);_out=strm.next_out;output=strm.output;beg=_out-(start-strm.avail_out);end=_out+(strm.avail_out-257);dmax=state.dmax;wsize=state.wsize;whave=state.whave;wnext=state.wnext;window=state.window;hold=state.hold;bits=state.bits;lcode=state.lencode;dcode=state.distcode;lmask=(1<>>24;hold>>>=op; -bits-=op;op=here>>>16&255;if(op===0)output[_out++]=here&65535;else if(op&16){len=here&65535;op&=15;if(op){if(bits>>=op;bits-=op}if(bits<15){hold+=input[_in++]<>>24;hold>>>=op;bits-=op;op=here>>>16&255;if(op&16){dist=here&65535;op&=15;if(bitsdmax){strm.msg="invalid distance too far back";state.mode=BAD;break top}hold>>>=op;bits-=op;op=_out-beg;if(dist>op){op=dist-op;if(op>whave)if(state.sane){strm.msg="invalid distance too far back";state.mode=BAD;break top}from=0;from_source=window;if(wnext===0){from+=wsize-op;if(op2){output[_out++]=from_source[from++];output[_out++]=from_source[from++];output[_out++]=from_source[from++];len-=3}if(len){output[_out++]=from_source[from++];if(len>1)output[_out++]=from_source[from++]}}else{from=_out-dist;do{output[_out++]=output[from++];output[_out++]= -output[from++];output[_out++]=output[from++];len-=3}while(len>2);if(len){output[_out++]=output[from++];if(len>1)output[_out++]=output[from++]}}}else if((op&64)===0){here=dcode[(here&65535)+(hold&(1<>3;_in-=len;bits-=len<<3;hold&=(1<>>24&255)+(q>>>8&65280)+((q&65280)<<8)+((q&255)<<24)}function InflateState(){this.mode=0;this.last=false;this.wrap=0;this.havedict=false;this.flags=0;this.dmax=0;this.check=0;this.total=0;this.head=null;this.wbits=0;this.wsize=0;this.whave=0;this.wnext=0;this.window=null;this.hold=0;this.bits=0;this.length=0;this.offset= -0;this.extra=0;this.lencode=null;this.distcode=null;this.lenbits=0;this.distbits=0;this.ncode=0;this.nlen=0;this.ndist=0;this.have=0;this.next=null;this.lens=new utils.Buf16(320);this.work=new utils.Buf16(288);this.lendyn=null;this.distdyn=null;this.sane=0;this.back=0;this.was=0}function inflateResetKeep(strm){var state;if(!strm||!strm.state)return Z_STREAM_ERROR;state=strm.state;strm.total_in=strm.total_out=state.total=0;strm.msg="";if(state.wrap)strm.adler=state.wrap&1;state.mode=HEAD;state.last= -0;state.havedict=0;state.dmax=32768;state.head=null;state.hold=0;state.bits=0;state.lencode=state.lendyn=new utils.Buf32(ENOUGH_LENS);state.distcode=state.distdyn=new utils.Buf32(ENOUGH_DISTS);state.sane=1;state.back=-1;return Z_OK}function inflateReset(strm){var state;if(!strm||!strm.state)return Z_STREAM_ERROR;state=strm.state;state.wsize=0;state.whave=0;state.wnext=0;return inflateResetKeep(strm)}function inflateReset2(strm,windowBits){var wrap;var state;if(!strm||!strm.state)return Z_STREAM_ERROR; -state=strm.state;if(windowBits<0){wrap=0;windowBits=-windowBits}else{wrap=(windowBits>>4)+1;if(windowBits<48)windowBits&=15}if(windowBits&&(windowBits<8||windowBits>15))return Z_STREAM_ERROR;if(state.window!==null&&state.wbits!==windowBits)state.window=null;state.wrap=wrap;state.wbits=windowBits;return inflateReset(strm)}function inflateInit2(strm,windowBits){var ret;var state;if(!strm)return Z_STREAM_ERROR;state=new InflateState;strm.state=state;state.window=null;ret=inflateReset2(strm,windowBits); -if(ret!==Z_OK)strm.state=null;return ret}function inflateInit(strm){return inflateInit2(strm,DEF_WBITS)}var virgin=true;var lenfix,distfix;function fixedtables(state){if(virgin){var sym;lenfix=new utils.Buf32(512);distfix=new utils.Buf32(32);sym=0;while(sym<144)state.lens[sym++]=8;while(sym<256)state.lens[sym++]=9;while(sym<280)state.lens[sym++]=7;while(sym<288)state.lens[sym++]=8;inflate_table(LENS,state.lens,0,288,lenfix,0,state.work,{bits:9});sym=0;while(sym<32)state.lens[sym++]=5;inflate_table(DISTS, -state.lens,0,32,distfix,0,state.work,{bits:5});virgin=false}state.lencode=lenfix;state.lenbits=9;state.distcode=distfix;state.distbits=5}function updatewindow(strm,src,end,copy){var dist;var state=strm.state;if(state.window===null){state.wsize=1<=state.wsize){utils.arraySet(state.window,src,end-state.wsize,state.wsize,0);state.wnext=0;state.whave=state.wsize}else{dist=state.wsize-state.wnext;if(dist>copy)dist= -copy;utils.arraySet(state.window,src,end-copy,dist,state.wnext);copy-=dist;if(copy){utils.arraySet(state.window,src,end-copy,copy,0);state.wnext=copy;state.whave=state.wsize}else{state.wnext+=dist;if(state.wnext===state.wsize)state.wnext=0;if(state.whave>>8&255;state.check=crc32(state.check,hbuf,2,0);hold=0;bits=0;state.mode=FLAGS;break}state.flags=0;if(state.head)state.head.done=false;if(!(state.wrap&1)||(((hold&255)<<8)+(hold>>8))%31){strm.msg="incorrect header check";state.mode=BAD;break}if((hold&15)!==Z_DEFLATED){strm.msg="unknown compression method";state.mode= -BAD;break}hold>>>=4;bits-=4;len=(hold&15)+8;if(state.wbits===0)state.wbits=len;else if(len>state.wbits){strm.msg="invalid window size";state.mode=BAD;break}state.dmax=1<>8&1;if(state.flags&512){hbuf[0]=hold&255;hbuf[1]=hold>>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0;state.mode=TIME;case TIME:while(bits<32){if(have===0)break inf_leave;have--;hold+=input[next++]<>>8&255;hbuf[2]=hold>>>16&255;hbuf[3]=hold>>>24&255;state.check=crc32(state.check,hbuf,4,0)}hold=0;bits=0;state.mode=OS;case OS:while(bits< -16){if(have===0)break inf_leave;have--;hold+=input[next++]<>8}if(state.flags&512){hbuf[0]=hold&255;hbuf[1]=hold>>>8&255;state.check=crc32(state.check,hbuf,2,0)}hold=0;bits=0;state.mode=EXLEN;case EXLEN:if(state.flags&1024){while(bits<16){if(have===0)break inf_leave;have--;hold+=input[next++]<>>8&255;state.check= -crc32(state.check,hbuf,2,0)}hold=0;bits=0}else if(state.head)state.head.extra=null;state.mode=EXTRA;case EXTRA:if(state.flags&1024){copy=state.length;if(copy>have)copy=have;if(copy){if(state.head){len=state.head.extra_len-state.length;if(!state.head.extra)state.head.extra=new Array(state.head.extra_len);utils.arraySet(state.head.extra,input,next,copy,len)}if(state.flags&512)state.check=crc32(state.check,input,copy,next);have-=copy;next+=copy;state.length-=copy}if(state.length)break inf_leave}state.length= -0;state.mode=NAME;case NAME:if(state.flags&2048){if(have===0)break inf_leave;copy=0;do{len=input[next+copy++];if(state.head&&len&&state.length<65536)state.head.name+=String.fromCharCode(len)}while(len&©>9&1;state.head.done=true}strm.adler=state.check=0;state.mode=TYPE;break;case DICTID:while(bits<32){if(have===0)break inf_leave;have--;hold+=input[next++]<>>=bits&7;bits-=bits&7;state.mode=CHECK;break}while(bits<3){if(have===0)break inf_leave;have--;hold+=input[next++]<>>=1;bits-=1;switch(hold&3){case 0:state.mode=STORED;break;case 1:fixedtables(state);state.mode=LEN_;if(flush===Z_TREES){hold>>>=2;bits-=2;break inf_leave}break;case 2:state.mode=TABLE;break;case 3:strm.msg="invalid block type";state.mode=BAD}hold>>>=2;bits-=2;break;case STORED:hold>>>=bits&7;bits-=bits&7;while(bits< -32){if(have===0)break inf_leave;have--;hold+=input[next++]<>>16^65535)){strm.msg="invalid stored block lengths";state.mode=BAD;break}state.length=hold&65535;hold=0;bits=0;state.mode=COPY_;if(flush===Z_TREES)break inf_leave;case COPY_:state.mode=COPY;case COPY:copy=state.length;if(copy){if(copy>have)copy=have;if(copy>left)copy=left;if(copy===0)break inf_leave;utils.arraySet(output,input,next,copy,put);have-=copy;next+=copy;left-=copy;put+=copy;state.length-=copy; -break}state.mode=TYPE;break;case TABLE:while(bits<14){if(have===0)break inf_leave;have--;hold+=input[next++]<>>=5;bits-=5;state.ndist=(hold&31)+1;hold>>>=5;bits-=5;state.ncode=(hold&15)+4;hold>>>=4;bits-=4;if(state.nlen>286||state.ndist>30){strm.msg="too many length or distance symbols";state.mode=BAD;break}state.have=0;state.mode=LENLENS;case LENLENS:while(state.have>>=3;bits-=3}while(state.have<19)state.lens[order[state.have++]]=0;state.lencode=state.lendyn;state.lenbits=7;opts={bits:state.lenbits};ret=inflate_table(CODES,state.lens,0,19,state.lencode,0,state.work,opts);state.lenbits=opts.bits;if(ret){strm.msg="invalid code lengths set";state.mode=BAD;break}state.have=0;state.mode=CODELENS;case CODELENS:while(state.have>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits)break;if(have===0)break inf_leave;have--;hold+=input[next++]<>>=here_bits;bits-=here_bits;state.lens[state.have++]=here_val}else{if(here_val===16){n=here_bits+2;while(bits>>=here_bits;bits-=here_bits;if(state.have===0){strm.msg="invalid bit length repeat";state.mode=BAD;break}len=state.lens[state.have-1];copy=3+(hold& -3);hold>>>=2;bits-=2}else if(here_val===17){n=here_bits+3;while(bits>>=here_bits;bits-=here_bits;len=0;copy=3+(hold&7);hold>>>=3;bits-=3}else{n=here_bits+7;while(bits>>=here_bits;bits-=here_bits;len=0;copy=11+(hold&127);hold>>>=7;bits-=7}if(state.have+copy>state.nlen+state.ndist){strm.msg="invalid bit length repeat";state.mode=BAD;break}while(copy--)state.lens[state.have++]= -len}}if(state.mode===BAD)break;if(state.lens[256]===0){strm.msg="invalid code -- missing end-of-block";state.mode=BAD;break}state.lenbits=9;opts={bits:state.lenbits};ret=inflate_table(LENS,state.lens,0,state.nlen,state.lencode,0,state.work,opts);state.lenbits=opts.bits;if(ret){strm.msg="invalid literal/lengths set";state.mode=BAD;break}state.distbits=6;state.distcode=state.distdyn;opts={bits:state.distbits};ret=inflate_table(DISTS,state.lens,state.nlen,state.ndist,state.distcode,0,state.work,opts); -state.distbits=opts.bits;if(ret){strm.msg="invalid distances set";state.mode=BAD;break}state.mode=LEN_;if(flush===Z_TREES)break inf_leave;case LEN_:state.mode=LEN;case LEN:if(have>=6&&left>=258){strm.next_out=put;strm.avail_out=left;strm.next_in=next;strm.avail_in=have;state.hold=hold;state.bits=bits;inflate_fast(strm,_out);put=strm.next_out;output=strm.output;left=strm.avail_out;next=strm.next_in;input=strm.input;have=strm.avail_in;hold=state.hold;bits=state.bits;if(state.mode===TYPE)state.back= --1;break}state.back=0;for(;;){here=state.lencode[hold&(1<>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits)break;if(have===0)break inf_leave;have--;hold+=input[next++]<>last_bits)];here_bits=here>>>24;here_op=here>>>16&255;here_val=here&65535;if(last_bits+here_bits<=bits)break;if(have=== -0)break inf_leave;have--;hold+=input[next++]<>>=last_bits;bits-=last_bits;state.back+=last_bits}hold>>>=here_bits;bits-=here_bits;state.back+=here_bits;state.length=here_val;if(here_op===0){state.mode=LIT;break}if(here_op&32){state.back=-1;state.mode=TYPE;break}if(here_op&64){strm.msg="invalid literal/length code";state.mode=BAD;break}state.extra=here_op&15;state.mode=LENEXT;case LENEXT:if(state.extra){n=state.extra;while(bits>>=state.extra;bits-=state.extra;state.back+=state.extra}state.was=state.length;state.mode=DIST;case DIST:for(;;){here=state.distcode[hold&(1<>>24;here_op=here>>>16&255;here_val=here&65535;if(here_bits<=bits)break;if(have===0)break inf_leave;have--;hold+=input[next++]<>last_bits)];here_bits=here>>>24;here_op=here>>>16&255;here_val=here&65535;if(last_bits+here_bits<=bits)break;if(have===0)break inf_leave;have--;hold+=input[next++]<>>=last_bits;bits-=last_bits;state.back+=last_bits}hold>>>=here_bits;bits-=here_bits;state.back+=here_bits;if(here_op&64){strm.msg="invalid distance code";state.mode=BAD;break}state.offset=here_val;state.extra=here_op&15;state.mode=DISTEXT;case DISTEXT:if(state.extra){n=state.extra;while(bits>>=state.extra;bits-=state.extra;state.back+=state.extra}if(state.offset>state.dmax){strm.msg="invalid distance too far back";state.mode=BAD;break}state.mode=MATCH;case MATCH:if(left===0)break inf_leave;copy=_out-left;if(state.offset>copy){copy=state.offset-copy;if(copy>state.whave)if(state.sane){strm.msg="invalid distance too far back";state.mode=BAD;break}if(copy>state.wnext){copy-=state.wnext; -from=state.wsize-copy}else from=state.wnext-copy;if(copy>state.length)copy=state.length;from_source=state.window}else{from_source=output;from=put-state.offset;copy=state.length}if(copy>left)copy=left;left-=copy;state.length-=copy;do output[put++]=from_source[from++];while(--copy);if(state.length===0)state.mode=LEN;break;case LIT:if(left===0)break inf_leave;output[put++]=state.length;left--;state.mode=LEN;break;case CHECK:if(state.wrap){while(bits<32){if(have===0)break inf_leave;have--;hold|=input[next++]<< -bits;bits+=8}_out-=left;strm.total_out+=_out;state.total+=_out;if(_out)strm.adler=state.check=state.flags?crc32(state.check,output,_out,put-_out):adler32(state.check,output,_out,put-_out);_out=left;if((state.flags?hold:ZSWAP32(hold))!==state.check){strm.msg="incorrect data check";state.mode=BAD;break}hold=0;bits=0}state.mode=LENGTH;case LENGTH:if(state.wrap&&state.flags){while(bits<32){if(have===0)break inf_leave;have--;hold+=input[next++]<=1;max--)if(count[max]!==0)break;if(root>max)root=max;if(max===0){table[table_index++]=1<<24|64<<16|0;table[table_index++]= -1<<24|64<<16|0;opts.bits=1;return 0}for(min=1;min0&&(type===CODES||max!==1))return-1;offs[1]=0;for(len=1;lenENOUGH_LENS||type===DISTS&&used>ENOUGH_DISTS)return 1;var i=0;for(;;){i++;here_bits=len-drop;if(work[sym]end){here_op=extra[extra_index+work[sym]];here_val=base[base_index+work[sym]]}else{here_op=32+64;here_val=0}incr=1<>drop)+fill]= -here_bits<<24|here_op<<16|here_val|0}while(fill!==0);incr=1<>=1;if(incr!==0){huff&=incr-1;huff+=incr}else huff=0;sym++;if(--count[len]===0){if(len===max)break;len=lens[lens_index+work[sym]]}if(len>root&&(huff&mask)!==low){if(drop===0)drop=root;next+=min;curr=len-drop;left=1<ENOUGH_LENS||type===DISTS&&used>ENOUGH_DISTS)return 1;low=huff&mask;table[low]=root<< -24|curr<<16|next-table_index|0}}if(huff!==0)table[next+huff]=len-drop<<24|64<<16|0;opts.bits=root;return 0}},{"../utils/common":27}],37:[function(_dereq_,module,exports){module.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(_dereq_,module,exports){var utils=_dereq_("../utils/common");var Z_FIXED=4;var Z_BINARY=0;var Z_TEXT=1;var Z_UNKNOWN=2;function zero(buf){var len= -buf.length;while(--len>=0)buf[len]=0}var STORED_BLOCK=0;var STATIC_TREES=1;var DYN_TREES=2;var MIN_MATCH=3;var MAX_MATCH=258;var LENGTH_CODES=29;var LITERALS=256;var L_CODES=LITERALS+1+LENGTH_CODES;var D_CODES=30;var BL_CODES=19;var HEAP_SIZE=2*L_CODES+1;var MAX_BITS=15;var Buf_size=16;var MAX_BL_BITS=7;var END_BLOCK=256;var REP_3_6=16;var REPZ_3_10=17;var REPZ_11_138=18;var extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];var extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7, -7,8,8,9,9,10,10,11,11,12,12,13,13];var extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];var bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];var DIST_CODE_LEN=512;var static_ltree=new Array((L_CODES+2)*2);zero(static_ltree);var static_dtree=new Array(D_CODES*2);zero(static_dtree);var _dist_code=new Array(DIST_CODE_LEN);zero(_dist_code);var _length_code=new Array(MAX_MATCH-MIN_MATCH+1);zero(_length_code);var base_length=new Array(LENGTH_CODES);zero(base_length);var base_dist=new Array(D_CODES); -zero(base_dist);var StaticTreeDesc=function(static_tree,extra_bits,extra_base,elems,max_length){this.static_tree=static_tree;this.extra_bits=extra_bits;this.extra_base=extra_base;this.elems=elems;this.max_length=max_length;this.has_stree=static_tree&&static_tree.length};var static_l_desc;var static_d_desc;var static_bl_desc;var TreeDesc=function(dyn_tree,stat_desc){this.dyn_tree=dyn_tree;this.max_code=0;this.stat_desc=stat_desc};function d_code(dist){return dist<256?_dist_code[dist]:_dist_code[256+ -(dist>>>7)]}function put_short(s,w){s.pending_buf[s.pending++]=w&255;s.pending_buf[s.pending++]=w>>>8&255}function send_bits(s,value,length){if(s.bi_valid>Buf_size-length){s.bi_buf|=value<>Buf_size-s.bi_valid;s.bi_valid+=length-Buf_size}else{s.bi_buf|=value<>>=1;res<<=1}while(--len>0); -return res>>>1}function bi_flush(s){if(s.bi_valid===16){put_short(s,s.bi_buf);s.bi_buf=0;s.bi_valid=0}else if(s.bi_valid>=8){s.pending_buf[s.pending++]=s.bi_buf&255;s.bi_buf>>=8;s.bi_valid-=8}}function gen_bitlen(s,desc){var tree=desc.dyn_tree;var max_code=desc.max_code;var stree=desc.stat_desc.static_tree;var has_stree=desc.stat_desc.has_stree;var extra=desc.stat_desc.extra_bits;var base=desc.stat_desc.extra_base;var max_length=desc.stat_desc.max_length;var h;var n,m;var bits;var xbits;var f;var overflow= -0;for(bits=0;bits<=MAX_BITS;bits++)s.bl_count[bits]=0;tree[s.heap[s.heap_max]*2+1]=0;for(h=s.heap_max+1;hmax_length){bits=max_length;overflow++}tree[n*2+1]=bits;if(n>max_code)continue;s.bl_count[bits]++;xbits=0;if(n>=base)xbits=extra[n-base];f=tree[n*2];s.opt_len+=f*(bits+xbits);if(has_stree)s.static_len+=f*(stree[n*2+1]+xbits)}if(overflow===0)return;do{bits=max_length-1;while(s.bl_count[bits]===0)bits--;s.bl_count[bits]--;s.bl_count[bits+ -1]+=2;s.bl_count[max_length]--;overflow-=2}while(overflow>0);for(bits=max_length;bits!==0;bits--){n=s.bl_count[bits];while(n!==0){m=s.heap[--h];if(m>max_code)continue;if(tree[m*2+1]!==bits){s.opt_len+=(bits-tree[m*2+1])*tree[m*2];tree[m*2+1]=bits}n--}}}function gen_codes(tree,max_code,bl_count){var next_code=new Array(MAX_BITS+1);var code=0;var bits;var n;for(bits=1;bits<=MAX_BITS;bits++)next_code[bits]=code=code+bl_count[bits-1]<<1;for(n=0;n<=max_code;n++){var len=tree[n*2+1];if(len===0)continue; -tree[n*2]=bi_reverse(next_code[len]++,len)}}function tr_static_init(){var n;var bits;var length;var code;var dist;var bl_count=new Array(MAX_BITS+1);length=0;for(code=0;code>=7;for(;code8)put_short(s,s.bi_buf);else if(s.bi_valid>0)s.pending_buf[s.pending++]= -s.bi_buf;s.bi_buf=0;s.bi_valid=0}function copy_block(s,buf,len,header){bi_windup(s);if(header){put_short(s,len);put_short(s,~len)}utils.arraySet(s.pending_buf,s.window,buf,len,s.pending);s.pending+=len}function smaller(tree,n,m,depth){var _n2=n*2;var _m2=m*2;return tree[_n2]>1;n>=1;n--)pqdownheap(s,tree,n);node=elems;do{n=s.heap[1];s.heap[1]=s.heap[s.heap_len--];pqdownheap(s,tree,1);m=s.heap[1];s.heap[--s.heap_max]=n;s.heap[--s.heap_max]=m;tree[node*2]=tree[n*2]+tree[m*2];s.depth[node]=(s.depth[n]>=s.depth[m]?s.depth[n]:s.depth[m])+1;tree[n*2+1]=tree[m*2+1]=node;s.heap[1]=node++;pqdownheap(s,tree,1)}while(s.heap_len>=2);s.heap[--s.heap_max]=s.heap[1];gen_bitlen(s, -desc);gen_codes(tree,max_code,s.bl_count)}function scan_tree(s,tree,max_code){var n;var prevlen=-1;var curlen;var nextlen=tree[0*2+1];var count=0;var max_count=7;var min_count=4;if(nextlen===0){max_count=138;min_count=3}tree[(max_code+1)*2+1]=65535;for(n=0;n<=max_code;n++){curlen=nextlen;nextlen=tree[(n+1)*2+1];if(++count=3;max_blindex--)if(s.bl_tree[bl_order[max_blindex]*2+1]!==0)break;s.opt_len+=3*(max_blindex+1)+5+5+4;return max_blindex}function send_all_trees(s,lcodes,dcodes,blcodes){var rank;send_bits(s,lcodes-257,5);send_bits(s,dcodes-1,5);send_bits(s,blcodes-4,4);for(rank=0;rank>>=1)if(black_mask&1&&s.dyn_ltree[n*2]!==0)return Z_BINARY;if(s.dyn_ltree[9*2]!==0||s.dyn_ltree[10*2]!==0||s.dyn_ltree[13*2]!==0)return Z_TEXT;for(n=32;n0){if(s.strm.data_type===Z_UNKNOWN)s.strm.data_type= -detect_data_type(s);build_tree(s,s.l_desc);build_tree(s,s.d_desc);max_blindex=build_bl_tree(s);opt_lenb=s.opt_len+3+7>>>3;static_lenb=s.static_len+3+7>>>3;if(static_lenb<=opt_lenb)opt_lenb=static_lenb}else opt_lenb=static_lenb=stored_len+5;if(stored_len+4<=opt_lenb&&buf!==-1)_tr_stored_block(s,buf,stored_len,last);else if(s.strategy===Z_FIXED||static_lenb===opt_lenb){send_bits(s,(STATIC_TREES<<1)+(last?1:0),3);compress_block(s,static_ltree,static_dtree)}else{send_bits(s,(DYN_TREES<<1)+(last?1:0), -3);send_all_trees(s,s.l_desc.max_code+1,s.d_desc.max_code+1,max_blindex+1);compress_block(s,s.dyn_ltree,s.dyn_dtree)}init_block(s);if(last)bi_windup(s)}function _tr_tally(s,dist,lc){s.pending_buf[s.d_buf+s.last_lit*2]=dist>>>8&255;s.pending_buf[s.d_buf+s.last_lit*2+1]=dist&255;s.pending_buf[s.l_buf+s.last_lit]=lc&255;s.last_lit++;if(dist===0)s.dyn_ltree[lc*2]++;else{s.matches++;dist--;s.dyn_ltree[(_length_code[lc]+LITERALS+1)*2]++;s.dyn_dtree[d_code(dist)*2]++}return s.last_lit===s.lit_bufsize-1} -exports._tr_init=_tr_init;exports._tr_stored_block=_tr_stored_block;exports._tr_flush_block=_tr_flush_block;exports._tr_tally=_tr_tally;exports._tr_align=_tr_align},{"../utils/common":27}],39:[function(_dereq_,module,exports){function ZStream(){this.input=null;this.next_in=0;this.avail_in=0;this.total_in=0;this.output=null;this.next_out=0;this.avail_out=0;this.total_out=0;this.msg="";this.state=null;this.data_type=2;this.adler=0}module.exports=ZStream},{}]},{},[9])(9)}); diff --git a/plugins/rebrandly/icon.png b/plugins/rebrandly/icon.png deleted file mode 100644 index 9040a45481cc7538f8d2054c71b86c95d8d2a5e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102500 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 AegFUf diff --git a/plugins/rebrandly/index.html b/plugins/rebrandly/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/rebrandly/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
    -

    403 - Access forbidden!

    -
    -
    Powered by Kleeja -
    - - \ No newline at end of file diff --git a/plugins/rebrandly/init.php b/plugins/rebrandly/init.php deleted file mode 100644 index f439aaa..0000000 --- a/plugins/rebrandly/init.php +++ /dev/null @@ -1,223 +0,0 @@ - array( - 'en' => 'Rebrandly for Kleeja', - 'ar' => 'Rebrandly لكليجا' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.0', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Generate a short links using Rebrandly service', - 'ar' => 'إنشاء روابط قصيرة من خدمة Rebrandly ' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['rebrandly']['first_run']['ar'] = " -شكراً لاستخدامك إضافة rebrandly ، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
    -info@kleeja.com -
    -
    -

    لاحظ:

    -تجد إعدادات الإضافة في : إعدادات المركز->خيارات Rebrandly -
    -
    -------- -

    معلومات قد تفيدك:

    -- إضغط هنا للتسجيل في Rebrandly
    -"; - -$kleeja_plugin['rebrandly']['first_run']['en'] = " -Thanks for using rebrandly plugin, to report bugs contact us: -
    -info@kleeja.com -
    -
    -

    Note:

    -You can find the settings at: Settings -> Rebrandly Settings -
    -
    -------- -

    Extra Info:

    -- Create your rebrandly account now!
    -"; - - -# Plugin Installation function -$kleeja_plugin['rebrandly']['install'] = function ($plg_id) { - //new options - $options = array( - 'rebrandly_enable' => - array( - 'value' => '0', - 'html' => configField('rebrandly_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'rebrandly' - ), - 'rebrandly_domain' => - array( - 'value' => 'rebrand.ly', - 'html' => configField('rebrandly_domain'), - 'plg_id' => $plg_id, - 'type' => 'rebrandly' - ), - 'rebrandly_api_code' => - array( - 'value' => '', - 'html' => configField('rebrandly_api_code'), - 'plg_id' => $plg_id, - 'type' => 'rebrandly' - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'REBRANDLY_ENABLE' => 'تفعيل Rebrandly', - 'REBRANDLY_API_CODE' => 'كود الربط API لـ Rebrandly', - 'REBRANDLY_DOMAIN' => 'الدومين المستخدم', - 'CONFIG_KLJ_MENUS_REBRANDLY' => 'خيارات Rebrandly', - ), - 'ar', - $plg_id); - - add_olang(array( - 'REBRANDLY_ENABLE' => 'Enable Rebrandly', - 'REBRANDLY_API_CODE' => 'Your API code of Rebrandly', - 'REBRANDLY_DOMAIN' => 'Domain of Rebrandly', - 'CONFIG_KLJ_MENUS_REBRANDLY' => 'Rebrandly Settings', - ), - 'en', - $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['rebrandly']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['rebrandly']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'rebrandly_enable', - 'rebrandly_api_code', - 'rebrandly_domain' - )); - - //delete language variables - foreach (array('ar', 'en') as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# Plugin functions -$kleeja_plugin['rebrandly']['functions'] = array( - 'kleeja_get_link_func2' => function ($args) { - global $config; - - if (!$config['rebrandly_enable']) { - return; - } - - - if(defined('IN_REAL_INDEX')) - { - $link = $args['return_link']; - $current_pid = $args['pid']; - if($current_pid === 'file') { - - $return_link = generate_rebrandly_link($link); - - return compact('return_link'); - } - } - } -); - - -/** - * special functions - */ - -if (!function_exists('genera_rebrandly_link')) { - function generate_rebrandly_link($link) - { - global $config; - - - if (!$config['rebrandly_enable']) { - return $link; - } - - - if (empty($config['rebrandly_api_code'])) { - return $link; - } - - - if (empty($config['rebrandly_domain'])) { - return $link; - } - - - $post_data["destination"] = $link; - $post_data["domain"] = array('fullName' => $config['rebrandly_domain']);; - - $ch = curl_init("https://api.rebrandly.com/v1/links"); - curl_setopt($ch, CURLOPT_HTTPHEADER, array( - "apikey: " . $config['rebrandly_api_code'], - "Content-Type: application/json" - )); - curl_setopt($ch, CURLOPT_POST, 1); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data)); - $result = curl_exec($ch); - curl_close($ch); - $response = json_decode($result, true); - - if(!empty($response["shortUrl"])){ - return $response["shortUrl"]; - } - - - return $link; - } -} diff --git a/plugins/traidnt_arbah/icon.png b/plugins/traidnt_arbah/icon.png deleted file mode 100644 index bd48390184d592b641fb6241f194e732e8b703f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119130 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 diff --git a/plugins/traidnt_arbah/index.html b/plugins/traidnt_arbah/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/traidnt_arbah/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
    -

    403 - Access forbidden!

    -
    -
    - - \ No newline at end of file diff --git a/plugins/traidnt_arbah/init.php b/plugins/traidnt_arbah/init.php deleted file mode 100644 index 4319129..0000000 --- a/plugins/traidnt_arbah/init.php +++ /dev/null @@ -1,231 +0,0 @@ - array( - 'en' => 'Traidnt Arbah', - 'ar' => 'ترايدنت أرباح' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.1', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Generate a links using Traidnt Arbah service', - 'ar' => 'دعم ترايدنت أرباح في كليجا وإنشاء روابط ربحية تلقائياً' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 0 -); - -//after installation message, you can remove it, it's not requiered -$kleeja_plugin['traidnt_arbah']['first_run']['ar'] = " -شكراً لاستخدامك إضافة ترايدنت أرباح، قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
    -info@kleeja.com -
    -
    -

    لاحظ:

    -تجد إعدادات الإضافة في : إعدادات المركز->خيارات ترايدنت أرباح -
    -
    -------- -

    معلومات قد تفيدك في برنامج أرباح:

    - -- صفحة أرباح الأساسية - سجل وضعها في المفضلة
    -- شروط وقوانين برنامج أرباح
    -- معلومات مهمة عن أدسنس والمشاكل وحلولها مع أرباح - -"; - - -# Plugin Installation function -$kleeja_plugin['traidnt_arbah']['install'] = function ($plg_id) { - //new options - $options = array( - 'traidnt_arbah_enable' => - array( - 'value' => '0', - 'html' => configField('traidnt_arbah_enable', 'yesno'), - 'plg_id' => $plg_id, - 'type' => 'traidnt_arbah' - ), - 'traidnt_arbah_api_code' => - array( - 'value' => '', - 'html' => configField('traidnt_arbah_api_code'), - 'plg_id' => $plg_id, - 'type' => 'traidnt_arbah' - ), - 'traidnt_arbah_user_id' => - array( - 'value' => '', - 'html' => configField('traidnt_arbah_user_id'), - 'plg_id' => $plg_id, - 'type' => 'traidnt_arbah' - ), - ); - - - add_config_r($options); - - - //new language variables - add_olang(array( - 'TRAIDNT_ARBAH_ENABLE' => 'تفعيل ترايدنت أرباح', - 'TRAIDNT_ARBAH_API_CODE' => 'كود الربط لترايدنت أرباح (تجده في حسابك في أرباح)', - 'TRAIDNT_ARBAH_USER_ID' => 'رقم عضويتك لترايدنت أرباح (للربط السريع)', - 'CONFIG_KLJ_MENUS_TRAIDNT_ARBAH' => 'خيارات ترايدنت أرباح', - ), - 'ar', - $plg_id); - - add_olang(array( - 'TRAIDNT_ARBAH_ENABLE' => 'Enable Traidnt Arbah', - 'TRAIDNT_ARBAH_API_CODE' => 'Your API code of Traidnt Arbah', - 'TRAIDNT_ARBAH_USER_ID' => 'Your user ID of Traidnt Arbah', - 'CONFIG_KLJ_MENUS_TRAIDNT_ARBAH' => 'Traidnt Arbah Settings', - ), - 'en', - $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['traidnt_arbah']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['traidnt_arbah']['uninstall'] = function ($plg_id) { - //delete options - delete_config(array( - 'traidnt_arbah_enable', - 'traidnt_arbah_api_code', - 'traidnt_arbah_user_id' - )); - - //delete language variables - foreach (array('ar', 'en') as $language) { - delete_olang(null, $language, $plg_id); - } -}; - - -# Plugin functions -$kleeja_plugin['traidnt_arbah']['functions'] = array( - - 'default_go_page' => function($args){ - if(g('go') == 'arbah') - { - $url = g('url', 'str'); - $no_request = false; - header('Location:' . generate_traidnt_arbah_link(base64_decode($url))); - return compact('no_request'); - } - }, - - 'kleeja_get_link_func2' => function ($args) { - global $config; - - if (!$config['traidnt_arbah_enable']) { - return; - } - - if(defined('IN_REAL_INDEX')) - { - $return_link = $args['return_link']; - $current_pid = $args['pid']; - if($current_pid === 'file') { - $return_link = $config['siteurl'] . 'go.php?go=arbah&url=' . base64_encode($return_link); - return compact('return_link'); - } - } - } -); - - -/** - * special functions - */ - -if (!function_exists('generate_traidnt_arbah_link')) { - function generate_traidnt_arbah_link($link, $by_user_id = false) - { - global $config; - - - if (!$config['traidnt_arbah_enable']) { - return $link; - } - - - if (empty($config['traidnt_arbah_api_code'])) { - return $link; - } - - if($by_user_id) - { - if (empty($config['traidnt_arbah_user_id'])) { - return $link; - }else{ - $config['traidnt_arbah_user_id'] = preg_replace('/[^0-9]/', '', $config['traidnt_arbah_user_id']); - return 'https://traidnt.net/link/fast_link.html?user=' . trim(intval($config['traidnt_arbah_user_id'])) - . '&url=' . trim($link); - } - } - - $service_url = "https://www.traidnt.net/link/api.html?url=".trim($link) - . "&api=".trim($config['traidnt_arbah_api_code']) - . "&allow_adv=1" - . "&minipage=1"; - - - $received_data = fetch_remote_file($service_url); - - - if(empty($received_data)) - { - return $by_user_id ? $link : generate_traidnt_arbah_link($link, true); - } - - - $decoded_data = json_decode($received_data); - - if($decoded_data->error or $decoded_data->code == '') - { - return $by_user_id ? $link : generate_traidnt_arbah_link($link, true); - } - - if(!empty($decoded_data->url)) - { - return $decoded_data->url; - } - - return $link; - } -} diff --git a/plugins/video_player/icon.png b/plugins/video_player/icon.png deleted file mode 100644 index 1e7b307b98d5d4ca664f44ff1967981d71639752..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7584 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 F{{WwGM!5h0 diff --git a/plugins/video_player/index.html b/plugins/video_player/index.html deleted file mode 100755 index 7395a44..0000000 --- a/plugins/video_player/index.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Powered by Kleeja - - -
    -

    403 - Access forbidden!

    -
    -
    Powered by Kleeja -
    - - \ No newline at end of file diff --git a/plugins/video_player/init.php b/plugins/video_player/init.php deleted file mode 100644 index bf8b797..0000000 --- a/plugins/video_player/init.php +++ /dev/null @@ -1,200 +0,0 @@ - array( - 'en' => 'Video & Audio Player', - 'ar' => 'مشغل فيديو وصوت' - ), - # Who wrote this plugin? - 'plugin_developer' => 'Kleeja.com', - # This plugin version - 'plugin_version' => '1.1', - # Explain what is this plugin, why should I use it? - 'plugin_description' => array( - 'en' => 'Integrate a video player in download page', - 'ar' => 'عرض مشغل فيديو في صفحة التحميل' - ), - # Min version of Kleeja that's requiered to run this plugin - 'plugin_kleeja_version_min' => '2.0', - # Max version of Kleeja that support this plugin, use 0 for unlimited - 'plugin_kleeja_version_max' => '3.9', - # Should this plugin run before others?, 0 is normal, and higher number has high priority - 'plugin_priority' => 10 -); - -//after installation message, you can remove it, it's not required -$kleeja_plugin['video_player']['first_run']['ar'] = " -شكراً لاستخدامك هذه الإضافة قم بمراسلتنا بالأخطاء عند ظهورها على البريد:
    -info@kleeja.com -"; - -$kleeja_plugin['video_player']['first_run']['en'] = " -Thanks for using this plugin, to report bugs contact us: -
    -info@kleeja.com -"; - - -# Plugin Installation function -$kleeja_plugin['video_player']['install'] = function ($plg_id) -{ -// //new language variables -// add_olang(array( -// -// ), -// 'ar', -// $plg_id); -// -// add_olang(array( -// -// ), -// 'en', -// $plg_id); -}; - - -//Plugin update function, called if plugin is already installed but version is different than current -$kleeja_plugin['video_player']['update'] = function ($old_version, $new_version) { - // if(version_compare($old_version, '0.5', '<')){ - // //... update to 0.5 - // } - // - // if(version_compare($old_version, '0.6', '<')){ - // //... update to 0.6 - // } - - //you could use update_config, update_olang -}; - - -# Plugin Uninstallation, function to be called at unistalling -$kleeja_plugin['video_player']['uninstall'] = function ($plg_id) { - //delete language variables -// foreach (array('ar', 'en') as $language) { -// delete_olang(null, $language, $plg_id); -// } -}; - - -# Plugin functions -$kleeja_plugin['video_player']['functions'] = array( - - 'Saaheader_links_func' => function($args){ - - $extra = $args['extra']; - - $header_codes = '' . "\n" . - '' . "\n"; - - - $extra .= $header_codes; - - return compact('extra'); - }, - - 'print_Saafooter_func' => function($args){ - $footer = $args['footer']; - - $footer = str_replace('', "\n", $footer); - return compact('footer'); - }, - - 'style_parse_func' => function($args) { - global $config; - - - if($args['template_name'] == 'download') { - - $x = PHP_EOL . ' -
    -
    - -
    -
    '; - - $x .= PHP_EOL . ' -
    -
    - -
    -
    '; - - $html = $args['html'] . $x; - - return compact('html'); - } - }, - - 'b4_showsty_downlaod_id_filename' => function($args){ - - - $file_info = $args['file_info']; - - - $show_video_player_code = false; - $show_audio_player_code = false; - $video_path = ''; - $video_thumb = ''; - $video_mime_type = ''; - - $type_mimes = array( - 'mp4' => 'video/mp4', - 'webm' => 'video/webm', -// 'webma' => 'audio/webm', - 'ogg' => 'video/ogg', - 'ogv' => 'video/ogg', - '3gp' => 'video/3gp', - 'flv' => 'video/x-flv', - 'oga' => 'audio/ogg', - 'mp3' => 'audio/mp3', - 'wav' => 'audio/wav', - 'flac' => 'audio/flac', - ); - - if(in_array(strtolower($file_info['type']), array_keys($type_mimes))){ - - if(in_array(strtolower($file_info['type']), array('mp3', 'oga', 'wav', 'flac'))){ - $show_audio_player_code = true; - }else{ - $show_video_player_code = true; - } - - - $video_path = "./{$file_info['folder']}/{$file_info['name']}"; - - $video_mime_type = $type_mimes[$file_info['type']]; - - is_array($plugin_run_result = Plugins::getInstance()->run('plugin:video_player:do_display', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook - - } - - return compact('show_video_player_code', 'video_path', 'video_thumb', 'video_mime_type', 'show_audio_player_code'); - } -); -